Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs-site/src/components/Examples/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import Inline from "../../examples/ts/inline?raw";
import InlineDisabled from "../../examples/ts/disabledInline?raw";
import InlineVisible from "../../examples/ts/inlineVisible?raw";
import TimeInput from "../../examples/ts/timeInput?raw";
import RangeTimeInputLabels from "../../examples/ts/rangeTimeInputLabels?raw";
import Locale from "../../examples/ts/locale?raw";
import LocaleWithTime from "../../examples/ts/localeWithTime?raw";
import LocaleWithoutGlobalVariable from "../../examples/ts/localeWithoutGlobalVariable?raw";
Expand Down Expand Up @@ -370,6 +371,10 @@ export const EXAMPLE_CONFIG: IExampleConfig[] = [
title: "Input Time",
component: TimeInput,
},
{
title: "Input Time with Range (custom start/end labels)",
component: RangeTimeInputLabels,
},
{
title: "Locale",
component: Locale,
Expand Down
26 changes: 26 additions & 0 deletions docs-site/src/examples/ts/rangeTimeInputLabels.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const RangeTimeInputLabels = () => {
const [startDate, setStartDate] = useState<Date | null>(new Date());
const [endDate, setEndDate] = useState<Date | null>(null);

const onChange = (dates: [Date | null, Date | null]) => {
const [start, end] = dates;
setStartDate(start);
setEndDate(end);
};

return (
<DatePicker
selected={startDate}
onChange={onChange}
startDate={startDate}
endDate={endDate}
selectsRange
showTimeInput
timeInputStartLabel="Start time"
timeInputEndLabel="End time"
dateFormat="MM/dd/yyyy h:mm aa"
/>
);
};

render(RangeTimeInputLabels);
12 changes: 10 additions & 2 deletions src/calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ type CalendarProps = React.PropsWithChildren<
onTimeChange?: (time: Date, modifyDateType?: "start" | "end") => void;
timeFormat?: TimeProps["format"];
timeIntervals?: TimeProps["intervals"];
timeInputStartLabel?: string;
timeInputEndLabel?: string;
} & (
| ({
showMonthYearDropdown: true;
Expand Down Expand Up @@ -1212,7 +1214,10 @@ export default class Calendar extends Component<CalendarProps, CalendarState> {
onChange={(time: Date) => {
this.props.onTimeChange?.(time, "start");
}}
timeInputLabel={(this.props.timeInputLabel ?? "Time") + " (Start)"}
timeInputLabel={
this.props.timeInputStartLabel ??
(this.props.timeInputLabel ?? "Time") + " (Start)"
}
/>
<InputTime
{...Calendar.defaultProps}
Expand All @@ -1222,7 +1227,10 @@ export default class Calendar extends Component<CalendarProps, CalendarState> {
onChange={(time: Date) => {
this.props.onTimeChange?.(time, "end");
}}
timeInputLabel={(this.props.timeInputLabel ?? "Time") + " (End)"}
timeInputLabel={
this.props.timeInputEndLabel ??
(this.props.timeInputLabel ?? "Time") + " (End)"
}
/>
</>
);
Expand Down
118 changes: 118 additions & 0 deletions src/test/datepicker_test.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6821,6 +6821,124 @@ describe("DatePicker", () => {
expect(timeInputs[0]?.value).toBe("");
expect(timeInputs[1]?.value).toBe("");
});

describe("timeInputStartLabel / timeInputEndLabel props (#6280)", () => {
const rangeStart = newDate("2024-01-15 09:00:00");
const rangeEnd = newDate("2024-01-20 14:30:00");

const captionsOf = (container: HTMLElement) =>
Array.from(
container.querySelectorAll(".react-datepicker-time__caption"),
).map((n) => n.textContent);

it("defaults to the hardcoded English suffixes", () => {
const { container } = render(
<DatePicker
selectsRange
startDate={rangeStart}
endDate={rangeEnd}
onChange={jest.fn()}
showTimeInput
inline
/>,
);
expect(captionsOf(container)).toEqual(["Time (Start)", "Time (End)"]);
});

it("appends the suffixes to a custom timeInputLabel (existing behavior)", () => {
const { container } = render(
<DatePicker
selectsRange
startDate={rangeStart}
endDate={rangeEnd}
onChange={jest.fn()}
showTimeInput
timeInputLabel="Uhrzeit"
inline
/>,
);
expect(captionsOf(container)).toEqual([
"Uhrzeit (Start)",
"Uhrzeit (End)",
]);
});

it("replaces each caption entirely when the new props are provided", () => {
const { container } = render(
<DatePicker
selectsRange
startDate={rangeStart}
endDate={rangeEnd}
onChange={jest.fn()}
showTimeInput
timeInputStartLabel="Startzeit"
timeInputEndLabel="Endzeit"
inline
/>,
);
expect(captionsOf(container)).toEqual(["Startzeit", "Endzeit"]);
});

it("overrides timeInputLabel + suffix when both are set", () => {
const { container } = render(
<DatePicker
selectsRange
startDate={rangeStart}
endDate={rangeEnd}
onChange={jest.fn()}
showTimeInput
timeInputLabel="Uhrzeit"
timeInputStartLabel="Von"
timeInputEndLabel="Bis"
inline
/>,
);
expect(captionsOf(container)).toEqual(["Von", "Bis"]);
});

it("falls back per-side when only one of the two props is set", () => {
const { container: c1 } = render(
<DatePicker
selectsRange
startDate={rangeStart}
endDate={rangeEnd}
onChange={jest.fn()}
showTimeInput
timeInputStartLabel="Von"
inline
/>,
);
expect(captionsOf(c1)).toEqual(["Von", "Time (End)"]);

const { container: c2 } = render(
<DatePicker
selectsRange
startDate={rangeStart}
endDate={rangeEnd}
onChange={jest.fn()}
showTimeInput
timeInputEndLabel="Bis"
inline
/>,
);
expect(captionsOf(c2)).toEqual(["Time (Start)", "Bis"]);
});

it("does not affect single (non-range) mode", () => {
const { container } = render(
<DatePicker
selected={rangeStart}
onChange={jest.fn()}
showTimeInput
timeInputStartLabel="Startzeit"
timeInputEndLabel="Endzeit"
timeInputLabel="Uhrzeit"
inline
/>,
);
expect(captionsOf(container)).toEqual(["Uhrzeit"]);
});
});
});

describe("Critical functions coverage - best in class", () => {
Expand Down
Loading