diff --git a/examples/AutoFocus.tsx b/examples/AutoFocus.tsx new file mode 100644 index 000000000..82aad429e --- /dev/null +++ b/examples/AutoFocus.tsx @@ -0,0 +1,12 @@ +import React from "react"; + +import { DayPicker } from "react-day-picker"; + +/** Test for the next focus day to not cause an infinite recursion. */ +export function AutoFocus() { + return ( +
+ +
+ ); +} diff --git a/examples/Dialog.tsx b/examples/Dialog.tsx index 8d7d12c4f..ee7213e6c 100644 --- a/examples/Dialog.tsx +++ b/examples/Dialog.tsx @@ -23,22 +23,16 @@ export function Dialog() { // Function to toggle the dialog visibility const toggleDialog = () => setIsDialogOpen(!isDialogOpen); - // Hook to handle the body scroll behavior and focus trapping. + // Hook to handle the body scroll behavior and focus trapping. You may want to + // use your own trapping library as the body.style overflow will break the + // scroll position. useEffect(() => { - const handleBodyScroll = (isOpen: boolean) => { - document.body.style.overflow = isOpen ? "hidden" : ""; - }; if (!dialogRef.current) return; if (isDialogOpen) { - handleBodyScroll(true); dialogRef.current.showModal(); } else { - handleBodyScroll(false); dialogRef.current.close(); } - return () => { - handleBodyScroll(false); - }; }, [isDialogOpen]); /** @@ -108,18 +102,21 @@ export function Dialog() { aria-labelledby={headerId} onClose={() => setIsDialogOpen(false)} > - Selected: {selectedDate.toDateString()} - ) - } - /> + {isDialogOpen && ( + Selected: {selectedDate.toDateString()} + ) + } + /> + )} ); diff --git a/examples/__snapshots__/Range.test.tsx.snap b/examples/__snapshots__/Range.test.tsx.snap index 5afc6c6e0..bca7c6591 100644 --- a/examples/__snapshots__/Range.test.tsx.snap +++ b/examples/__snapshots__/Range.test.tsx.snap @@ -159,7 +159,7 @@ exports[`should match the snapshot 1`] = ` @@ -353,7 +353,7 @@ exports[`should match the snapshot 1`] = ` diff --git a/examples/index.ts b/examples/index.ts index 7013d6071..34d9be9cc 100644 --- a/examples/index.ts +++ b/examples/index.ts @@ -15,6 +15,7 @@ export * from "./DisableNavigation"; export * from "./Dropdown"; export * from "./DropdownMultipleMonths"; export * from "./Fixedweeks"; +export * from "./AutoFocus"; export * from "./FocusRecursive"; export * from "./Footer"; export * from "./Formatters"; diff --git a/src/DayPicker.tsx b/src/DayPicker.tsx index 07f63e32c..b83787e6b 100644 --- a/src/DayPicker.tsx +++ b/src/DayPicker.tsx @@ -51,8 +51,7 @@ export function DayPicker(props: DayPickerProps) { const modifiers = useModifiers(props, calendar, dateLib); const selection = useSelection(props, dateLib); - const focus = useFocus(props, calendar, modifiers, dateLib); - + const focus = useFocus(props, calendar, modifiers, selection, dateLib); const { captionLayout, dir, @@ -537,6 +536,7 @@ export function DayPicker(props: DayPickerProps) { style={styles?.[UI.DayButton]} day={day} modifiers={m} + focused={isFocused} disabled={m.disabled || undefined} tabIndex={ focus.isFocusTarget(day) ? 0 : -1 diff --git a/src/components/DayButton.tsx b/src/components/DayButton.tsx index f90beeb93..d3ee84eca 100644 --- a/src/components/DayButton.tsx +++ b/src/components/DayButton.tsx @@ -16,14 +16,21 @@ import type { Modifiers } from "../types/index.js"; */ export function DayButton( props: { + /** Whether the day is focused. */ + focused: boolean; /** The day to render. */ day: CalendarDay; /** The modifiers for the day. */ modifiers: Modifiers; } & JSX.IntrinsicElements["button"] ) { - const { day, modifiers, ...buttonProps } = props; - return