Skip to content

Commit ed39cc4

Browse files
committed
Update Vite ecosystem
1 parent ee7507b commit ed39cc4

8 files changed

Lines changed: 799 additions & 1943 deletions

File tree

packages/react-date-picker/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,14 @@
6262
"@types/node": "*",
6363
"@types/react": "^19.2.0",
6464
"@types/react-dom": "^19.2.0",
65-
"@vitest/browser-playwright": "^4.0.1",
65+
"@vitest/browser-playwright": "^4.1.0",
6666
"cpy-cli": "^5.0.0",
6767
"playwright": "^1.55.1",
6868
"react": "^19.2.0",
6969
"react-dom": "^19.2.0",
7070
"typescript": "^6.0.2",
71-
"vitest": "^4.0.1",
72-
"vitest-browser-react": "^2.0.0"
71+
"vitest": "^4.1.0",
72+
"vitest-browser-react": "^2.2.0"
7373
},
7474
"peerDependencies": {
7575
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",

packages/react-date-picker/src/DateInput.spec.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,27 @@ describe('DateInput', () => {
492492
expect(onChange).toHaveBeenCalledWith(new Date(currentYear, 8, 20), false);
493493
});
494494

495+
it('does not call onChange for leap day until yyyy year is complete', async () => {
496+
const onChange = vi.fn();
497+
498+
await render(<DateInput {...defaultProps} format="MM/dd/yyyy" onChange={onChange} />);
499+
500+
const monthInput = page.getByRole('spinbutton', { name: 'month' });
501+
const dayInput = page.getByRole('spinbutton', { name: 'day' });
502+
const yearInput = page.getByRole('spinbutton', { name: 'year' });
503+
504+
await userEvent.fill(monthInput, '02');
505+
await userEvent.fill(dayInput, '29');
506+
await userEvent.type(yearInput, '200');
507+
508+
expect(onChange).not.toHaveBeenCalled();
509+
510+
await userEvent.type(yearInput, '0');
511+
512+
expect(onChange).toHaveBeenCalledTimes(1);
513+
expect(onChange).toHaveBeenCalledWith(new Date(2000, 1, 29), false);
514+
});
515+
495516
it('triggers onChange correctly when cleared custom inputs', async () => {
496517
const onChange = vi.fn();
497518
const date = new Date(2017, 8, 30);

packages/react-date-picker/src/DateInput.tsx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ export default function DateInput({
235235
const dayInput = useRef<HTMLInputElement>(null);
236236
const [isCalendarOpen, setIsCalendarOpen] = useState(isCalendarOpenProps);
237237
const lastPressedKey = useRef<KeyboardEvent['key'] | undefined>(undefined);
238+
const hasPendingInternalChange = useRef(false);
238239

239240
useEffect(() => {
240241
setIsCalendarOpen(isCalendarOpenProps);
@@ -365,6 +366,16 @@ export default function DateInput({
365366
return dividers ? dividers[0] : null;
366367
})();
367368

369+
const yearMinLength = (() => {
370+
const yearMatch = format?.match(/y+/);
371+
372+
if (!yearMatch || yearMatch[0].length <= 1) {
373+
return null;
374+
}
375+
376+
return yearMatch[0].length;
377+
})();
378+
368379
function onClick(event: React.MouseEvent<HTMLDivElement> & { target: HTMLDivElement }) {
369380
if (event.target === event.currentTarget) {
370381
// Wrapper was directly clicked
@@ -468,6 +479,15 @@ export default function DateInput({
468479
return;
469480
}
470481

482+
const isIncompleteYear =
483+
yearMinLength !== null &&
484+
yearInput.current?.value &&
485+
yearInput.current.value.length < yearMinLength;
486+
487+
if (isIncompleteYear) {
488+
return;
489+
}
490+
471491
const isEveryValueFilled = formElements.every((formElement) => formElement.value);
472492
const isEveryValueValid = formElements.every((formElement) => formElement.validity.valid);
473493

@@ -500,6 +520,8 @@ export default function DateInput({
500520
) {
501521
const { name, value } = event.target;
502522

523+
hasPendingInternalChange.current = true;
524+
503525
switch (name) {
504526
case 'year':
505527
setYear(value);
@@ -511,9 +533,17 @@ export default function DateInput({
511533
setDay(value);
512534
break;
513535
}
536+
}
537+
538+
// biome-ignore lint/correctness/useExhaustiveDependencies: onChangeExternal must run after internal value state updates
539+
useEffect(() => {
540+
if (!hasPendingInternalChange.current) {
541+
return;
542+
}
514543

544+
hasPendingInternalChange.current = false;
515545
onChangeExternal();
516-
}
546+
}, [day, month, year]);
517547

518548
/**
519549
* Called when native date input is changed.

packages/react-date-picker/src/DatePicker.spec.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,38 @@ describe('DatePicker', () => {
590590
expect(onChange).toHaveBeenCalledWith(new Date(2023, 0, 1));
591591
});
592592

593+
it('does not call onChange for leap day until yyyy year is complete', async () => {
594+
const onChange = vi.fn();
595+
596+
await render(
597+
<DatePicker
598+
{...defaultProps}
599+
format="MM/dd/yyyy"
600+
onChange={onChange}
601+
openCalendarOnFocus={false}
602+
/>,
603+
);
604+
605+
const monthInput = page.getByRole('spinbutton', { name: 'month' });
606+
const dayInput = page.getByRole('spinbutton', { name: 'day' });
607+
const yearInput = page.getByRole('spinbutton', { name: 'year' });
608+
609+
await act(async () => {
610+
await userEvent.fill(monthInput, '02');
611+
await userEvent.fill(dayInput, '29');
612+
await userEvent.type(yearInput, '200');
613+
});
614+
615+
expect(onChange).not.toHaveBeenCalled();
616+
617+
await act(async () => {
618+
await userEvent.type(yearInput, '0');
619+
});
620+
621+
await vi.waitFor(() => expect(onChange).toHaveBeenCalledTimes(1));
622+
expect(onChange).toHaveBeenCalledWith(new Date(2000, 1, 29));
623+
});
624+
593625
it('calls onInvalidChange callback when changing value to an invalid one', async () => {
594626
const value = new Date(2023, 0, 31);
595627
const onInvalidChange = vi.fn();

sample/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
"react-dom": "^19.2.0"
2121
},
2222
"devDependencies": {
23-
"@vitejs/plugin-react": "^4.6.0",
23+
"@vitejs/plugin-react": "^6.0.1",
2424
"typescript": "^6.0.2",
25-
"vite": "^7.1.11"
25+
"vite": "^8.0.5"
2626
},
2727
"packageManager": "yarn@4.10.3"
2828
}

0 commit comments

Comments
 (0)