Skip to content
Merged
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
12 changes: 10 additions & 2 deletions docs-site/src/examples/rawChange.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
() => {
const [selectedDate, setSelectedDate] = useState(null);
const handleChangeRaw = (value) => {
const handleChangeRaw = (value, selectedDateMeta) => {
console.log(
selectedDateMeta
? `Selected Date Meta: ${JSON.stringify(selectedDateMeta)}`
: "No Selection Meta is available",
);

if (value === "tomorrow") {
setSelectedDate(addDays(new Date(), 1));
}
Expand All @@ -10,7 +16,9 @@
selected={selectedDate}
onChange={(date) => setSelectedDate(date)}
placeholderText='Enter "tomorrow"'
onChangeRaw={(event) => handleChangeRaw(event.target.value)}
onChangeRaw={(event, selectedDateMeta) =>
handleChangeRaw(event.target.value, selectedDateMeta)
}
/>
);
};
14 changes: 12 additions & 2 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ export type DatePickerProps = OmitUnion<
rangeSeparator?: string;
onChangeRaw?: (
event?: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>,
selectionMeta?: {
date: Date;
formattedDate: string;
},
) => void;
onSelect?: (
date: Date | null,
Expand Down Expand Up @@ -717,7 +721,9 @@ export class DatePicker extends Component<DatePickerProps, DatePickerState> {
) => {
if (this.props.readOnly) return;

const { selectsRange, startDate, endDate, swapRange } = this.props;
const { selectsRange, startDate, endDate, locale, swapRange } = this.props;
const dateFormat =
this.props.dateFormat ?? DatePicker.defaultProps.dateFormat;
const isDateSelectionComplete =
!selectsRange ||
(startDate && !endDate && (swapRange || !isDateBefore(date, startDate)));
Expand All @@ -732,7 +738,11 @@ export class DatePicker extends Component<DatePickerProps, DatePickerState> {
this.sendFocusBackToInput();
}
if (this.props.onChangeRaw) {
this.props.onChangeRaw(event);
const formattedDate = safeDateFormat(date, {
dateFormat,
locale,
});
this.props.onChangeRaw(event, { date, formattedDate });
}
this.setSelected(date, event, false, monthSelectedIn);
if (this.props.showDateSelect) {
Expand Down
64 changes: 64 additions & 0 deletions src/test/datepicker_test.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4819,4 +4819,68 @@ describe("DatePicker", () => {
});
});
});

describe("onChangeRaw - selectionMeta", () => {
it("should include selectionMeta as a second param to the onChangeRaw when user selected a date to provide extra meta about the selected date element", () => {
const selectedDate = newDate("2025-11-05");
const onChangeRawSpy = jest.fn();
const { container } = render(
<DatePicker
dateFormat="MM/dd/yyyy"
selected={selectedDate}
onChangeRaw={onChangeRawSpy}
/>,
);
expect(onChangeRawSpy).not.toHaveBeenCalled();

const input = safeQuerySelector(container, "input");
fireEvent.focus(input);

const day = safeQuerySelector(container, ".react-datepicker__day--002");
fireEvent.click(day);

expect(onChangeRawSpy).toHaveBeenCalledTimes(1);
const params = onChangeRawSpy.mock.calls[0];
expect(params.length).toBe(2);

const eventObject = params[0];
expect(typeof eventObject).toBe("object");

const selectionMeta = params[1];
expect(typeof selectionMeta).toBe("object");
expect(selectionMeta).toHaveProperty("date");
expect(selectionMeta).toHaveProperty("formattedDate");
expect(selectionMeta.formattedDate).toBe("11/02/2025");
expect(selectionMeta.date).toBeInstanceOf(Date);
});

it("should not include selectionMeta as a second param to the onChangeRaw when user updated date using date input", () => {
const selectedDate = newDate("2025-11-05");
const onChangeRawSpy = jest.fn();
const { container } = render(
<DatePicker
dateFormat="MM/dd/yyyy"
selected={selectedDate}
onChangeRaw={onChangeRawSpy}
/>,
);
expect(onChangeRawSpy).not.toHaveBeenCalled();

const input = safeQuerySelector(container, "input");
const inputValue = "11/02/2025";
fireEvent.change(input, {
target: {
value: inputValue,
},
});
expect(onChangeRawSpy).toHaveBeenCalledTimes(1);

const params = onChangeRawSpy.mock.calls[0];
expect(params.length).toBe(1);

const eventObject = params[0];
expect(typeof eventObject).toBe("object");
expect(eventObject.target?.value).toBe(inputValue);
});
});
});
Loading