diff --git a/packages/ui/src/components/Datepicker/Datepicker.stories.tsx b/packages/ui/src/components/Datepicker/Datepicker.stories.tsx index 78b261e0d..bca68b6e2 100644 --- a/packages/ui/src/components/Datepicker/Datepicker.stories.tsx +++ b/packages/ui/src/components/Datepicker/Datepicker.stories.tsx @@ -2,6 +2,7 @@ import type { Meta, StoryFn } from "@storybook/react"; import type { DatepickerProps } from "./Datepicker"; import { Datepicker } from "./Datepicker"; import { getFirstDateInRange, WeekStart } from "./helpers"; +import { useState } from "react"; export default { title: "Components/Datepicker", @@ -32,6 +33,13 @@ export default { } as Meta; const Template: StoryFn = (args) => { + const [selectedDate, setSelectedDate] = useState(args.value ?? null); + + const handleChange = (date: Date | null) => { + setSelectedDate(date); + }; + + // https://github.com/storybookjs/storybook/issues/11822 if (args.minDate) { args.minDate = new Date(args.minDate); @@ -47,7 +55,7 @@ const Template: StoryFn = (args) => { } } - return ; + return ; }; export const DefaultEmpty = Template.bind({}); DefaultEmpty.args = { @@ -56,11 +64,12 @@ DefaultEmpty.args = { showClearButton: true, showTodayButton: true, defaultValue: undefined, - value: undefined, + value: null, minDate: undefined, maxDate: undefined, language: "en", theme: {}, + label: "No date selected", }; export const Default = Template.bind({}); @@ -82,7 +91,6 @@ NullDateValue.args = { autoHide: true, showClearButton: true, showTodayButton: true, - value: "", minDate: undefined, maxDate: undefined, language: "en", diff --git a/packages/ui/src/components/Datepicker/Datepicker.tsx b/packages/ui/src/components/Datepicker/Datepicker.tsx index f2f40f71e..6c44a1d36 100644 --- a/packages/ui/src/components/Datepicker/Datepicker.tsx +++ b/packages/ui/src/components/Datepicker/Datepicker.tsx @@ -82,7 +82,7 @@ export interface DatepickerRef { clear: () => void; } -export interface DatepickerProps extends Omit { +export interface DatepickerProps extends Omit { defaultDate?: Date; open?: boolean; inline?: boolean; @@ -97,7 +97,7 @@ export interface DatepickerProps extends Omit; onChange?: (date: Date) => void; - customValue?: Date | null; + value?: Date | null; label?: string; } @@ -120,7 +120,7 @@ const DatepickerRender: ForwardRefRenderFunction theme: customTheme = {}, onChange, label, - customValue, + value, ...props }, ref, @@ -138,9 +138,9 @@ const DatepickerRender: ForwardRefRenderFunction const [isOpen, setIsOpen] = useState(open); const [view, setView] = useState(Views.Days); // selectedDate is the date selected by the user - const [selectedDate, setSelectedDate] = useState(customValue ?? effectiveDefaultValue); + const [selectedDate, setSelectedDate] = useState(value ?? effectiveDefaultValue); // viewDate is only for navigation - const [viewDate, setViewDate] = useState(customValue ?? effectiveDefaultView); + const [viewDate, setViewDate] = useState(value ?? effectiveDefaultView); const inputRef = useRef(null); const datepickerRef = useRef(null); @@ -251,15 +251,17 @@ const DatepickerRender: ForwardRefRenderFunction }, [inputRef, datepickerRef, setIsOpen]); useEffect(() => { - if (customValue !== undefined && customValue !== selectedDate) { - setSelectedDate(customValue); - customValue && setViewDate(customValue); + const effectiveValue = value && getFirstDateInRange(new Date(value), minDate, maxDate); + const effectiveSelectedDate = selectedDate && getFirstDateInRange(new Date(selectedDate), minDate, maxDate); + if (effectiveSelectedDate && effectiveValue && !isDateEqual(effectiveValue, effectiveSelectedDate)) { + setSelectedDate(effectiveValue); } if (selectedDate == null) { setSelectedDate(effectiveDefaultValue); - setViewDate(effectiveDefaultView); } - }, [customValue, setSelectedDate, setViewDate, selectedDate]); + }, [value, setSelectedDate, setViewDate, selectedDate]); + + const displayValue = value === null ? label : getFormattedDate(language, selectedDate || new Date()); return ( } setIsOpen(true); }} - value={selectedDate ? getFormattedDate(language, selectedDate) : label} + value={displayValue} readOnly defaultValue={effectiveDefaultValue ? getFormattedDate(language, effectiveDefaultValue) : label} {...props} diff --git a/packages/ui/src/components/Datepicker/helpers.ts b/packages/ui/src/components/Datepicker/helpers.ts index 6585f3bba..6c91eba11 100644 --- a/packages/ui/src/components/Datepicker/helpers.ts +++ b/packages/ui/src/components/Datepicker/helpers.ts @@ -38,6 +38,7 @@ export const isDateInRange = (date: Date, minDate?: Date, maxDate?: Date): boole }; export const isDateEqual = (date: Date, selectedDate: Date): boolean => { + debugger date = new Date(date.getFullYear(), date.getMonth(), date.getDate()); selectedDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate());