diff --git a/docs/components/InputGroup/Web.stories.tsx b/docs/components/InputGroup/Web.stories.tsx index ee93f59263..263a61016c 100644 --- a/docs/components/InputGroup/Web.stories.tsx +++ b/docs/components/InputGroup/Web.stories.tsx @@ -1,8 +1,9 @@ -import React from "react"; +import React, { useState } from "react"; import { ComponentMeta, ComponentStory } from "@storybook/react"; import { InputGroup } from "@jobber/components/InputGroup"; import { InputTime } from "@jobber/components/InputTime"; import { InputText } from "@jobber/components/InputText"; +import { InputDate } from "@jobber/components/InputDate"; export default { title: "Components/Forms and Inputs/InputGroup/Web", @@ -49,6 +50,27 @@ const NestedTemplate: ComponentStory = args => { ); }; +const DateRangeTemplate: ComponentStory = args => { + const [startDate, setStartDate] = useState(new Date("2024-01-01")); + const [endDate, setEndDate] = useState(new Date("2024-12-31")); + + return ( + + + + + ); +}; + export const Basic = BasicTemplate.bind({}); Basic.args = { flowDirection: "vertical", @@ -58,3 +80,8 @@ export const Nested = NestedTemplate.bind({}); Nested.args = { flowDirection: "vertical", }; + +export const DateRange = DateRangeTemplate.bind({}); +DateRange.args = { + flowDirection: "horizontal", +}; diff --git a/packages/components/src/DatePicker/DatePicker.tsx b/packages/components/src/DatePicker/DatePicker.tsx index eac94e48e9..6e11742020 100644 --- a/packages/components/src/DatePicker/DatePicker.tsx +++ b/packages/components/src/DatePicker/DatePicker.tsx @@ -83,6 +83,8 @@ interface DatePickerInlineProps extends BaseDatePickerProps { type DatePickerProps = XOR; +const openDatePickerRef = { current: null as ReactDatePicker | null }; + /*eslint max-statements: ["error", 13]*/ export function DatePicker({ onChange, @@ -115,7 +117,7 @@ export function DatePicker({ const datePickerClassNames = classnames(styles.datePicker, { [styles.inline]: inline, }); - const { pickerRef } = useEscapeKeyToCloseDatePicker(open, ref); + const { pickerRef } = useEscapeKeyToCloseDatePicker(open); if (smartAutofocus) { useRefocusOnActivator(open); @@ -170,35 +172,46 @@ export function DatePicker({ } function handleCalendarOpen() { + if ( + openDatePickerRef.current && + openDatePickerRef.current !== pickerRef.current + ) { + openDatePickerRef.current.setOpen(false); + } + + openDatePickerRef.current = pickerRef.current; setOpen(true); } function handleCalendarClose() { + if (openDatePickerRef.current === pickerRef.current) { + openDatePickerRef.current = null; + } setOpen(false); } } -function useEscapeKeyToCloseDatePicker( - open: boolean, - ref: React.RefObject, -): { pickerRef: React.RefObject } { +function useEscapeKeyToCloseDatePicker(open: boolean): { + pickerRef: React.RefObject; +} { const pickerRef = useRef(null); - const escFunction = (event: KeyboardEvent) => { - if (event.key === "Escape" && open) { - // Close the picker ourselves and prevent propagation so that ESC presses with the picker open - // do not close parent elements that may also be listening for ESC presses such as Modals - pickerRef.current?.setOpen(false); - event.stopPropagation(); - } - }; useEffect(() => { - ref.current?.addEventListener("keydown", escFunction); + const escFunction = (event: KeyboardEvent) => { + if (event.key === "Escape" && open) { + // Close the picker ourselves and prevent propagation so that ESC presses with the picker open + // do not close parent elements that may also be listening for ESC presses such as Modals + pickerRef.current?.setOpen(false); + event.stopPropagation(); + } + }; + + document.addEventListener("keydown", escFunction, true); return () => { - ref.current?.removeEventListener("keydown", escFunction); + document.removeEventListener("keydown", escFunction, true); }; - }, [open, ref, pickerRef]); + }, [open]); return { pickerRef,