@salt-ds/lab 1.0.0-alpha.61 → 1.0.0-alpha.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +102 -0
- package/css/salt-lab.css +623 -324
- package/dist-cjs/date-picker/DatePicker.js +4 -3
- package/dist-cjs/date-picker/DatePicker.js.map +1 -1
- package/dist-cjs/date-picker/DatePickerActions.js +1 -1
- package/dist-cjs/date-picker/DatePickerActions.js.map +1 -1
- package/dist-cjs/date-picker/DatePickerContext.js.map +1 -1
- package/dist-cjs/date-picker/DatePickerOverlay.js +0 -4
- package/dist-cjs/date-picker/DatePickerOverlay.js.map +1 -1
- package/dist-cjs/date-picker/DatePickerOverlayProvider.js +65 -43
- package/dist-cjs/date-picker/DatePickerOverlayProvider.js.map +1 -1
- package/dist-cjs/date-picker/DatePickerRangeInput.js +10 -26
- package/dist-cjs/date-picker/DatePickerRangeInput.js.map +1 -1
- package/dist-cjs/date-picker/DatePickerSingleInput.js +8 -14
- package/dist-cjs/date-picker/DatePickerSingleInput.js.map +1 -1
- package/dist-cjs/date-picker/useDatePicker.js +10 -7
- package/dist-cjs/date-picker/useDatePicker.js.map +1 -1
- package/dist-cjs/date-picker/useKeyboard.js +23 -0
- package/dist-cjs/date-picker/useKeyboard.js.map +1 -0
- package/dist-cjs/index.js +19 -8
- package/dist-cjs/index.js.map +1 -1
- package/dist-cjs/number-input/NumberInput.css.js +6 -0
- package/dist-cjs/number-input/NumberInput.css.js.map +1 -0
- package/dist-cjs/{stepper-input/StepperInput.js → number-input/NumberInput.js} +15 -15
- package/dist-cjs/number-input/NumberInput.js.map +1 -0
- package/dist-cjs/number-input/internal/useActivateWhileMouseDown.js.map +1 -0
- package/dist-cjs/number-input/internal/useInterval.js.map +1 -0
- package/dist-cjs/number-input/internal/utils.js.map +1 -0
- package/dist-cjs/{stepper-input/useStepperInput.js → number-input/useNumberInput.js} +3 -3
- package/dist-cjs/number-input/useNumberInput.js.map +1 -0
- package/dist-cjs/slider/RangeSlider.js +161 -0
- package/dist-cjs/slider/RangeSlider.js.map +1 -0
- package/dist-cjs/slider/Slider.js +104 -70
- package/dist-cjs/slider/Slider.js.map +1 -1
- package/dist-cjs/slider/internal/SliderThumb.css.js +6 -0
- package/dist-cjs/slider/internal/SliderThumb.css.js.map +1 -0
- package/dist-cjs/slider/internal/SliderThumb.js +136 -70
- package/dist-cjs/slider/internal/SliderThumb.js.map +1 -1
- package/dist-cjs/slider/internal/SliderTooltip.css.js +6 -0
- package/dist-cjs/slider/internal/SliderTooltip.css.js.map +1 -0
- package/dist-cjs/slider/internal/SliderTooltip.js +43 -0
- package/dist-cjs/slider/internal/SliderTooltip.js.map +1 -0
- package/dist-cjs/slider/internal/SliderTrack.css.js +6 -0
- package/dist-cjs/slider/internal/SliderTrack.css.js.map +1 -0
- package/dist-cjs/slider/internal/SliderTrack.js +160 -80
- package/dist-cjs/slider/internal/SliderTrack.js.map +1 -1
- package/dist-cjs/slider/internal/useRangeSliderThumb.js +194 -0
- package/dist-cjs/slider/internal/useRangeSliderThumb.js.map +1 -0
- package/dist-cjs/slider/internal/useSliderThumb.js +123 -0
- package/dist-cjs/slider/internal/useSliderThumb.js.map +1 -0
- package/dist-cjs/slider/internal/utils.js +97 -72
- package/dist-cjs/slider/internal/utils.js.map +1 -1
- package/dist-cjs/splitter/SplitHandle.css.js +6 -0
- package/dist-cjs/splitter/SplitHandle.css.js.map +1 -0
- package/dist-cjs/splitter/SplitHandle.js +60 -0
- package/dist-cjs/splitter/SplitHandle.js.map +1 -0
- package/dist-cjs/splitter/SplitPanel.css.js +6 -0
- package/dist-cjs/splitter/SplitPanel.css.js.map +1 -0
- package/dist-cjs/splitter/SplitPanel.js +37 -0
- package/dist-cjs/splitter/SplitPanel.js.map +1 -0
- package/dist-cjs/splitter/Splitter.js +31 -0
- package/dist-cjs/splitter/Splitter.js.map +1 -0
- package/dist-cjs/splitter/utils.js +18 -0
- package/dist-cjs/splitter/utils.js.map +1 -0
- package/dist-cjs/stepped-tracker/stepReducer.js +127 -81
- package/dist-cjs/stepped-tracker/stepReducer.js.map +1 -1
- package/dist-cjs/stepped-tracker/useStepReducer.js +6 -4
- package/dist-cjs/stepped-tracker/useStepReducer.js.map +1 -1
- package/dist-cjs/stepped-tracker/utils.js +44 -9
- package/dist-cjs/stepped-tracker/utils.js.map +1 -1
- package/dist-cjs/tabs-next/TabListNext.css.js +1 -1
- package/dist-cjs/tabs-next/TabListNext.js +10 -16
- package/dist-cjs/tabs-next/TabListNext.js.map +1 -1
- package/dist-cjs/tabs-next/TabOverflowList.css.js +1 -1
- package/dist-cjs/tabs-next/TabOverflowList.js +3 -2
- package/dist-cjs/tabs-next/TabOverflowList.js.map +1 -1
- package/dist-cjs/tabs-next/TabsNext.js +4 -51
- package/dist-cjs/tabs-next/TabsNext.js.map +1 -1
- package/dist-cjs/tabs-next/TabsNextContext.js +1 -1
- package/dist-cjs/tabs-next/TabsNextContext.js.map +1 -1
- package/dist-cjs/tabs-next/hooks/useCollection.js.map +1 -1
- package/dist-cjs/tabs-next/hooks/useOverflow.js +48 -5
- package/dist-cjs/tabs-next/hooks/useOverflow.js.map +1 -1
- package/dist-cjs/tabs-next/hooks/useRestoreActiveTab.js +93 -0
- package/dist-cjs/tabs-next/hooks/useRestoreActiveTab.js.map +1 -0
- package/dist-es/date-picker/DatePicker.js +4 -3
- package/dist-es/date-picker/DatePicker.js.map +1 -1
- package/dist-es/date-picker/DatePickerActions.js +1 -1
- package/dist-es/date-picker/DatePickerActions.js.map +1 -1
- package/dist-es/date-picker/DatePickerContext.js.map +1 -1
- package/dist-es/date-picker/DatePickerOverlay.js +0 -4
- package/dist-es/date-picker/DatePickerOverlay.js.map +1 -1
- package/dist-es/date-picker/DatePickerOverlayProvider.js +67 -45
- package/dist-es/date-picker/DatePickerOverlayProvider.js.map +1 -1
- package/dist-es/date-picker/DatePickerRangeInput.js +10 -26
- package/dist-es/date-picker/DatePickerRangeInput.js.map +1 -1
- package/dist-es/date-picker/DatePickerSingleInput.js +8 -14
- package/dist-es/date-picker/DatePickerSingleInput.js.map +1 -1
- package/dist-es/date-picker/useDatePicker.js +10 -7
- package/dist-es/date-picker/useDatePicker.js.map +1 -1
- package/dist-es/date-picker/useKeyboard.js +21 -0
- package/dist-es/date-picker/useKeyboard.js.map +1 -0
- package/dist-es/index.js +9 -4
- package/dist-es/index.js.map +1 -1
- package/dist-es/number-input/NumberInput.css.js +4 -0
- package/dist-es/number-input/NumberInput.css.js.map +1 -0
- package/dist-es/{stepper-input/StepperInput.js → number-input/NumberInput.js} +14 -14
- package/dist-es/number-input/NumberInput.js.map +1 -0
- package/dist-es/number-input/internal/useActivateWhileMouseDown.js.map +1 -0
- package/dist-es/number-input/internal/useInterval.js.map +1 -0
- package/dist-es/number-input/internal/utils.js.map +1 -0
- package/dist-es/{stepper-input/useStepperInput.js → number-input/useNumberInput.js} +3 -3
- package/dist-es/number-input/useNumberInput.js.map +1 -0
- package/dist-es/slider/RangeSlider.js +159 -0
- package/dist-es/slider/RangeSlider.js.map +1 -0
- package/dist-es/slider/Slider.js +107 -73
- package/dist-es/slider/Slider.js.map +1 -1
- package/dist-es/slider/internal/SliderThumb.css.js +4 -0
- package/dist-es/slider/internal/SliderThumb.css.js.map +1 -0
- package/dist-es/slider/internal/SliderThumb.js +138 -72
- package/dist-es/slider/internal/SliderThumb.js.map +1 -1
- package/dist-es/slider/internal/SliderTooltip.css.js +4 -0
- package/dist-es/slider/internal/SliderTooltip.css.js.map +1 -0
- package/dist-es/slider/internal/SliderTooltip.js +41 -0
- package/dist-es/slider/internal/SliderTooltip.js.map +1 -0
- package/dist-es/slider/internal/SliderTrack.css.js +4 -0
- package/dist-es/slider/internal/SliderTrack.css.js.map +1 -0
- package/dist-es/slider/internal/SliderTrack.js +164 -84
- package/dist-es/slider/internal/SliderTrack.js.map +1 -1
- package/dist-es/slider/internal/useRangeSliderThumb.js +192 -0
- package/dist-es/slider/internal/useRangeSliderThumb.js.map +1 -0
- package/dist-es/slider/internal/useSliderThumb.js +121 -0
- package/dist-es/slider/internal/useSliderThumb.js.map +1 -0
- package/dist-es/slider/internal/utils.js +91 -63
- package/dist-es/slider/internal/utils.js.map +1 -1
- package/dist-es/splitter/SplitHandle.css.js +4 -0
- package/dist-es/splitter/SplitHandle.css.js.map +1 -0
- package/dist-es/splitter/SplitHandle.js +58 -0
- package/dist-es/splitter/SplitHandle.js.map +1 -0
- package/dist-es/splitter/SplitPanel.css.js +4 -0
- package/dist-es/splitter/SplitPanel.css.js.map +1 -0
- package/dist-es/splitter/SplitPanel.js +35 -0
- package/dist-es/splitter/SplitPanel.js.map +1 -0
- package/dist-es/splitter/Splitter.js +27 -0
- package/dist-es/splitter/Splitter.js.map +1 -0
- package/dist-es/splitter/utils.js +15 -0
- package/dist-es/splitter/utils.js.map +1 -0
- package/dist-es/stepped-tracker/stepReducer.js +128 -82
- package/dist-es/stepped-tracker/stepReducer.js.map +1 -1
- package/dist-es/stepped-tracker/useStepReducer.js +7 -5
- package/dist-es/stepped-tracker/useStepReducer.js.map +1 -1
- package/dist-es/stepped-tracker/utils.js +43 -9
- package/dist-es/stepped-tracker/utils.js.map +1 -1
- package/dist-es/tabs-next/TabListNext.css.js +1 -1
- package/dist-es/tabs-next/TabListNext.js +11 -17
- package/dist-es/tabs-next/TabListNext.js.map +1 -1
- package/dist-es/tabs-next/TabOverflowList.css.js +1 -1
- package/dist-es/tabs-next/TabOverflowList.js +4 -3
- package/dist-es/tabs-next/TabOverflowList.js.map +1 -1
- package/dist-es/tabs-next/TabsNext.js +5 -52
- package/dist-es/tabs-next/TabsNext.js.map +1 -1
- package/dist-es/tabs-next/TabsNextContext.js +1 -1
- package/dist-es/tabs-next/TabsNextContext.js.map +1 -1
- package/dist-es/tabs-next/hooks/useCollection.js.map +1 -1
- package/dist-es/tabs-next/hooks/useOverflow.js +49 -6
- package/dist-es/tabs-next/hooks/useOverflow.js.map +1 -1
- package/dist-es/tabs-next/hooks/useRestoreActiveTab.js +91 -0
- package/dist-es/tabs-next/hooks/useRestoreActiveTab.js.map +1 -0
- package/dist-types/date-picker/DatePicker.d.ts +6 -1
- package/dist-types/date-picker/DatePickerContext.d.ts +2 -1
- package/dist-types/date-picker/DatePickerOverlayProvider.d.ts +18 -4
- package/dist-types/date-picker/DatePickerRangeInput.d.ts +1 -1
- package/dist-types/date-picker/index.d.ts +1 -0
- package/dist-types/date-picker/useKeyboard.d.ts +14 -0
- package/dist-types/index.d.ts +5 -4
- package/dist-types/{stepper-input/StepperInput.d.ts → number-input/NumberInput.d.ts} +7 -7
- package/dist-types/number-input/index.d.ts +2 -0
- package/dist-types/{stepper-input/useStepperInput.d.ts → number-input/useNumberInput.d.ts} +2 -2
- package/dist-types/slider/RangeSlider.d.ts +91 -0
- package/dist-types/slider/Slider.d.ts +74 -15
- package/dist-types/slider/index.d.ts +1 -1
- package/dist-types/slider/internal/SliderThumb.d.ts +20 -7
- package/dist-types/slider/internal/SliderTooltip.d.ts +6 -0
- package/dist-types/slider/internal/SliderTrack.d.ts +23 -3
- package/dist-types/slider/internal/useRangeSliderThumb.d.ts +26 -0
- package/dist-types/slider/internal/useSliderThumb.d.ts +24 -0
- package/dist-types/slider/internal/utils.d.ts +17 -15
- package/dist-types/splitter/SplitHandle.d.ts +21 -0
- package/dist-types/splitter/SplitPanel.d.ts +10 -0
- package/dist-types/splitter/Splitter.d.ts +22 -0
- package/dist-types/splitter/index.d.ts +4 -0
- package/dist-types/splitter/utils.d.ts +4 -0
- package/dist-types/stepped-tracker/Step.types.d.ts +2 -4
- package/dist-types/stepped-tracker/stepReducer.types.d.ts +6 -4
- package/dist-types/stepped-tracker/utils.d.ts +6 -3
- package/dist-types/tabs/drag-drop/drag-utils.d.ts +6 -6
- package/dist-types/tabs-next/TabsNextContext.d.ts +1 -1
- package/dist-types/tabs-next/hooks/useOverflow.d.ts +1 -1
- package/dist-types/tabs-next/hooks/useRestoreActiveTab.d.ts +10 -0
- package/package.json +4 -3
- package/dist-cjs/slider/Slider.css.js +0 -6
- package/dist-cjs/slider/Slider.css.js.map +0 -1
- package/dist-cjs/slider/internal/SliderContext.js +0 -19
- package/dist-cjs/slider/internal/SliderContext.js.map +0 -1
- package/dist-cjs/slider/internal/SliderMarks.js +0 -29
- package/dist-cjs/slider/internal/SliderMarks.js.map +0 -1
- package/dist-cjs/slider/internal/SliderSelection.js +0 -33
- package/dist-cjs/slider/internal/SliderSelection.js.map +0 -1
- package/dist-cjs/slider/internal/useKeyDownThumb.js +0 -50
- package/dist-cjs/slider/internal/useKeyDownThumb.js.map +0 -1
- package/dist-cjs/stepper-input/StepperInput.css.js +0 -6
- package/dist-cjs/stepper-input/StepperInput.css.js.map +0 -1
- package/dist-cjs/stepper-input/StepperInput.js.map +0 -1
- package/dist-cjs/stepper-input/internal/useActivateWhileMouseDown.js.map +0 -1
- package/dist-cjs/stepper-input/internal/useInterval.js.map +0 -1
- package/dist-cjs/stepper-input/internal/utils.js.map +0 -1
- package/dist-cjs/stepper-input/useStepperInput.js.map +0 -1
- package/dist-es/slider/Slider.css.js +0 -4
- package/dist-es/slider/Slider.css.js.map +0 -1
- package/dist-es/slider/internal/SliderContext.js +0 -16
- package/dist-es/slider/internal/SliderContext.js.map +0 -1
- package/dist-es/slider/internal/SliderMarks.js +0 -27
- package/dist-es/slider/internal/SliderMarks.js.map +0 -1
- package/dist-es/slider/internal/SliderSelection.js +0 -31
- package/dist-es/slider/internal/SliderSelection.js.map +0 -1
- package/dist-es/slider/internal/useKeyDownThumb.js +0 -48
- package/dist-es/slider/internal/useKeyDownThumb.js.map +0 -1
- package/dist-es/stepper-input/StepperInput.css.js +0 -4
- package/dist-es/stepper-input/StepperInput.css.js.map +0 -1
- package/dist-es/stepper-input/StepperInput.js.map +0 -1
- package/dist-es/stepper-input/internal/useActivateWhileMouseDown.js.map +0 -1
- package/dist-es/stepper-input/internal/useInterval.js.map +0 -1
- package/dist-es/stepper-input/internal/utils.js.map +0 -1
- package/dist-es/stepper-input/useStepperInput.js.map +0 -1
- package/dist-types/slider/internal/SliderContext.d.ts +0 -11
- package/dist-types/slider/internal/SliderMarks.d.ts +0 -7
- package/dist-types/slider/internal/SliderSelection.d.ts +0 -4
- package/dist-types/slider/internal/index.d.ts +0 -3
- package/dist-types/slider/internal/useKeyDownThumb.d.ts +0 -2
- package/dist-types/slider/types.d.ts +0 -4
- package/dist-types/stepper-input/index.d.ts +0 -2
- /package/dist-cjs/{stepper-input → number-input}/internal/useActivateWhileMouseDown.js +0 -0
- /package/dist-cjs/{stepper-input → number-input}/internal/useInterval.js +0 -0
- /package/dist-cjs/{stepper-input → number-input}/internal/utils.js +0 -0
- /package/dist-es/{stepper-input → number-input}/internal/useActivateWhileMouseDown.js +0 -0
- /package/dist-es/{stepper-input → number-input}/internal/useInterval.js +0 -0
- /package/dist-es/{stepper-input → number-input}/internal/utils.js +0 -0
- /package/dist-types/{stepper-input → number-input}/internal/useActivateWhileMouseDown.d.ts +0 -0
- /package/dist-types/{stepper-input → number-input}/internal/useInterval.d.ts +0 -0
- /package/dist-types/{stepper-input → number-input}/internal/utils.d.ts +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePickerContext.js","sources":["../src/date-picker/DatePickerContext.ts"],"sourcesContent":["import { createContext } from \"@salt-ds/core\";\nimport type { DateFrameworkType } from \"@salt-ds/date-adapters\";\nimport { type Context, type Ref, type SyntheticEvent, useContext } from \"react\";\nimport type { DateRangeSelection, SingleDateSelection } from \"../calendar\";\nimport type {\n DateInputRangeDetails,\n DateInputSingleDetails,\n} from \"../date-input\";\n\n/**\n * Interface representing the base state for a DatePicker.\n */\ninterface DatePickerBaseState<TDate extends DateFrameworkType> {\n /**\n * The state properties of the DatePicker.\n */\n state: {\n /**\n * If `true`, the DatePicker is disabled.\n */\n disabled?: boolean;\n /**\n * If `true`, the DatePicker is read-only.\n */\n readOnly?: boolean;\n /**\n * If `true`, the DatePicker has been cancelled.\n */\n cancelled?: boolean;\n /**\n * If `true`, the apply action is enabled.\n */\n enableApply?: boolean;\n /**\n * The minimum selectable date.\n */\n minDate?: TDate;\n /**\n * The maximum selectable date.\n */\n maxDate?: TDate;\n /**\n * Reference to the container element.\n */\n containerRef: Ref<HTMLDivElement>;\n };\n /**\n * Helper functions for managing the DatePicker state.\n */\n helpers: {\n /**\n * Cancels the DatePicker action.\n */\n cancel: () => void;\n /**\n * Sets the enableApply state.\n * @param newEnableApply - The new value for enableApply.\n */\n setEnableApply: (newEnableApply: boolean) => void;\n };\n}\n\n/**\n * Interface representing the state for a single date picker.\n */\nexport interface SingleDatePickerState<TDate extends DateFrameworkType>\n extends DatePickerBaseState<TDate> {\n /**\n * The state properties of the single date picker.\n */\n state: DatePickerBaseState<TDate>[\"state\"] & {\n /**\n * The selected date.\n */\n selectedDate: SingleDateSelection<TDate> | null;\n /**\n * The default selected date.\n */\n defaultSelectedDate?: SingleDateSelection<TDate>;\n };\n /**\n * Helper functions for managing the single date picker state.\n */\n helpers: DatePickerBaseState<TDate>[\"helpers\"] & {\n /**\n * Apply the selected single date.\n * @param event - The synthetic event.\n * @param date - The new applied date.\n */\n apply: (\n event: SyntheticEvent,\n date: SingleDateSelection<TDate> | null,\n ) => void;\n /**\n * Select a single date.\n * @param event - The synthetic event.\n * @param date - The selected date or null.\n * @param details - Details of selection, such as errors and original value.\n */\n select: (\n event: SyntheticEvent,\n date: SingleDateSelection<TDate> | null,\n details?: DateInputSingleDetails,\n ) => void;\n };\n}\n\n/**\n * Interface representing the state for a range date picker.\n */\nexport interface RangeDatePickerState<TDate extends DateFrameworkType>\n extends DatePickerBaseState<TDate> {\n /**\n * The state properties of the range date picker.\n */\n state: DatePickerBaseState<TDate>[\"state\"] & {\n /**\n * The selected date range.\n */\n selectedDate: DateRangeSelection<TDate> | null;\n /**\n * The default selected date range.\n */\n defaultSelectedDate?: DateRangeSelection<TDate>;\n };\n /**\n * Helper functions for managing the range date picker state.\n */\n helpers: DatePickerBaseState<TDate>[\"helpers\"] & {\n /**\n * Apply the selected date range.\n * @param event - The synthetic event.\n * @param date - The new applied date range\n */\n apply: (\n event: SyntheticEvent,\n date: DateRangeSelection<TDate> | null,\n ) => void;\n /**\n * Select a date range.\n * @param event - The synthetic event.\n * @param date - The selected date.\n * @param details - Details of selection, such as errors and original value. */\n select: (\n event: SyntheticEvent,\n date: DateRangeSelection<TDate> | null,\n details?: DateInputRangeDetails,\n ) => void;\n };\n}\n\n/**\n * Type representing the state of a date picker, either single or range.\n */\nexport type DatePickerState<TDate extends DateFrameworkType> =\n | SingleDatePickerState<TDate>\n | RangeDatePickerState<TDate>;\n\n/**\n * Context for single date selection.\n */\nexport const SingleDateSelectionContext = createContext<\n SingleDatePickerState<any> | undefined\n>(\"SingleDateSelectionContext\", undefined);\n\n/**\n * Context for date range selection.\n */\nexport const DateRangeSelectionContext = createContext<\n RangeDatePickerState<any> | undefined\n>(\"DateRangeSelectionContext\", undefined);\n\n/**\n * Props for using the date picker context.\n */\nexport interface UseDatePickerContextProps {\n /**\n * The selection variant, either \"single\" or \"range\".\n */\n selectionVariant: \"single\" | \"range\";\n}\n\n// Overloads\n\n/**\n * Hook to use the date picker context for single date selection.\n * @param props - The props for the hook.\n * @returns The state of the single date picker.\n */\nexport function useDatePickerContext<TDate extends DateFrameworkType>(props: {\n selectionVariant: \"single\";\n}): SingleDatePickerState<TDate>;\n\n/**\n * Hook to use the date picker context for range date selection.\n * @param props - The props for the hook.\n * @returns The state of the range date picker.\n */\nexport function useDatePickerContext<TDate extends DateFrameworkType>(props: {\n selectionVariant: \"range\";\n}): RangeDatePickerState<TDate>;\n\nexport function useDatePickerContext<TDate extends DateFrameworkType>({\n selectionVariant,\n}: UseDatePickerContextProps): DatePickerState<TDate> {\n if (selectionVariant === \"range\") {\n const context = useContext(\n DateRangeSelectionContext as Context<\n RangeDatePickerState<TDate> | undefined\n >,\n );\n if (!context) {\n throw new Error(\n 'useDatePickerSelection should be called with props { selectionVariant : \"range\" } inside DateRangeSelectionContext.Provider',\n );\n }\n return context;\n }\n const context = useContext(\n SingleDateSelectionContext as Context<\n SingleDatePickerState<TDate> | undefined\n >,\n );\n if (!context) {\n throw new Error(\n 'useDatePickerSelection should be called with props { selectionVariant : \"single\" } inside SingleDateSelectionContext.Provider',\n );\n }\n return context;\n}\n"],"names":["context"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"DatePickerContext.js","sources":["../src/date-picker/DatePickerContext.ts"],"sourcesContent":["import { createContext } from \"@salt-ds/core\";\nimport type { DateFrameworkType } from \"@salt-ds/date-adapters\";\nimport { type Context, type Ref, type SyntheticEvent, useContext } from \"react\";\nimport type { DateRangeSelection, SingleDateSelection } from \"../calendar\";\nimport type {\n DateInputRangeDetails,\n DateInputSingleDetails,\n} from \"../date-input\";\n\n/**\n * Interface representing the base state for a DatePicker.\n */\ninterface DatePickerBaseState<TDate extends DateFrameworkType> {\n /**\n * The state properties of the DatePicker.\n */\n state: {\n /**\n * If `true`, the DatePicker is disabled.\n */\n disabled?: boolean;\n /**\n * If `true`, the DatePicker is read-only.\n */\n readOnly?: boolean;\n /**\n * If `true`, the DatePicker has been cancelled.\n */\n cancelled?: boolean;\n /**\n * If `true`, the apply action is enabled.\n */\n enableApply?: boolean;\n /**\n * The minimum selectable date.\n */\n minDate?: TDate;\n /**\n * The maximum selectable date.\n */\n maxDate?: TDate;\n /**\n * Reference to the container element.\n */\n containerRef: Ref<HTMLDivElement>;\n };\n /**\n * Helper functions for managing the DatePicker state.\n */\n helpers: {\n /**\n * Cancels the DatePicker action.\n * @param event - event that triggered the state change\n */\n cancel: (event?: Event) => void;\n /**\n * Sets the enableApply state.\n * @param newEnableApply - The new value for enableApply.\n */\n setEnableApply: (newEnableApply: boolean) => void;\n };\n}\n\n/**\n * Interface representing the state for a single date picker.\n */\nexport interface SingleDatePickerState<TDate extends DateFrameworkType>\n extends DatePickerBaseState<TDate> {\n /**\n * The state properties of the single date picker.\n */\n state: DatePickerBaseState<TDate>[\"state\"] & {\n /**\n * The selected date.\n */\n selectedDate: SingleDateSelection<TDate> | null;\n /**\n * The default selected date.\n */\n defaultSelectedDate?: SingleDateSelection<TDate>;\n };\n /**\n * Helper functions for managing the single date picker state.\n */\n helpers: DatePickerBaseState<TDate>[\"helpers\"] & {\n /**\n * Apply the selected single date.\n * @param event - The synthetic event.\n * @param date - The new applied date.\n */\n apply: (\n event: SyntheticEvent,\n date: SingleDateSelection<TDate> | null,\n ) => void;\n /**\n * Select a single date.\n * @param event - The synthetic event.\n * @param date - The selected date or null.\n * @param details - Details of selection, such as errors and original value.\n */\n select: (\n event: SyntheticEvent,\n date: SingleDateSelection<TDate> | null,\n details?: DateInputSingleDetails,\n ) => void;\n };\n}\n\n/**\n * Interface representing the state for a range date picker.\n */\nexport interface RangeDatePickerState<TDate extends DateFrameworkType>\n extends DatePickerBaseState<TDate> {\n /**\n * The state properties of the range date picker.\n */\n state: DatePickerBaseState<TDate>[\"state\"] & {\n /**\n * The selected date range.\n */\n selectedDate: DateRangeSelection<TDate> | null;\n /**\n * The default selected date range.\n */\n defaultSelectedDate?: DateRangeSelection<TDate>;\n };\n /**\n * Helper functions for managing the range date picker state.\n */\n helpers: DatePickerBaseState<TDate>[\"helpers\"] & {\n /**\n * Apply the selected date range.\n * @param event - The synthetic event.\n * @param date - The new applied date range\n */\n apply: (\n event: SyntheticEvent,\n date: DateRangeSelection<TDate> | null,\n ) => void;\n /**\n * Select a date range.\n * @param event - The synthetic event.\n * @param date - The selected date.\n * @param details - Details of selection, such as errors and original value. */\n select: (\n event: SyntheticEvent,\n date: DateRangeSelection<TDate> | null,\n details?: DateInputRangeDetails,\n ) => void;\n };\n}\n\n/**\n * Type representing the state of a date picker, either single or range.\n */\nexport type DatePickerState<TDate extends DateFrameworkType> =\n | SingleDatePickerState<TDate>\n | RangeDatePickerState<TDate>;\n\n/**\n * Context for single date selection.\n */\nexport const SingleDateSelectionContext = createContext<\n SingleDatePickerState<any> | undefined\n>(\"SingleDateSelectionContext\", undefined);\n\n/**\n * Context for date range selection.\n */\nexport const DateRangeSelectionContext = createContext<\n RangeDatePickerState<any> | undefined\n>(\"DateRangeSelectionContext\", undefined);\n\n/**\n * Props for using the date picker context.\n */\nexport interface UseDatePickerContextProps {\n /**\n * The selection variant, either \"single\" or \"range\".\n */\n selectionVariant: \"single\" | \"range\";\n}\n\n// Overloads\n\n/**\n * Hook to use the date picker context for single date selection.\n * @param props - The props for the hook.\n * @returns The state of the single date picker.\n */\nexport function useDatePickerContext<TDate extends DateFrameworkType>(props: {\n selectionVariant: \"single\";\n}): SingleDatePickerState<TDate>;\n\n/**\n * Hook to use the date picker context for range date selection.\n * @param props - The props for the hook.\n * @returns The state of the range date picker.\n */\nexport function useDatePickerContext<TDate extends DateFrameworkType>(props: {\n selectionVariant: \"range\";\n}): RangeDatePickerState<TDate>;\n\nexport function useDatePickerContext<TDate extends DateFrameworkType>({\n selectionVariant,\n}: UseDatePickerContextProps): DatePickerState<TDate> {\n if (selectionVariant === \"range\") {\n const context = useContext(\n DateRangeSelectionContext as Context<\n RangeDatePickerState<TDate> | undefined\n >,\n );\n if (!context) {\n throw new Error(\n 'useDatePickerSelection should be called with props { selectionVariant : \"range\" } inside DateRangeSelectionContext.Provider',\n );\n }\n return context;\n }\n const context = useContext(\n SingleDateSelectionContext as Context<\n SingleDatePickerState<TDate> | undefined\n >,\n );\n if (!context) {\n throw new Error(\n 'useDatePickerSelection should be called with props { selectionVariant : \"single\" } inside SingleDateSelectionContext.Provider',\n );\n }\n return context;\n}\n"],"names":["context"],"mappings":";;;AAkKa,MAAA,0BAAA,GAA6B,aAExC,CAAA,4BAAA,EAA8B,KAAS,CAAA;AAK5B,MAAA,yBAAA,GAA4B,aAEvC,CAAA,2BAAA,EAA6B,KAAS,CAAA;AAgCjC,SAAS,oBAAsD,CAAA;AAAA,EACpE;AACF,CAAsD,EAAA;AACpD,EAAA,IAAI,qBAAqB,OAAS,EAAA;AAChC,IAAA,MAAMA,QAAU,GAAA,UAAA;AAAA,MACd;AAAA,KAGF;AACA,IAAA,IAAI,CAACA,QAAS,EAAA;AACZ,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA;AAEF,IAAOA,OAAAA,QAAAA;AAAA;AAET,EAAA,MAAM,OAAU,GAAA,UAAA;AAAA,IACd;AAAA,GAGF;AACA,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA;AAEF,EAAO,OAAA,OAAA;AACT;;;;"}
|
|
@@ -33,10 +33,6 @@ const DatePickerOverlay = forwardRef(function DatePickerOverlay2({ className, ch
|
|
|
33
33
|
role: "dialog",
|
|
34
34
|
"aria-modal": "true",
|
|
35
35
|
ref: floatingRef,
|
|
36
|
-
focusManagerProps: (floatingUIResult == null ? void 0 : floatingUIResult.context) ? {
|
|
37
|
-
context: floatingUIResult.context,
|
|
38
|
-
initialFocus: 4
|
|
39
|
-
} : void 0,
|
|
40
36
|
...getFloatingProps ? getFloatingProps({
|
|
41
37
|
...a11yProps,
|
|
42
38
|
...rest
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePickerOverlay.js","sources":["../src/date-picker/DatePickerOverlay.tsx"],"sourcesContent":["import {\n makePrefixer,\n useFloatingComponent,\n useForkRef,\n useFormFieldProps,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n type ReactNode,\n forwardRef,\n} from \"react\";\nimport datePickerOverlayCss from \"./DatePickerOverlay.css\";\nimport { useDatePickerOverlay } from \"./DatePickerOverlayProvider\";\n\nconst withBaseName = makePrefixer(\"saltDatePickerOverlay\");\n\n/**\n * Props for the DatePickerOverlay component.\n */\nexport interface DatePickerOverlayProps\n extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The content to be rendered inside the overlay.\n */\n children: ReactNode;\n}\n\nexport const DatePickerOverlay = forwardRef<\n HTMLDivElement,\n DatePickerOverlayProps\n>(function DatePickerOverlay({ className, children, ...rest }, ref) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-date-picker-overlay\",\n css: datePickerOverlayCss,\n window: targetWindow,\n });\n\n const { Component: FloatingComponent } = useFloatingComponent();\n\n const { a11yProps } = useFormFieldProps();\n\n const {\n state: { open, floatingUIResult },\n helpers: { getFloatingProps },\n } = useDatePickerOverlay();\n\n const floatingRef = useForkRef<HTMLDivElement>(\n ref,\n floatingUIResult?.floating,\n );\n\n return (\n <FloatingComponent\n className={clsx(withBaseName(), className)}\n open={open || false}\n role=\"dialog\"\n aria-modal=\"true\"\n ref={floatingRef}\n
|
|
1
|
+
{"version":3,"file":"DatePickerOverlay.js","sources":["../src/date-picker/DatePickerOverlay.tsx"],"sourcesContent":["import {\n makePrefixer,\n useFloatingComponent,\n useForkRef,\n useFormFieldProps,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n type ReactNode,\n forwardRef,\n} from \"react\";\nimport datePickerOverlayCss from \"./DatePickerOverlay.css\";\nimport { useDatePickerOverlay } from \"./DatePickerOverlayProvider\";\n\nconst withBaseName = makePrefixer(\"saltDatePickerOverlay\");\n\n/**\n * Props for the DatePickerOverlay component.\n */\nexport interface DatePickerOverlayProps\n extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The content to be rendered inside the overlay.\n */\n children: ReactNode;\n}\n\nexport const DatePickerOverlay = forwardRef<\n HTMLDivElement,\n DatePickerOverlayProps\n>(function DatePickerOverlay({ className, children, ...rest }, ref) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-date-picker-overlay\",\n css: datePickerOverlayCss,\n window: targetWindow,\n });\n\n const { Component: FloatingComponent } = useFloatingComponent();\n\n const { a11yProps } = useFormFieldProps();\n\n const {\n state: { open, floatingUIResult },\n helpers: { getFloatingProps },\n } = useDatePickerOverlay();\n\n const floatingRef = useForkRef<HTMLDivElement>(\n ref,\n floatingUIResult?.floating,\n );\n\n return (\n <FloatingComponent\n className={clsx(withBaseName(), className)}\n open={open || false}\n role=\"dialog\"\n aria-modal=\"true\"\n ref={floatingRef}\n {...(getFloatingProps\n ? getFloatingProps({\n ...a11yProps,\n ...rest,\n })\n : rest)}\n >\n {children}\n </FloatingComponent>\n );\n});\n"],"names":["DatePickerOverlay","datePickerOverlayCss"],"mappings":";;;;;;;;;AAiBA,MAAM,YAAA,GAAe,aAAa,uBAAuB,CAAA;AAa5C,MAAA,iBAAA,GAAoB,UAG/B,CAAA,SAASA,kBAAkB,CAAA,EAAE,WAAW,QAAU,EAAA,GAAG,IAAK,EAAA,EAAG,GAAK,EAAA;AAClE,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,0BAAA;AAAA,IACR,GAAK,EAAAC,QAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,EAAE,SAAA,EAAW,iBAAkB,EAAA,GAAI,oBAAqB,EAAA;AAE9D,EAAM,MAAA,EAAE,SAAU,EAAA,GAAI,iBAAkB,EAAA;AAExC,EAAM,MAAA;AAAA,IACJ,KAAA,EAAO,EAAE,IAAA,EAAM,gBAAiB,EAAA;AAAA,IAChC,OAAA,EAAS,EAAE,gBAAiB;AAAA,MAC1B,oBAAqB,EAAA;AAEzB,EAAA,MAAM,WAAc,GAAA,UAAA;AAAA,IAClB,GAAA;AAAA,IACA,gBAAkB,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,gBAAA,CAAA;AAAA,GACpB;AAEA,EACE,uBAAA,GAAA;AAAA,IAAC,iBAAA;AAAA,IAAA;AAAA,MACC,SAAW,EAAA,IAAA,CAAK,YAAa,EAAA,EAAG,SAAS,CAAA;AAAA,MACzC,MAAM,IAAQ,IAAA,KAAA;AAAA,MACd,IAAK,EAAA,QAAA;AAAA,MACL,YAAW,EAAA,MAAA;AAAA,MACX,GAAK,EAAA,WAAA;AAAA,MACJ,GAAI,mBACD,gBAAiB,CAAA;AAAA,QACf,GAAG,SAAA;AAAA,QACH,GAAG;AAAA,OACJ,CACD,GAAA,IAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ,CAAC;;;;"}
|
|
@@ -1,66 +1,79 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { flip, useInteractions, useDismiss } from '@floating-ui/react';
|
|
2
|
+
import { flip, useInteractions, useDismiss, useClick } from '@floating-ui/react';
|
|
3
3
|
import { createContext, useControlled, useFloatingUI } from '@salt-ds/core';
|
|
4
|
-
import {
|
|
4
|
+
import { useState, useRef, useCallback, useMemo, useContext } from 'react';
|
|
5
|
+
import { useKeyboard } from './useKeyboard.js';
|
|
5
6
|
|
|
6
7
|
const DatePickerOverlayContext = createContext("DatePickerOverlayContext", void 0);
|
|
7
|
-
const DatePickerOverlayProvider = ({
|
|
8
|
-
|
|
8
|
+
const DatePickerOverlayProvider = ({
|
|
9
|
+
open: openProp,
|
|
10
|
+
openOnClick,
|
|
11
|
+
defaultOpen,
|
|
12
|
+
onOpenChange,
|
|
13
|
+
children,
|
|
14
|
+
interactions,
|
|
15
|
+
readOnly
|
|
16
|
+
}) => {
|
|
17
|
+
const [open, setOpenState, isOpenControlled] = useControlled({
|
|
9
18
|
controlled: openProp,
|
|
10
19
|
default: Boolean(defaultOpen),
|
|
11
20
|
name: "DatePicker",
|
|
12
21
|
state: "openDatePickerOverlay"
|
|
13
22
|
});
|
|
14
|
-
const
|
|
23
|
+
const [disableFocus, setDisableFocus] = useState(true);
|
|
24
|
+
const triggeringElementRef = useRef(null);
|
|
15
25
|
const onDismissCallback = useRef();
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const trigger = triggeringElement.current;
|
|
19
|
-
if (trigger) {
|
|
20
|
-
trigger.focus();
|
|
21
|
-
}
|
|
22
|
-
if (trigger instanceof HTMLInputElement) {
|
|
23
|
-
setTimeout(() => {
|
|
24
|
-
trigger.setSelectionRange(0, trigger.value.length);
|
|
25
|
-
}, 0);
|
|
26
|
-
}
|
|
27
|
-
triggeringElement.current = null;
|
|
28
|
-
}
|
|
29
|
-
}, [open]);
|
|
30
|
-
const setOpen = useCallback(
|
|
31
|
-
(newOpen, _event, reason) => {
|
|
26
|
+
const handleOpenChange = useCallback(
|
|
27
|
+
(newOpen, event, reason) => {
|
|
32
28
|
var _a;
|
|
33
29
|
if (newOpen) {
|
|
34
30
|
if (readOnly) {
|
|
35
31
|
return;
|
|
36
32
|
}
|
|
37
|
-
|
|
33
|
+
triggeringElementRef.current = document.activeElement;
|
|
34
|
+
setDisableFocus(reason === "click");
|
|
35
|
+
} else if (!isOpenControlled) {
|
|
36
|
+
const trigger = triggeringElementRef.current;
|
|
37
|
+
if (trigger) {
|
|
38
|
+
trigger.focus();
|
|
39
|
+
}
|
|
40
|
+
if (trigger instanceof HTMLInputElement) {
|
|
41
|
+
setTimeout(() => {
|
|
42
|
+
trigger.setSelectionRange(0, trigger.value.length);
|
|
43
|
+
}, 1);
|
|
44
|
+
}
|
|
45
|
+
triggeringElementRef.current = null;
|
|
38
46
|
}
|
|
39
47
|
setOpenState(newOpen);
|
|
40
|
-
|
|
48
|
+
onOpenChange == null ? void 0 : onOpenChange(newOpen, event, reason);
|
|
41
49
|
if (reason === "escape-key" || reason === "outside-press" && onDismissCallback.current) {
|
|
42
50
|
(_a = onDismissCallback == null ? void 0 : onDismissCallback.current) == null ? void 0 : _a.call(onDismissCallback);
|
|
43
51
|
}
|
|
44
52
|
},
|
|
45
|
-
[
|
|
53
|
+
[onOpenChange, readOnly]
|
|
46
54
|
);
|
|
55
|
+
const openState = open && !readOnly;
|
|
47
56
|
const floatingUIResult = useFloatingUI({
|
|
48
|
-
open,
|
|
49
|
-
onOpenChange:
|
|
57
|
+
open: openState,
|
|
58
|
+
onOpenChange: handleOpenChange,
|
|
50
59
|
placement: "bottom-start",
|
|
51
60
|
middleware: [flip({ fallbackStrategy: "initialPlacement" })]
|
|
52
61
|
});
|
|
53
62
|
const {
|
|
54
|
-
getFloatingProps:
|
|
55
|
-
getReferenceProps:
|
|
56
|
-
} = useInteractions(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
getFloatingProps: getFloatingPropsCallback,
|
|
64
|
+
getReferenceProps: getReferencePropsCallback
|
|
65
|
+
} = useInteractions(
|
|
66
|
+
interactions ? interactions(floatingUIResult.context) : [
|
|
67
|
+
useDismiss(floatingUIResult.context),
|
|
68
|
+
useKeyboard(floatingUIResult.context, {
|
|
69
|
+
enabled: !readOnly
|
|
70
|
+
}),
|
|
71
|
+
useClick(floatingUIResult.context, {
|
|
72
|
+
enabled: !!openOnClick && !readOnly,
|
|
73
|
+
toggle: false,
|
|
74
|
+
keyboardHandlers: false
|
|
75
|
+
})
|
|
76
|
+
]
|
|
64
77
|
);
|
|
65
78
|
const getFloatingProps = useCallback(
|
|
66
79
|
(userProps) => {
|
|
@@ -72,17 +85,26 @@ const DatePickerOverlayProvider = ({ open: openProp, defaultOpen, onOpen, childr
|
|
|
72
85
|
position: strategy,
|
|
73
86
|
width: (_a = elements.floating) == null ? void 0 : _a.offsetWidth,
|
|
74
87
|
height: (_b = elements.floating) == null ? void 0 : _b.offsetHeight,
|
|
75
|
-
...getFloatingPropsCallback(userProps)
|
|
88
|
+
...getFloatingPropsCallback(userProps),
|
|
89
|
+
focusManagerProps: {
|
|
90
|
+
disabled: disableFocus,
|
|
91
|
+
returnFocus: false,
|
|
92
|
+
context: floatingUIResult.context,
|
|
93
|
+
initialFocus: 4
|
|
94
|
+
}
|
|
76
95
|
};
|
|
77
96
|
},
|
|
78
|
-
[getFloatingPropsCallback, floatingUIResult]
|
|
97
|
+
[getFloatingPropsCallback, floatingUIResult, disableFocus]
|
|
98
|
+
);
|
|
99
|
+
const setOnDismiss = useCallback(
|
|
100
|
+
(dismissCallback) => {
|
|
101
|
+
onDismissCallback.current = dismissCallback;
|
|
102
|
+
},
|
|
103
|
+
[]
|
|
79
104
|
);
|
|
80
|
-
const setOnDismiss = useCallback((dismissCallback) => {
|
|
81
|
-
onDismissCallback.current = dismissCallback;
|
|
82
|
-
}, []);
|
|
83
105
|
const state = useMemo(
|
|
84
106
|
() => ({
|
|
85
|
-
open,
|
|
107
|
+
open: openState,
|
|
86
108
|
floatingUIResult
|
|
87
109
|
}),
|
|
88
110
|
[open, floatingUIResult]
|
|
@@ -90,11 +112,11 @@ const DatePickerOverlayProvider = ({ open: openProp, defaultOpen, onOpen, childr
|
|
|
90
112
|
const helpers = useMemo(
|
|
91
113
|
() => ({
|
|
92
114
|
getFloatingProps,
|
|
93
|
-
getReferenceProps,
|
|
94
|
-
setOpen,
|
|
115
|
+
getReferenceProps: getReferencePropsCallback,
|
|
116
|
+
setOpen: handleOpenChange,
|
|
95
117
|
setOnDismiss
|
|
96
118
|
}),
|
|
97
|
-
[getFloatingProps,
|
|
119
|
+
[getFloatingProps, getReferencePropsCallback, handleOpenChange]
|
|
98
120
|
);
|
|
99
121
|
const contextValue = useMemo(() => ({ state, helpers }), [state, helpers]);
|
|
100
122
|
return /* @__PURE__ */ jsx(DatePickerOverlayContext.Provider, { value: contextValue, children });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePickerOverlayProvider.js","sources":["../src/date-picker/DatePickerOverlayProvider.tsx"],"sourcesContent":["import {\n type OpenChangeReason,\n flip,\n useDismiss,\n useInteractions,\n} from \"@floating-ui/react\";\nimport { createContext, useControlled, useFloatingUI } from \"@salt-ds/core\";\nimport {\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\n\n/**\n * Interface representing the state for a DatePicker overlay.\n */\ninterface DatePickerOverlayState {\n /**\n * If `true`, the overlay is open.\n */\n open: boolean;\n /**\n * The result of the floating UI calculations.\n */\n floatingUIResult: ReturnType<typeof useFloatingUI>;\n}\n\n/**\n * Interface representing the helper functions for a DatePicker overlay.\n */\ninterface DatePickerOverlayHelpers {\n /**\n * Function to get the props for the floating element.\n */\n getFloatingProps: ReturnType<typeof useInteractions>[\"getFloatingProps\"];\n /**\n * Function to get the props for the reference element.\n */\n getReferenceProps: ReturnType<typeof useInteractions>[\"getReferenceProps\"];\n /**\n * Sets the open state of the overlay.\n * @param newOpen - The new value for the open state.\n */\n setOpen: (newOpen: boolean) => void;\n /**~\n * Register a callback for when onDismiss is called\n * @param onDismissCallback\n */\n setOnDismiss: (onDismissCallback: () => void) => void;\n}\n\n/**\n * Interface representing the context type for a DatePicker overlay.\n */\ninterface DatePickerOverlayContextType {\n /**\n * The state of the DatePicker overlay.\n */\n state: DatePickerOverlayState;\n /**\n * The helper functions for the DatePicker overlay.\n */\n helpers: DatePickerOverlayHelpers;\n}\n\n/**\n * Context for the DatePicker overlay.\n */\nconst DatePickerOverlayContext = createContext<\n DatePickerOverlayContextType | undefined\n>(\"DatePickerOverlayContext\", undefined);\n\n/**\n * Props for the DatePickerOverlayProvider component.\n */\ninterface DatePickerOverlayProviderProps {\n /**\n * If `true`, the overlay is open.\n */\n open?: boolean;\n /**\n * Handler for when open state changes\n * @param newOpen - true when opened\n */\n onOpen?: (newOpen: boolean) => void;\n /**\n * The default open state of the overlay.\n */\n defaultOpen?: boolean;\n /**\n * The content to be rendered inside the overlay provider.\n */\n children: ReactNode;\n /**\n * When true, shouldn't open the overlay.\n */\n readOnly?: boolean;\n}\n\nexport const DatePickerOverlayProvider: React.FC<\n DatePickerOverlayProviderProps\n> = ({ open: openProp, defaultOpen, onOpen, children, readOnly }) => {\n const [open, setOpenState] = useControlled({\n controlled: openProp,\n default: Boolean(defaultOpen),\n name: \"DatePicker\",\n state: \"openDatePickerOverlay\",\n });\n const triggeringElement = useRef<HTMLElement | null>(null);\n const onDismissCallback = useRef<() => void>();\n\n useEffect(() => {\n if (!open) {\n const trigger = triggeringElement.current as HTMLElement;\n if (trigger) {\n trigger.focus();\n }\n if (trigger instanceof HTMLInputElement) {\n setTimeout(() => {\n trigger.setSelectionRange(0, trigger.value.length);\n }, 0);\n }\n triggeringElement.current = null;\n }\n }, [open]);\n\n const setOpen = useCallback(\n (\n newOpen: boolean,\n _event?: Event | undefined,\n reason?: OpenChangeReason | undefined,\n ) => {\n if (newOpen) {\n if (readOnly) {\n // When not open overlay when readOnly\n return;\n }\n triggeringElement.current = document.activeElement as HTMLElement;\n }\n setOpenState(newOpen);\n onOpen?.(newOpen);\n if (\n reason === \"escape-key\" ||\n (reason === \"outside-press\" && onDismissCallback.current)\n ) {\n onDismissCallback?.current?.();\n }\n },\n [onOpen, readOnly],\n );\n\n const floatingUIResult = useFloatingUI({\n open,\n onOpenChange: setOpen,\n placement: \"bottom-start\",\n middleware: [flip({ fallbackStrategy: \"initialPlacement\" })],\n });\n\n const {\n getFloatingProps: _getFloatingPropsCallback,\n getReferenceProps: _getReferenceProps,\n } = useInteractions([useDismiss(floatingUIResult.context)]);\n const getFloatingPropsCallback = useMemo(\n () => _getFloatingPropsCallback,\n [_getFloatingPropsCallback],\n );\n const getReferenceProps = useMemo(\n () => _getReferenceProps,\n [_getReferenceProps],\n );\n\n const getFloatingProps = useCallback(\n (userProps: React.HTMLProps<HTMLElement> | undefined) => {\n const { x, y, strategy, elements } = floatingUIResult;\n return {\n top: y ?? 0,\n left: x ?? 0,\n position: strategy,\n width: elements.floating?.offsetWidth,\n height: elements.floating?.offsetHeight,\n ...getFloatingPropsCallback(userProps),\n };\n },\n [getFloatingPropsCallback, floatingUIResult],\n );\n const setOnDismiss = useCallback((dismissCallback: () => void) => {\n onDismissCallback.current = dismissCallback;\n }, []);\n\n const state: DatePickerOverlayState = useMemo(\n () => ({\n open,\n floatingUIResult,\n }),\n [open, floatingUIResult],\n );\n\n const helpers: DatePickerOverlayHelpers = useMemo(\n () => ({\n getFloatingProps,\n getReferenceProps,\n setOpen,\n setOnDismiss,\n }),\n [getFloatingProps, getReferenceProps, setOpen],\n );\n const contextValue = useMemo(() => ({ state, helpers }), [state, helpers]);\n\n return (\n <DatePickerOverlayContext.Provider value={contextValue}>\n {children}\n </DatePickerOverlayContext.Provider>\n );\n};\n\nexport const useDatePickerOverlay = (): DatePickerOverlayContextType => {\n const context = useContext(DatePickerOverlayContext);\n if (!context) {\n throw new Error(\n \"useDatePickerOverlay must be used within a DatePickerOverlayProvider\",\n );\n }\n return context;\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DatePickerOverlayProvider.js","sources":["../src/date-picker/DatePickerOverlayProvider.tsx"],"sourcesContent":["import {\n type ElementProps,\n type FloatingContext,\n type OpenChangeReason as FloatingUIOpenChangeReason,\n flip,\n useClick,\n useDismiss,\n useInteractions,\n} from \"@floating-ui/react\";\nimport { createContext, useControlled, useFloatingUI } from \"@salt-ds/core\";\nimport {\n type ReactNode,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useKeyboard } from \"./useKeyboard\";\n\n/** Reason for overlay state change, can be a custom reason */\nexport type DatePickerOpenChangeReason =\n | FloatingUIOpenChangeReason\n | \"apply\"\n | \"cancel\"\n | string;\n/**\n * Interface representing the state for a DatePicker overlay.\n */\ninterface DatePickerOverlayState {\n /**\n * If `true`, the overlay is open.\n */\n open: boolean;\n /**\n * The result of the floating UI calculations.\n */\n floatingUIResult: ReturnType<typeof useFloatingUI>;\n}\n\n/**\n * Interface representing the helper functions for a DatePicker overlay.\n */\ninterface DatePickerOverlayHelpers {\n /**\n * Function to get the props for the floating element.\n */\n getFloatingProps: ReturnType<typeof useInteractions>[\"getFloatingProps\"];\n /**\n * Function to get the props for the reference element.\n */\n getReferenceProps: ReturnType<typeof useInteractions>[\"getReferenceProps\"];\n /**\n * Sets the open state of the overlay.\n * @param newOpen - The new value for the open state.\n * @param event - event that triggered the state change\n * @param reason - reason for the the state change\n */\n setOpen: (\n newOpen: boolean,\n event?: Event,\n reason?: DatePickerOpenChangeReason,\n ) => void;\n /**~\n * Register a callback for when onDismiss is called\n * @param onDismissCallback\n */\n setOnDismiss: (onDismissCallback: (event?: Event) => void) => void;\n}\n\n/**\n * Interface representing the context type for a DatePicker overlay.\n */\ninterface DatePickerOverlayContextType {\n /**\n * The state of the DatePicker overlay.\n */\n state: DatePickerOverlayState;\n /**\n * The helper functions for the DatePicker overlay.\n */\n helpers: DatePickerOverlayHelpers;\n}\n\n/**\n * Context for the DatePicker overlay.\n */\nconst DatePickerOverlayContext = createContext<\n DatePickerOverlayContextType | undefined\n>(\"DatePickerOverlayContext\", undefined);\n\n/**\n * Props for the DatePickerOverlayProvider component.\n */\ninterface DatePickerOverlayProviderProps {\n /**\n * If `true`, the overlay is open.\n */\n open?: boolean;\n /**\n * When `open` is uncontrolled, set this to `true` to open on click\n */\n openOnClick?: boolean;\n /**\n * Handler for when open state changes\n * @param newOpen - true when opened\n * @param event - event that triggered the state change\n * @param reason - reason for the the state change\n */\n onOpenChange?: (\n newOpen: boolean,\n event?: Event,\n reason?: DatePickerOpenChangeReason,\n ) => void;\n /**\n * The default open state of the overlay.\n */\n defaultOpen?: boolean;\n /**\n * The content to be rendered inside the overlay provider.\n */\n children: ReactNode;\n /**\n * A factory method to create a set of interaction, if provided overrides the default interactions\n */\n interactions?: (context: FloatingContext) => Array<ElementProps>;\n /**\n * When true, shouldn't open the overlay.\n */\n readOnly?: boolean;\n}\n\nexport const DatePickerOverlayProvider: React.FC<\n DatePickerOverlayProviderProps\n> = ({\n open: openProp,\n openOnClick,\n defaultOpen,\n onOpenChange,\n children,\n interactions,\n readOnly,\n}) => {\n const [open, setOpenState, isOpenControlled] = useControlled({\n controlled: openProp,\n default: Boolean(defaultOpen),\n name: \"DatePicker\",\n state: \"openDatePickerOverlay\",\n });\n const [disableFocus, setDisableFocus] = useState<boolean>(true);\n const triggeringElementRef = useRef<HTMLElement | null>(null);\n const onDismissCallback = useRef<(event?: Event) => void>();\n const handleOpenChange = useCallback(\n (newOpen: boolean, event?: Event, reason?: DatePickerOpenChangeReason) => {\n if (newOpen) {\n if (readOnly) {\n return;\n }\n triggeringElementRef.current = document.activeElement as HTMLElement;\n setDisableFocus(reason === \"click\"); // prevent the overlay taking focus on click\n } else if (!isOpenControlled) {\n const trigger = triggeringElementRef.current as HTMLElement;\n if (trigger) {\n trigger.focus();\n }\n if (trigger instanceof HTMLInputElement) {\n setTimeout(() => {\n trigger.setSelectionRange(0, trigger.value.length);\n }, 1);\n }\n triggeringElementRef.current = null;\n }\n setOpenState(newOpen);\n onOpenChange?.(newOpen, event, reason);\n\n if (\n reason === \"escape-key\" ||\n (reason === \"outside-press\" && onDismissCallback.current)\n ) {\n onDismissCallback?.current?.();\n }\n },\n [onOpenChange, readOnly],\n );\n\n const openState = open && !readOnly;\n const floatingUIResult = useFloatingUI({\n open: openState,\n onOpenChange: handleOpenChange,\n placement: \"bottom-start\",\n middleware: [flip({ fallbackStrategy: \"initialPlacement\" })],\n });\n\n const {\n getFloatingProps: getFloatingPropsCallback,\n getReferenceProps: getReferencePropsCallback,\n } = useInteractions(\n interactions\n ? interactions(floatingUIResult.context)\n : [\n useDismiss(floatingUIResult.context),\n useKeyboard(floatingUIResult.context, {\n enabled: !readOnly,\n }),\n useClick(floatingUIResult.context, {\n enabled: !!openOnClick && !readOnly,\n toggle: false,\n keyboardHandlers: false,\n }),\n ],\n );\n\n const getFloatingProps = useCallback(\n (userProps: React.HTMLProps<HTMLElement> | undefined) => {\n const { x, y, strategy, elements } = floatingUIResult;\n return {\n top: y ?? 0,\n left: x ?? 0,\n position: strategy,\n width: elements.floating?.offsetWidth,\n height: elements.floating?.offsetHeight,\n ...getFloatingPropsCallback(userProps),\n focusManagerProps: {\n disabled: disableFocus,\n returnFocus: false,\n context: floatingUIResult.context,\n initialFocus: 4,\n },\n };\n },\n [getFloatingPropsCallback, floatingUIResult, disableFocus],\n );\n const setOnDismiss = useCallback(\n (dismissCallback: (event?: Event) => void) => {\n onDismissCallback.current = dismissCallback;\n },\n [],\n );\n\n const state: DatePickerOverlayState = useMemo(\n () => ({\n open: openState,\n floatingUIResult,\n }),\n [open, floatingUIResult],\n );\n\n const helpers: DatePickerOverlayHelpers = useMemo(\n () => ({\n getFloatingProps,\n getReferenceProps: getReferencePropsCallback,\n setOpen: handleOpenChange,\n setOnDismiss,\n }),\n [getFloatingProps, getReferencePropsCallback, handleOpenChange],\n );\n const contextValue = useMemo(() => ({ state, helpers }), [state, helpers]);\n\n return (\n <DatePickerOverlayContext.Provider value={contextValue}>\n {children}\n </DatePickerOverlayContext.Provider>\n );\n};\n\nexport const useDatePickerOverlay = (): DatePickerOverlayContextType => {\n const context = useContext(DatePickerOverlayContext);\n if (!context) {\n throw new Error(\n \"useDatePickerOverlay must be used within a DatePickerOverlayProvider\",\n );\n }\n return context;\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -58,9 +58,8 @@ const DatePickerRangeInput = forwardRef(function DatePickerRangeInput2(props, re
|
|
|
58
58
|
const { dateAdapter } = useLocalization();
|
|
59
59
|
const {
|
|
60
60
|
className,
|
|
61
|
-
endInputProps
|
|
62
|
-
startInputProps
|
|
63
|
-
onKeyDown,
|
|
61
|
+
endInputProps,
|
|
62
|
+
startInputProps,
|
|
64
63
|
defaultValue,
|
|
65
64
|
format,
|
|
66
65
|
value: valueProp,
|
|
@@ -85,9 +84,13 @@ const DatePickerRangeInput = forwardRef(function DatePickerRangeInput2(props, re
|
|
|
85
84
|
name: "DatePickerRangeInput",
|
|
86
85
|
state: "dateValue"
|
|
87
86
|
});
|
|
88
|
-
const handleCalendarButton = useCallback(
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
const handleCalendarButton = useCallback(
|
|
88
|
+
(event) => {
|
|
89
|
+
setOpen(!open, event.nativeEvent, "click");
|
|
90
|
+
event.stopPropagation();
|
|
91
|
+
},
|
|
92
|
+
[open, setOpen]
|
|
93
|
+
);
|
|
91
94
|
const handleDateChange = useCallback(
|
|
92
95
|
(event, date, details) => {
|
|
93
96
|
const validatedDetails = validate ? validate(date, details) : defaultRangeValidator(dateAdapter, date, details, minDate, maxDate);
|
|
@@ -112,26 +115,6 @@ const DatePickerRangeInput = forwardRef(function DatePickerRangeInput2(props, re
|
|
|
112
115
|
setValue(previousValue.current);
|
|
113
116
|
}
|
|
114
117
|
}, [cancelled]);
|
|
115
|
-
const startInputProps = {
|
|
116
|
-
onKeyDown: (event) => {
|
|
117
|
-
var _a;
|
|
118
|
-
if (event.key === "ArrowDown") {
|
|
119
|
-
setOpen(true);
|
|
120
|
-
}
|
|
121
|
-
(_a = startInputPropsProp == null ? void 0 : startInputPropsProp.onKeyDown) == null ? void 0 : _a.call(startInputPropsProp, event);
|
|
122
|
-
},
|
|
123
|
-
...startInputPropsProp
|
|
124
|
-
};
|
|
125
|
-
const endInputProps = {
|
|
126
|
-
onKeyDown: (event) => {
|
|
127
|
-
var _a;
|
|
128
|
-
if (event.key === "ArrowDown") {
|
|
129
|
-
setOpen(true);
|
|
130
|
-
}
|
|
131
|
-
(_a = endInputPropsProp == null ? void 0 : endInputPropsProp.onKeyDown) == null ? void 0 : _a.call(endInputPropsProp, event);
|
|
132
|
-
},
|
|
133
|
-
...endInputPropsProp
|
|
134
|
-
};
|
|
135
118
|
return /* @__PURE__ */ jsx(
|
|
136
119
|
DateInputRange,
|
|
137
120
|
{
|
|
@@ -144,6 +127,7 @@ const DatePickerRangeInput = forwardRef(function DatePickerRangeInput2(props, re
|
|
|
144
127
|
startInputProps,
|
|
145
128
|
endInputProps,
|
|
146
129
|
readOnly,
|
|
130
|
+
disabled,
|
|
147
131
|
ref,
|
|
148
132
|
onDateChange: handleDateChange,
|
|
149
133
|
onDateValueChange: handleDateValueChange,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePickerRangeInput.js","sources":["../src/date-picker/DatePickerRangeInput.tsx"],"sourcesContent":["import { Button, makePrefixer, useControlled, useIcon } from \"@salt-ds/core\";\nimport {\n DateDetailError,\n type DateFrameworkType,\n type SaltDateAdapter,\n} from \"@salt-ds/date-adapters\";\nimport { clsx } from \"clsx\";\nimport {\n type KeyboardEvent,\n type KeyboardEventHandler,\n type SyntheticEvent,\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport type { DateRangeSelection, SingleDateSelection } from \"../calendar\";\nimport {\n DateInputRange,\n type DateInputRangeDetails,\n type DateInputRangeProps,\n type DateInputRangeValue,\n} from \"../date-input\";\nimport { useLocalization } from \"../localization-provider\";\nimport { useDatePickerContext } from \"./DatePickerContext\";\nimport { useDatePickerOverlay } from \"./DatePickerOverlayProvider\";\n\nconst withBaseName = makePrefixer(\"saltDatePickerRangeInput\");\n\n/**\n * Props for the DatePickerRangeInput component.\n */\nexport interface DatePickerRangeInputProps<TDate extends DateFrameworkType>\n extends DateInputRangeProps<TDate> {\n /**\n * Function to validate the entered date\n * @param date - The selected date\n * @param details - The details of date selection, either a valid date or error\n * @returns updated DateInputRangeDetails details\n */\n validate?: (\n date: DateRangeSelection<TDate> | null,\n details: DateInputRangeDetails,\n ) => DateInputRangeDetails;\n}\n\nexport function defaultRangeValidator<TDate extends DateFrameworkType>(\n dateAdapter: SaltDateAdapter<TDate>,\n date: DateRangeSelection<TDate> | null,\n details: DateInputRangeDetails,\n minDate: TDate | undefined,\n maxDate: TDate | undefined,\n): DateInputRangeDetails {\n const { startDate, endDate } = date || {};\n\n if (!startDate) {\n details.startDate = details.startDate || {};\n details.startDate.errors = details.startDate.errors || [];\n details.startDate.errors.push({\n type: DateDetailError.UNSET,\n message: \"no start date defined\",\n });\n }\n if (!endDate) {\n details.endDate = details.endDate || {};\n details.endDate.errors = details.endDate.errors || [];\n details.endDate.errors.push({\n type: DateDetailError.UNSET,\n message: \"no end date defined\",\n });\n }\n\n // If startDate is after endDate\n if (\n dateAdapter.isValid(startDate) &&\n dateAdapter.isValid(endDate) &&\n dateAdapter.compare(startDate, endDate) > 0\n ) {\n details.startDate = details.startDate || {};\n details.startDate.errors = details.startDate.errors || [];\n details.startDate.errors.push({\n type: \"greater-than-end-date\",\n message: \"start date after end date\",\n });\n }\n // If startDate is before minDate\n if (\n minDate &&\n dateAdapter.isValid(startDate) &&\n dateAdapter.compare(startDate, minDate) < 0\n ) {\n details.startDate = details.startDate || {};\n details.startDate.errors = details.startDate.errors || [];\n details.startDate.errors.push({\n type: \"min-date\",\n message: \"is before min date\",\n });\n }\n // If endDate is after maxDate\n if (\n maxDate &&\n dateAdapter.isValid(endDate) &&\n dateAdapter.compare(endDate, maxDate) > 0\n ) {\n details.endDate = details.endDate || {};\n details.endDate.errors = details.endDate.errors || [];\n details.endDate.errors.push({\n type: \"max-date\",\n message: \"is after max date\",\n });\n }\n return details;\n}\n\nexport const DatePickerRangeInput = forwardRef(function DatePickerRangeInput<\n TDate extends DateFrameworkType,\n>(\n props: DatePickerRangeInputProps<SingleDateSelection<TDate>>,\n ref: React.Ref<HTMLDivElement>,\n) {\n const { dateAdapter } = useLocalization<TDate>();\n const {\n className,\n endInputProps: endInputPropsProp,\n startInputProps: startInputPropsProp,\n onKeyDown,\n defaultValue,\n format,\n value: valueProp,\n validate,\n onChange,\n onDateValueChange,\n ...rest\n } = props;\n\n const { CalendarIcon } = useIcon();\n\n const {\n state: { selectedDate, disabled, readOnly, cancelled, minDate, maxDate },\n helpers: { select },\n } = useDatePickerContext<TDate>({ selectionVariant: \"range\" });\n const {\n state: { open },\n helpers: { setOpen },\n } = useDatePickerOverlay();\n\n const previousValue = useRef<typeof valueProp>();\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default: defaultValue,\n name: \"DatePickerRangeInput\",\n state: \"dateValue\",\n });\n\n const handleCalendarButton = useCallback(() => {\n setOpen(!open);\n }, [open, setOpen]);\n\n const handleDateChange = useCallback(\n (\n event: SyntheticEvent,\n date: DateRangeSelection<TDate> | null,\n details: DateInputRangeDetails,\n ) => {\n const validatedDetails = validate\n ? validate(date, details)\n : defaultRangeValidator(dateAdapter, date, details, minDate, maxDate);\n select(event, date, validatedDetails);\n },\n [select, minDate, maxDate],\n );\n\n const handleDateValueChange = useCallback(\n (event: SyntheticEvent | null, newDateValue: DateInputRangeValue) => {\n setValue(newDateValue);\n onDateValueChange?.(event, newDateValue);\n },\n [onDateValueChange],\n );\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: should run when open changes and not selected date or value\n useEffect(() => {\n if (open) {\n previousValue.current = value;\n }\n }, [open]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: avoid excessive re-rendering\n useEffect(() => {\n if (cancelled) {\n setValue(previousValue.current);\n }\n }, [cancelled]);\n\n const startInputProps: {\n onKeyDown: KeyboardEventHandler<HTMLInputElement>;\n } = {\n onKeyDown: (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.key === \"ArrowDown\") {\n setOpen(true);\n }\n startInputPropsProp?.onKeyDown?.(event);\n },\n ...startInputPropsProp,\n };\n const endInputProps: {\n onKeyDown: KeyboardEventHandler<HTMLInputElement>;\n } = {\n onKeyDown: (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.key === \"ArrowDown\") {\n setOpen(true);\n }\n endInputPropsProp?.onKeyDown?.(event);\n },\n ...endInputPropsProp,\n };\n\n return (\n <DateInputRange\n value={\n value ?? {\n startDate: dateAdapter.format(value, format),\n endDate: dateAdapter.format(value, format),\n }\n }\n className={clsx(withBaseName(), className)}\n date={selectedDate ?? null}\n startInputProps={startInputProps}\n endInputProps={endInputProps}\n readOnly={readOnly}\n ref={ref}\n onDateChange={handleDateChange}\n onDateValueChange={handleDateValueChange}\n onChange={onChange}\n endAdornment={\n !readOnly && (\n <Button\n appearance=\"transparent\"\n sentiment=\"neutral\"\n onClick={handleCalendarButton}\n disabled={disabled}\n aria-label=\"Open Calendar\"\n >\n <CalendarIcon />\n </Button>\n )\n }\n format={format}\n {...rest}\n />\n );\n});\n"],"names":["DatePickerRangeInput"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DatePickerRangeInput.js","sources":["../src/date-picker/DatePickerRangeInput.tsx"],"sourcesContent":["import { Button, makePrefixer, useControlled, useIcon } from \"@salt-ds/core\";\nimport {\n DateDetailError,\n type DateFrameworkType,\n type SaltDateAdapter,\n} from \"@salt-ds/date-adapters\";\nimport { clsx } from \"clsx\";\nimport {\n type MouseEventHandler,\n type SyntheticEvent,\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport type { DateRangeSelection, SingleDateSelection } from \"../calendar\";\nimport {\n DateInputRange,\n type DateInputRangeDetails,\n type DateInputRangeProps,\n type DateInputRangeValue,\n} from \"../date-input\";\nimport { useLocalization } from \"../localization-provider\";\nimport { useDatePickerContext } from \"./DatePickerContext\";\nimport { useDatePickerOverlay } from \"./DatePickerOverlayProvider\";\n\nconst withBaseName = makePrefixer(\"saltDatePickerRangeInput\");\n\n/**\n * Props for the DatePickerRangeInput component.\n */\nexport interface DatePickerRangeInputProps<TDate extends DateFrameworkType>\n extends DateInputRangeProps<TDate> {\n /**\n * Function to validate the entered date\n * @param date - The selected date\n * @param details - The details of date selection, either a valid date or error\n * @returns updated DateInputRangeDetails details\n */\n validate?: (\n date: DateRangeSelection<TDate> | null,\n details: DateInputRangeDetails,\n ) => DateInputRangeDetails;\n}\n\nexport function defaultRangeValidator<TDate extends DateFrameworkType>(\n dateAdapter: SaltDateAdapter<TDate>,\n date: DateRangeSelection<TDate> | null,\n details: DateInputRangeDetails,\n minDate?: TDate,\n maxDate?: TDate,\n): DateInputRangeDetails {\n const { startDate, endDate } = date || {};\n\n if (!startDate) {\n details.startDate = details.startDate || {};\n details.startDate.errors = details.startDate.errors || [];\n details.startDate.errors.push({\n type: DateDetailError.UNSET,\n message: \"no start date defined\",\n });\n }\n if (!endDate) {\n details.endDate = details.endDate || {};\n details.endDate.errors = details.endDate.errors || [];\n details.endDate.errors.push({\n type: DateDetailError.UNSET,\n message: \"no end date defined\",\n });\n }\n\n // If startDate is after endDate\n if (\n dateAdapter.isValid(startDate) &&\n dateAdapter.isValid(endDate) &&\n dateAdapter.compare(startDate, endDate) > 0\n ) {\n details.startDate = details.startDate || {};\n details.startDate.errors = details.startDate.errors || [];\n details.startDate.errors.push({\n type: \"greater-than-end-date\",\n message: \"start date after end date\",\n });\n }\n // If startDate is before minDate\n if (\n minDate &&\n dateAdapter.isValid(startDate) &&\n dateAdapter.compare(startDate, minDate) < 0\n ) {\n details.startDate = details.startDate || {};\n details.startDate.errors = details.startDate.errors || [];\n details.startDate.errors.push({\n type: \"min-date\",\n message: \"is before min date\",\n });\n }\n // If endDate is after maxDate\n if (\n maxDate &&\n dateAdapter.isValid(endDate) &&\n dateAdapter.compare(endDate, maxDate) > 0\n ) {\n details.endDate = details.endDate || {};\n details.endDate.errors = details.endDate.errors || [];\n details.endDate.errors.push({\n type: \"max-date\",\n message: \"is after max date\",\n });\n }\n return details;\n}\n\nexport const DatePickerRangeInput = forwardRef(function DatePickerRangeInput<\n TDate extends DateFrameworkType,\n>(\n props: DatePickerRangeInputProps<SingleDateSelection<TDate>>,\n ref: React.Ref<HTMLDivElement>,\n) {\n const { dateAdapter } = useLocalization<TDate>();\n const {\n className,\n endInputProps,\n startInputProps,\n defaultValue,\n format,\n value: valueProp,\n validate,\n onChange,\n onDateValueChange,\n ...rest\n } = props;\n\n const { CalendarIcon } = useIcon();\n\n const {\n state: { selectedDate, disabled, readOnly, cancelled, minDate, maxDate },\n helpers: { select },\n } = useDatePickerContext<TDate>({ selectionVariant: \"range\" });\n const {\n state: { open },\n helpers: { setOpen },\n } = useDatePickerOverlay();\n\n const previousValue = useRef<typeof valueProp>();\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default: defaultValue,\n name: \"DatePickerRangeInput\",\n state: \"dateValue\",\n });\n\n const handleCalendarButton: MouseEventHandler<HTMLButtonElement> =\n useCallback(\n (event) => {\n setOpen(!open, event.nativeEvent, \"click\");\n event.stopPropagation();\n },\n [open, setOpen],\n );\n\n const handleDateChange = useCallback(\n (\n event: SyntheticEvent,\n date: DateRangeSelection<TDate> | null,\n details: DateInputRangeDetails,\n ) => {\n const validatedDetails = validate\n ? validate(date, details)\n : defaultRangeValidator(dateAdapter, date, details, minDate, maxDate);\n select(event, date, validatedDetails);\n },\n [select, minDate, maxDate],\n );\n\n const handleDateValueChange = useCallback(\n (event: SyntheticEvent | null, newDateValue: DateInputRangeValue) => {\n setValue(newDateValue);\n onDateValueChange?.(event, newDateValue);\n },\n [onDateValueChange],\n );\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: should run when open changes and not selected date or value\n useEffect(() => {\n if (open) {\n previousValue.current = value;\n }\n }, [open]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: avoid excessive re-rendering\n useEffect(() => {\n if (cancelled) {\n setValue(previousValue.current);\n }\n }, [cancelled]);\n\n return (\n <DateInputRange\n value={\n value ?? {\n startDate: dateAdapter.format(value, format),\n endDate: dateAdapter.format(value, format),\n }\n }\n className={clsx(withBaseName(), className)}\n date={selectedDate ?? null}\n startInputProps={startInputProps}\n endInputProps={endInputProps}\n readOnly={readOnly}\n disabled={disabled}\n ref={ref}\n onDateChange={handleDateChange}\n onDateValueChange={handleDateValueChange}\n onChange={onChange}\n endAdornment={\n !readOnly && (\n <Button\n appearance=\"transparent\"\n sentiment=\"neutral\"\n onClick={handleCalendarButton}\n disabled={disabled}\n aria-label=\"Open Calendar\"\n >\n <CalendarIcon />\n </Button>\n )\n }\n format={format}\n {...rest}\n />\n );\n});\n"],"names":["DatePickerRangeInput"],"mappings":"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"}
|
|
@@ -47,7 +47,6 @@ const DatePickerSingleInput = forwardRef(
|
|
|
47
47
|
validate,
|
|
48
48
|
defaultValue,
|
|
49
49
|
onDateValueChange,
|
|
50
|
-
onKeyDown,
|
|
51
50
|
...rest
|
|
52
51
|
} = props;
|
|
53
52
|
const {
|
|
@@ -65,9 +64,13 @@ const DatePickerSingleInput = forwardRef(
|
|
|
65
64
|
name: "DatePickerSingleInput",
|
|
66
65
|
state: "value"
|
|
67
66
|
});
|
|
68
|
-
const handleCalendarButton = useCallback(
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
const handleCalendarButton = useCallback(
|
|
68
|
+
(event) => {
|
|
69
|
+
setOpen(!open, event.nativeEvent, "click");
|
|
70
|
+
event.stopPropagation();
|
|
71
|
+
},
|
|
72
|
+
[open, setOpen]
|
|
73
|
+
);
|
|
71
74
|
const handleDateChange = useCallback(
|
|
72
75
|
(event, date, details) => {
|
|
73
76
|
const validatedDetails = validate ? validate(date, details) : defaultSingleValidation(
|
|
@@ -88,15 +91,6 @@ const DatePickerSingleInput = forwardRef(
|
|
|
88
91
|
},
|
|
89
92
|
[onDateValueChange]
|
|
90
93
|
);
|
|
91
|
-
const handleOnKeyDown = useCallback(
|
|
92
|
-
(event) => {
|
|
93
|
-
if (event.key === "ArrowDown") {
|
|
94
|
-
setOpen(true);
|
|
95
|
-
onKeyDown == null ? void 0 : onKeyDown(event);
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
[onKeyDown]
|
|
99
|
-
);
|
|
100
94
|
useEffect(() => {
|
|
101
95
|
if (open) {
|
|
102
96
|
previousValue.current = value;
|
|
@@ -114,6 +108,7 @@ const DatePickerSingleInput = forwardRef(
|
|
|
114
108
|
className: clsx(withBaseName(), className),
|
|
115
109
|
date: selectedDate ?? null,
|
|
116
110
|
readOnly,
|
|
111
|
+
disabled,
|
|
117
112
|
ref,
|
|
118
113
|
onDateChange: handleDateChange,
|
|
119
114
|
onDateValueChange: handleDateValueChange,
|
|
@@ -128,7 +123,6 @@ const DatePickerSingleInput = forwardRef(
|
|
|
128
123
|
children: /* @__PURE__ */ jsx(CalendarIcon, {})
|
|
129
124
|
}
|
|
130
125
|
),
|
|
131
|
-
onKeyDown: handleOnKeyDown,
|
|
132
126
|
...rest
|
|
133
127
|
}
|
|
134
128
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePickerSingleInput.js","sources":["../src/date-picker/DatePickerSingleInput.tsx"],"sourcesContent":["import { Button, makePrefixer, useControlled } from \"@salt-ds/core\";\nimport {\n DateDetailError,\n type DateFrameworkType,\n type SaltDateAdapter,\n} from \"@salt-ds/date-adapters\";\nimport { CalendarIcon } from \"@salt-ds/icons\";\nimport { clsx } from \"clsx\";\nimport {\n type
|
|
1
|
+
{"version":3,"file":"DatePickerSingleInput.js","sources":["../src/date-picker/DatePickerSingleInput.tsx"],"sourcesContent":["import { Button, makePrefixer, useControlled } from \"@salt-ds/core\";\nimport {\n DateDetailError,\n type DateFrameworkType,\n type SaltDateAdapter,\n} from \"@salt-ds/date-adapters\";\nimport { CalendarIcon } from \"@salt-ds/icons\";\nimport { clsx } from \"clsx\";\nimport {\n type MouseEventHandler,\n type SyntheticEvent,\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport type { SingleDateSelection } from \"../calendar\";\nimport {\n DateInputSingle,\n type DateInputSingleDetails,\n type DateInputSingleProps,\n} from \"../date-input\";\nimport { useLocalization } from \"../localization-provider\";\nimport { useDatePickerContext } from \"./DatePickerContext\";\nimport { useDatePickerOverlay } from \"./DatePickerOverlayProvider\";\n\nconst withBaseName = makePrefixer(\"saltDatePickerSingleInput\");\n\n/**\n * Props for the DatePickerSingleInput component.\n */\nexport interface DatePickerSingleInputProps<TDate extends DateFrameworkType>\n extends DateInputSingleProps<TDate> {\n /**\n * Function to validate the entered date\n * @param date - The selected date\n * @param details - The details of date selection, either a valid date or error\n * @returns updated DateInputSingleDetails details\n */\n validate?: (\n date: SingleDateSelection<TDate>,\n details: DateInputSingleDetails,\n ) => DateInputSingleDetails;\n}\n\nfunction defaultSingleValidation<TDate extends DateFrameworkType>(\n dateAdapter: SaltDateAdapter<TDate>,\n date: TDate,\n details: DateInputSingleDetails,\n minDate?: TDate,\n maxDate?: TDate,\n): DateInputSingleDetails {\n if (!date) {\n details.errors = details.errors ?? [];\n details.errors?.push({\n type: DateDetailError.UNSET,\n message: \"no date defined\",\n });\n } else {\n if (\n minDate &&\n dateAdapter.isValid(date) &&\n dateAdapter.compare(date, minDate) < 0\n ) {\n details.errors = details.errors ?? [];\n details.errors?.push({\n type: \"min-date\",\n message: \"is before min date\",\n });\n } else if (\n maxDate &&\n dateAdapter.isValid(date) &&\n dateAdapter.compare(date, maxDate) > 0\n ) {\n details.errors = details.errors ?? [];\n details.errors?.push({\n type: \"max-date\",\n message: \"is after max date\",\n });\n }\n }\n return details;\n}\n\nexport const DatePickerSingleInput = forwardRef<\n HTMLDivElement,\n DatePickerSingleInputProps<any>\n>(\n <TDate extends DateFrameworkType>(\n props: DatePickerSingleInputProps<TDate>,\n ref: React.Ref<HTMLDivElement>,\n ) => {\n const { dateAdapter } = useLocalization<TDate>();\n\n const {\n className,\n onFocus,\n onBlur,\n value: valueProp,\n validate,\n defaultValue,\n onDateValueChange,\n ...rest\n } = props;\n\n const {\n state: { selectedDate, disabled, readOnly, cancelled, minDate, maxDate },\n helpers: { select },\n } = useDatePickerContext<TDate>({ selectionVariant: \"single\" });\n const {\n state: { open },\n helpers: { setOpen },\n } = useDatePickerOverlay();\n\n const previousValue = useRef<typeof valueProp>();\n\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default: defaultValue,\n name: \"DatePickerSingleInput\",\n state: \"value\",\n });\n\n const handleCalendarButton: MouseEventHandler<HTMLButtonElement> =\n useCallback(\n (event) => {\n setOpen(!open, event.nativeEvent, \"click\");\n event.stopPropagation();\n },\n [open, setOpen],\n );\n\n const handleDateChange = useCallback(\n (\n event: SyntheticEvent,\n date: SingleDateSelection<TDate>,\n details: DateInputSingleDetails,\n ) => {\n const validatedDetails = validate\n ? validate(date, details)\n : defaultSingleValidation<TDate>(\n dateAdapter,\n date,\n details,\n minDate,\n maxDate,\n );\n select(event, date, validatedDetails);\n },\n [select, validate],\n );\n\n const handleDateValueChange = useCallback(\n (event: SyntheticEvent | null, newDateValue: string) => {\n setValue(newDateValue);\n onDateValueChange?.(event, newDateValue);\n },\n [onDateValueChange],\n );\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: should run when open changes and not selected date or value\n useEffect(() => {\n if (open) {\n previousValue.current = value;\n }\n }, [open]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: avoid excessive re-rendering\n useEffect(() => {\n if (cancelled) {\n setValue(previousValue?.current);\n }\n }, [cancelled]);\n\n return (\n <DateInputSingle\n value={value ?? \"\"}\n className={clsx(withBaseName(), className)}\n date={selectedDate ?? null}\n readOnly={readOnly}\n disabled={disabled}\n ref={ref}\n onDateChange={handleDateChange}\n onDateValueChange={handleDateValueChange}\n endAdornment={\n !readOnly && (\n <Button\n appearance=\"transparent\"\n sentiment=\"neutral\"\n onClick={handleCalendarButton}\n disabled={disabled}\n aria-label=\"Open Calendar\"\n >\n <CalendarIcon />\n </Button>\n )\n }\n {...rest}\n />\n );\n },\n);\n"],"names":[],"mappings":"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"}
|
|
@@ -54,7 +54,7 @@ function useDatePicker(props, ref) {
|
|
|
54
54
|
const applySingle = useCallback(
|
|
55
55
|
(event, date) => {
|
|
56
56
|
setCancelled(false);
|
|
57
|
-
setOpen(false);
|
|
57
|
+
setOpen(false, event.nativeEvent, "apply");
|
|
58
58
|
if (selectionVariant === "single") {
|
|
59
59
|
onApply == null ? void 0 : onApply(event, date);
|
|
60
60
|
}
|
|
@@ -82,7 +82,7 @@ function useDatePicker(props, ref) {
|
|
|
82
82
|
const applyRange = useCallback(
|
|
83
83
|
(event, date) => {
|
|
84
84
|
setCancelled(false);
|
|
85
|
-
setOpen(false);
|
|
85
|
+
setOpen(false, event.nativeEvent, "apply");
|
|
86
86
|
if (selectionVariant === "range") {
|
|
87
87
|
onApply == null ? void 0 : onApply(event, date);
|
|
88
88
|
}
|
|
@@ -107,11 +107,14 @@ function useDatePicker(props, ref) {
|
|
|
107
107
|
setSelectedDate
|
|
108
108
|
]
|
|
109
109
|
);
|
|
110
|
-
const cancel = useCallback(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
const cancel = useCallback(
|
|
111
|
+
(event) => {
|
|
112
|
+
setCancelled(true);
|
|
113
|
+
setOpen(false, event, "cancel");
|
|
114
|
+
onCancel == null ? void 0 : onCancel();
|
|
115
|
+
},
|
|
116
|
+
[setCancelled, setOpen, onCancel]
|
|
117
|
+
);
|
|
115
118
|
const returnValue = {
|
|
116
119
|
state: {
|
|
117
120
|
selectionVariant,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDatePicker.js","sources":["../src/date-picker/useDatePicker.ts"],"sourcesContent":["import { useControlled, useForkRef, useFormFieldProps } from \"@salt-ds/core\";\nimport type { DateFrameworkType } from \"@salt-ds/date-adapters\";\nimport {\n type SyntheticEvent,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { DateRangeSelection, SingleDateSelection } from \"../calendar\";\nimport type {\n DateInputRangeDetails,\n DateInputSingleDetails,\n} from \"../date-input\";\nimport { useLocalization } from \"../localization-provider\";\nimport type {\n RangeDatePickerState,\n SingleDatePickerState,\n} from \"./DatePickerContext\";\nimport { useDatePickerOverlay } from \"./DatePickerOverlayProvider\";\n\ninterface UseDatePickerBaseProps<TDate> {\n /** If `true`, the component is disabled. */\n disabled?: boolean;\n /** If `true`, the component is read-only. */\n readOnly?: boolean;\n /**\n * The minimum date for the range, default is 1900.\n */\n minDate?: TDate;\n /**\n * The maximum date for the range, default is 2100.\n */\n maxDate?: TDate;\n /**\n * Handler for when the date selection is cancelled.\n */\n onCancel?: () => void;\n}\n\n/**\n * Props for single date selection.\n *\n * @template TDate - The type of the date framework.\n */\nexport interface UseDatePickerSingleProps<TDate extends DateFrameworkType>\n extends UseDatePickerBaseProps<TDate> {\n /**\n * Single date selection.\n */\n selectionVariant: \"single\";\n /**\n * The selected date. The selected date will be controlled when this prop is provided.\n */\n selectedDate?: SingleDateSelection<TDate> | null;\n /**\n * The initial selected date, when the selected date is uncontrolled.\n */\n defaultSelectedDate?: SingleDateSelection<TDate> | null;\n /**\n * Handler called when the selected date changes.\n * @param event - The synthetic event.\n * @param date - The selected date or null.\n * @param details - The selected date details.\n */\n onSelectionChange?: (\n event: SyntheticEvent,\n date: SingleDateSelection<TDate> | null,\n details?: DateInputSingleDetails,\n ) => void;\n /**\n * Handler called when the selected date is confirmed/applied.\n * @param event - The synthetic event.\n * @param date - The selected date or null.\n */\n onApply?: (\n event: SyntheticEvent,\n date: SingleDateSelection<TDate> | null,\n ) => void;\n}\n\n/**\n * Props for date range selection.\n *\n * @template TDate - The type of the date framework.\n */\nexport interface UseDatePickerRangeProps<TDate extends DateFrameworkType>\n extends UseDatePickerBaseProps<TDate> {\n /**\n * Date range selection.\n */\n selectionVariant: \"range\";\n /**\n * The selected date range. The selected date will be controlled when this prop is provided.\n */\n selectedDate?: DateRangeSelection<TDate> | null;\n /**\n * The initial selected date range, when the selected date is uncontrolled.\n */\n defaultSelectedDate?: DateRangeSelection<TDate> | null;\n /**\n * Handler called when the selected date range changes.\n * @param event - The synthetic event.\n * @param date - The selected date range or null.\n * @param details - The selected date range details.\n */\n onSelectionChange?: (\n event: SyntheticEvent,\n date: DateRangeSelection<TDate> | null,\n details?: DateInputRangeDetails,\n ) => void;\n /**\n * Handler called when the selected date range is confirmed/applied.\n * @param event - The synthetic event.\n * @param date - The selected date range.\n */\n onApply?: (\n event: SyntheticEvent,\n date: DateRangeSelection<TDate> | null,\n ) => void;\n}\n\n/**\n * Props for the useDatePicker hook.\n *\n * @template TDate - The type of the date framework.\n * @template SelectionVariant - The selection variant, either \"single\" or \"range\".\n */\nexport type UseDatePickerProps<\n TDate extends DateFrameworkType,\n SelectionVariant,\n> = SelectionVariant extends \"single\"\n ? UseDatePickerSingleProps<TDate>\n : SelectionVariant extends \"range\"\n ? UseDatePickerRangeProps<TDate>\n : never;\n\n/**\n * Custom hook for managing date picker state.\n *\n * @template TDate - The type of the date framework.\n * @template SelectionVariant - The selection variant, either \"single\" or \"range\".\n * @param props - The props for the date picker.\n * @param ref - The ref for the date picker container.\n * @returns The date picker state and helpers.\n */\nexport function useDatePicker<\n TDate extends DateFrameworkType,\n SelectionVariant extends \"single\" | \"range\",\n>(\n props: UseDatePickerProps<TDate, SelectionVariant>,\n ref: React.ForwardedRef<HTMLDivElement>,\n): SingleDatePickerState<TDate> | RangeDatePickerState<TDate> {\n const {\n defaultDates: { minDate: defaultMinDate, maxDate: defaultMaxDate },\n } = useLocalization<TDate>();\n const {\n readOnly = false,\n disabled,\n selectionVariant,\n defaultSelectedDate,\n selectedDate: selectedDateProp,\n onSelectionChange,\n onApply,\n minDate = defaultMinDate,\n maxDate = defaultMaxDate,\n onCancel,\n } = props;\n\n const previousSelectedDate = useRef<typeof selectedDateProp>();\n const datePickerRef = useRef<HTMLDivElement>(null);\n const containerRef = useForkRef(ref, datePickerRef);\n\n const {\n state: { open },\n helpers: { setOpen, setOnDismiss },\n } = useDatePickerOverlay();\n\n const [selectedDate, setSelectedDate] = useControlled({\n controlled: selectedDateProp,\n default: defaultSelectedDate,\n name: \"DatePicker\",\n state: \"selectedDate\",\n });\n\n const [enableApply, setEnableApply] = useState<boolean>(false);\n const [cancelled, setCancelled] = useState<boolean>(false);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: should run when open changes and not selected date or value\n useEffect(() => {\n if (open) {\n previousSelectedDate.current = selectedDate;\n if (enableApply) {\n setOnDismiss(cancel);\n }\n setCancelled(false);\n }\n }, [enableApply, open, setOnDismiss, setCancelled]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: avoid excessive re-rendering\n useEffect(() => {\n if (cancelled) {\n setSelectedDate(previousSelectedDate?.current);\n }\n }, [cancelled, setSelectedDate]);\n\n const { disabled: formFieldDisabled, readOnly: formFieldReadOnly } =\n useFormFieldProps();\n const isReadOnly = readOnly || formFieldReadOnly || false;\n const isDisabled = disabled || formFieldDisabled || false;\n\n const applySingle = useCallback(\n (event: SyntheticEvent, date: SingleDateSelection<TDate> | null): void => {\n setCancelled(false);\n setOpen(false);\n if (selectionVariant === \"single\") {\n onApply?.(event, date);\n }\n },\n [setCancelled, setOpen, onApply],\n );\n\n const selectSingle = useCallback(\n (\n event: SyntheticEvent,\n date: SingleDateSelection<TDate> | null,\n details: DateInputSingleDetails,\n ) => {\n setSelectedDate(date);\n if (selectionVariant === \"single\") {\n onSelectionChange?.(event, date, details);\n }\n if (!enableApply && date) {\n applySingle(event, date);\n }\n },\n [\n applySingle,\n enableApply,\n onSelectionChange,\n selectionVariant,\n setSelectedDate,\n ],\n );\n\n const applyRange = useCallback(\n (event: SyntheticEvent, date: DateRangeSelection<TDate> | null): void => {\n setCancelled(false);\n setOpen(false);\n if (selectionVariant === \"range\") {\n onApply?.(event, date);\n }\n },\n [onApply, setCancelled, setOpen, selectionVariant],\n );\n\n const selectRange = useCallback(\n (\n event: SyntheticEvent,\n date: DateRangeSelection<TDate> | null,\n details: DateInputRangeDetails,\n ) => {\n setSelectedDate(date);\n if (selectionVariant === \"range\") {\n onSelectionChange?.(event, date, details);\n }\n if (!enableApply && date?.startDate && date?.endDate) {\n applyRange(event, date);\n }\n },\n [\n applyRange,\n enableApply,\n onSelectionChange,\n selectionVariant,\n setSelectedDate,\n ],\n );\n\n const cancel = useCallback(() => {\n setCancelled(true);\n setOpen(false);\n onCancel?.();\n }, [setCancelled, setOpen, onCancel]);\n\n const returnValue = {\n state: {\n selectionVariant,\n selectedDate,\n cancelled,\n enableApply,\n disabled: isDisabled,\n readOnly: isReadOnly,\n containerRef,\n minDate,\n maxDate,\n },\n helpers: {\n cancel,\n setEnableApply,\n },\n };\n if (props.selectionVariant === \"range\") {\n return {\n ...returnValue,\n helpers: {\n ...returnValue.helpers,\n apply: applyRange,\n select: selectRange,\n },\n } as RangeDatePickerState<TDate>;\n }\n return {\n ...returnValue,\n helpers: {\n ...returnValue.helpers,\n apply: applySingle,\n select: selectSingle,\n },\n } as SingleDatePickerState<TDate>;\n}\n"],"names":[],"mappings":";;;;;AAkJgB,SAAA,aAAA,CAId,OACA,GAC4D,EAAA;AAC5D,EAAM,MAAA;AAAA,IACJ,YAAc,EAAA,EAAE,OAAS,EAAA,cAAA,EAAgB,SAAS,cAAe;AAAA,MAC/D,eAAuB,EAAA;AAC3B,EAAM,MAAA;AAAA,IACJ,QAAW,GAAA,KAAA;AAAA,IACX,QAAA;AAAA,IACA,gBAAA;AAAA,IACA,mBAAA;AAAA,IACA,YAAc,EAAA,gBAAA;AAAA,IACd,iBAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAU,GAAA,cAAA;AAAA,IACV,OAAU,GAAA,cAAA;AAAA,IACV;AAAA,GACE,GAAA,KAAA;AAEJ,EAAA,MAAM,uBAAuB,MAAgC,EAAA;AAC7D,EAAM,MAAA,aAAA,GAAgB,OAAuB,IAAI,CAAA;AACjD,EAAM,MAAA,YAAA,GAAe,UAAW,CAAA,GAAA,EAAK,aAAa,CAAA;AAElD,EAAM,MAAA;AAAA,IACJ,KAAA,EAAO,EAAE,IAAK,EAAA;AAAA,IACd,OAAA,EAAS,EAAE,OAAA,EAAS,YAAa;AAAA,MAC/B,oBAAqB,EAAA;AAEzB,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,aAAc,CAAA;AAAA,IACpD,UAAY,EAAA,gBAAA;AAAA,IACZ,OAAS,EAAA,mBAAA;AAAA,IACT,IAAM,EAAA,YAAA;AAAA,IACN,KAAO,EAAA;AAAA,GACR,CAAA;AAED,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAkB,KAAK,CAAA;AAC7D,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAkB,KAAK,CAAA;AAGzD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,IAAM,EAAA;AACR,MAAA,oBAAA,CAAqB,OAAU,GAAA,YAAA;AAC/B,MAAA,IAAI,WAAa,EAAA;AACf,QAAA,YAAA,CAAa,MAAM,CAAA;AAAA;AAErB,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA;AACpB,KACC,CAAC,WAAA,EAAa,IAAM,EAAA,YAAA,EAAc,YAAY,CAAC,CAAA;AAGlD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAW,EAAA;AACb,MAAA,eAAA,CAAgB,6DAAsB,OAAO,CAAA;AAAA;AAC/C,GACC,EAAA,CAAC,SAAW,EAAA,eAAe,CAAC,CAAA;AAE/B,EAAA,MAAM,EAAE,QAAU,EAAA,iBAAA,EAAmB,QAAU,EAAA,iBAAA,KAC7C,iBAAkB,EAAA;AACpB,EAAM,MAAA,UAAA,GAAa,YAAY,iBAAqB,IAAA,KAAA;AACpD,EAAM,MAAA,UAAA,GAAa,YAAY,iBAAqB,IAAA,KAAA;AAEpD,EAAA,MAAM,WAAc,GAAA,WAAA;AAAA,IAClB,CAAC,OAAuB,IAAkD,KAAA;AACxE,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA,OAAA,CAAQ,KAAK,CAAA;AACb,MAAA,IAAI,qBAAqB,QAAU,EAAA;AACjC,QAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAU,KAAO,EAAA,IAAA,CAAA;AAAA;AACnB,KACF;AAAA,IACA,CAAC,YAAc,EAAA,OAAA,EAAS,OAAO;AAAA,GACjC;AAEA,EAAA,MAAM,YAAe,GAAA,WAAA;AAAA,IACnB,CACE,KACA,EAAA,IAAA,EACA,OACG,KAAA;AACH,MAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,MAAA,IAAI,qBAAqB,QAAU,EAAA;AACjC,QAAA,iBAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,iBAAA,CAAoB,OAAO,IAAM,EAAA,OAAA,CAAA;AAAA;AAEnC,MAAI,IAAA,CAAC,eAAe,IAAM,EAAA;AACxB,QAAA,WAAA,CAAY,OAAO,IAAI,CAAA;AAAA;AACzB,KACF;AAAA,IACA;AAAA,MACE,WAAA;AAAA,MACA,WAAA;AAAA,MACA,iBAAA;AAAA,MACA,gBAAA;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAA,MAAM,UAAa,GAAA,WAAA;AAAA,IACjB,CAAC,OAAuB,IAAiD,KAAA;AACvE,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA,OAAA,CAAQ,KAAK,CAAA;AACb,MAAA,IAAI,qBAAqB,OAAS,EAAA;AAChC,QAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAU,KAAO,EAAA,IAAA,CAAA;AAAA;AACnB,KACF;AAAA,IACA,CAAC,OAAA,EAAS,YAAc,EAAA,OAAA,EAAS,gBAAgB;AAAA,GACnD;AAEA,EAAA,MAAM,WAAc,GAAA,WAAA;AAAA,IAClB,CACE,KACA,EAAA,IAAA,EACA,OACG,KAAA;AACH,MAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,MAAA,IAAI,qBAAqB,OAAS,EAAA;AAChC,QAAA,iBAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,iBAAA,CAAoB,OAAO,IAAM,EAAA,OAAA,CAAA;AAAA;AAEnC,MAAA,IAAI,CAAC,WAAA,KAAe,IAAM,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,IAAA,CAAA,SAAA,CAAA,KAAa,6BAAM,OAAS,CAAA,EAAA;AACpD,QAAA,UAAA,CAAW,OAAO,IAAI,CAAA;AAAA;AACxB,KACF;AAAA,IACA;AAAA,MACE,UAAA;AAAA,MACA,WAAA;AAAA,MACA,iBAAA;AAAA,MACA,gBAAA;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAM,MAAA,MAAA,GAAS,YAAY,MAAM;AAC/B,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAA,OAAA,CAAQ,KAAK,CAAA;AACb,IAAA,QAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,QAAA,EAAA;AAAA,GACC,EAAA,CAAC,YAAc,EAAA,OAAA,EAAS,QAAQ,CAAC,CAAA;AAEpC,EAAA,MAAM,WAAc,GAAA;AAAA,IAClB,KAAO,EAAA;AAAA,MACL,gBAAA;AAAA,MACA,YAAA;AAAA,MACA,SAAA;AAAA,MACA,WAAA;AAAA,MACA,QAAU,EAAA,UAAA;AAAA,MACV,QAAU,EAAA,UAAA;AAAA,MACV,YAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,OAAS,EAAA;AAAA,MACP,MAAA;AAAA,MACA;AAAA;AACF,GACF;AACA,EAAI,IAAA,KAAA,CAAM,qBAAqB,OAAS,EAAA;AACtC,IAAO,OAAA;AAAA,MACL,GAAG,WAAA;AAAA,MACH,OAAS,EAAA;AAAA,QACP,GAAG,WAAY,CAAA,OAAA;AAAA,QACf,KAAO,EAAA,UAAA;AAAA,QACP,MAAQ,EAAA;AAAA;AACV,KACF;AAAA;AAEF,EAAO,OAAA;AAAA,IACL,GAAG,WAAA;AAAA,IACH,OAAS,EAAA;AAAA,MACP,GAAG,WAAY,CAAA,OAAA;AAAA,MACf,KAAO,EAAA,WAAA;AAAA,MACP,MAAQ,EAAA;AAAA;AACV,GACF;AACF;;;;"}
|
|
1
|
+
{"version":3,"file":"useDatePicker.js","sources":["../src/date-picker/useDatePicker.ts"],"sourcesContent":["import { useControlled, useForkRef, useFormFieldProps } from \"@salt-ds/core\";\nimport type { DateFrameworkType } from \"@salt-ds/date-adapters\";\nimport {\n type SyntheticEvent,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { DateRangeSelection, SingleDateSelection } from \"../calendar\";\nimport type {\n DateInputRangeDetails,\n DateInputSingleDetails,\n} from \"../date-input\";\nimport { useLocalization } from \"../localization-provider\";\nimport type {\n RangeDatePickerState,\n SingleDatePickerState,\n} from \"./DatePickerContext\";\nimport { useDatePickerOverlay } from \"./DatePickerOverlayProvider\";\n\ninterface UseDatePickerBaseProps<TDate> {\n /** If `true`, the component is disabled. */\n disabled?: boolean;\n /** If `true`, the component is read-only. */\n readOnly?: boolean;\n /**\n * The minimum date for the range, default is 1900.\n */\n minDate?: TDate;\n /**\n * The maximum date for the range, default is 2100.\n */\n maxDate?: TDate;\n /**\n * Handler for when the date selection is cancelled.\n */\n onCancel?: () => void;\n}\n\n/**\n * Props for single date selection.\n *\n * @template TDate - The type of the date framework.\n */\nexport interface UseDatePickerSingleProps<TDate extends DateFrameworkType>\n extends UseDatePickerBaseProps<TDate> {\n /**\n * Single date selection.\n */\n selectionVariant: \"single\";\n /**\n * The selected date. The selected date will be controlled when this prop is provided.\n */\n selectedDate?: SingleDateSelection<TDate> | null;\n /**\n * The initial selected date, when the selected date is uncontrolled.\n */\n defaultSelectedDate?: SingleDateSelection<TDate> | null;\n /**\n * Handler called when the selected date changes.\n * @param event - The synthetic event.\n * @param date - The selected date or null.\n * @param details - The selected date details.\n */\n onSelectionChange?: (\n event: SyntheticEvent,\n date: SingleDateSelection<TDate> | null,\n details?: DateInputSingleDetails,\n ) => void;\n /**\n * Handler called when the selected date is confirmed/applied.\n * @param event - The synthetic event.\n * @param date - The selected date or null.\n */\n onApply?: (\n event: SyntheticEvent,\n date: SingleDateSelection<TDate> | null,\n ) => void;\n}\n\n/**\n * Props for date range selection.\n *\n * @template TDate - The type of the date framework.\n */\nexport interface UseDatePickerRangeProps<TDate extends DateFrameworkType>\n extends UseDatePickerBaseProps<TDate> {\n /**\n * Date range selection.\n */\n selectionVariant: \"range\";\n /**\n * The selected date range. The selected date will be controlled when this prop is provided.\n */\n selectedDate?: DateRangeSelection<TDate> | null;\n /**\n * The initial selected date range, when the selected date is uncontrolled.\n */\n defaultSelectedDate?: DateRangeSelection<TDate> | null;\n /**\n * Handler called when the selected date range changes.\n * @param event - The synthetic event.\n * @param date - The selected date range or null.\n * @param details - The selected date range details.\n */\n onSelectionChange?: (\n event: SyntheticEvent,\n date: DateRangeSelection<TDate> | null,\n details?: DateInputRangeDetails,\n ) => void;\n /**\n * Handler called when the selected date range is confirmed/applied.\n * @param event - The synthetic event.\n * @param date - The selected date range.\n */\n onApply?: (\n event: SyntheticEvent,\n date: DateRangeSelection<TDate> | null,\n ) => void;\n}\n\n/**\n * Props for the useDatePicker hook.\n *\n * @template TDate - The type of the date framework.\n * @template SelectionVariant - The selection variant, either \"single\" or \"range\".\n */\nexport type UseDatePickerProps<\n TDate extends DateFrameworkType,\n SelectionVariant,\n> = SelectionVariant extends \"single\"\n ? UseDatePickerSingleProps<TDate>\n : SelectionVariant extends \"range\"\n ? UseDatePickerRangeProps<TDate>\n : never;\n\n/**\n * Custom hook for managing date picker state.\n *\n * @template TDate - The type of the date framework.\n * @template SelectionVariant - The selection variant, either \"single\" or \"range\".\n * @param props - The props for the date picker.\n * @param ref - The ref for the date picker container.\n * @returns The date picker state and helpers.\n */\nexport function useDatePicker<\n TDate extends DateFrameworkType,\n SelectionVariant extends \"single\" | \"range\",\n>(\n props: UseDatePickerProps<TDate, SelectionVariant>,\n ref: React.ForwardedRef<HTMLDivElement>,\n): SingleDatePickerState<TDate> | RangeDatePickerState<TDate> {\n const {\n defaultDates: { minDate: defaultMinDate, maxDate: defaultMaxDate },\n } = useLocalization<TDate>();\n const {\n readOnly = false,\n disabled,\n selectionVariant,\n defaultSelectedDate,\n selectedDate: selectedDateProp,\n onSelectionChange,\n onApply,\n minDate = defaultMinDate,\n maxDate = defaultMaxDate,\n onCancel,\n } = props;\n\n const previousSelectedDate = useRef<typeof selectedDateProp>();\n const datePickerRef = useRef<HTMLDivElement>(null);\n const containerRef = useForkRef(ref, datePickerRef);\n\n const {\n state: { open },\n helpers: { setOpen, setOnDismiss },\n } = useDatePickerOverlay();\n\n const [selectedDate, setSelectedDate] = useControlled({\n controlled: selectedDateProp,\n default: defaultSelectedDate,\n name: \"DatePicker\",\n state: \"selectedDate\",\n });\n\n const [enableApply, setEnableApply] = useState<boolean>(false);\n const [cancelled, setCancelled] = useState<boolean>(false);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: should run when open changes and not selected date or value\n useEffect(() => {\n if (open) {\n previousSelectedDate.current = selectedDate;\n if (enableApply) {\n setOnDismiss(cancel);\n }\n setCancelled(false);\n }\n }, [enableApply, open, setOnDismiss, setCancelled]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: avoid excessive re-rendering\n useEffect(() => {\n if (cancelled) {\n setSelectedDate(previousSelectedDate?.current);\n }\n }, [cancelled, setSelectedDate]);\n\n const { disabled: formFieldDisabled, readOnly: formFieldReadOnly } =\n useFormFieldProps();\n const isReadOnly = readOnly || formFieldReadOnly || false;\n const isDisabled = disabled || formFieldDisabled || false;\n\n const applySingle = useCallback(\n (event: SyntheticEvent, date: SingleDateSelection<TDate> | null): void => {\n setCancelled(false);\n setOpen(false, event.nativeEvent, \"apply\");\n if (selectionVariant === \"single\") {\n onApply?.(event, date);\n }\n },\n [setCancelled, setOpen, onApply],\n );\n\n const selectSingle = useCallback(\n (\n event: SyntheticEvent,\n date: SingleDateSelection<TDate> | null,\n details: DateInputSingleDetails,\n ) => {\n setSelectedDate(date);\n if (selectionVariant === \"single\") {\n onSelectionChange?.(event, date, details);\n }\n if (!enableApply && date) {\n applySingle(event, date);\n }\n },\n [\n applySingle,\n enableApply,\n onSelectionChange,\n selectionVariant,\n setSelectedDate,\n ],\n );\n\n const applyRange = useCallback(\n (event: SyntheticEvent, date: DateRangeSelection<TDate> | null): void => {\n setCancelled(false);\n setOpen(false, event.nativeEvent, \"apply\");\n if (selectionVariant === \"range\") {\n onApply?.(event, date);\n }\n },\n [onApply, setCancelled, setOpen, selectionVariant],\n );\n\n const selectRange = useCallback(\n (\n event: SyntheticEvent,\n date: DateRangeSelection<TDate> | null,\n details: DateInputRangeDetails,\n ) => {\n setSelectedDate(date);\n if (selectionVariant === \"range\") {\n onSelectionChange?.(event, date, details);\n }\n if (!enableApply && date?.startDate && date?.endDate) {\n applyRange(event, date);\n }\n },\n [\n applyRange,\n enableApply,\n onSelectionChange,\n selectionVariant,\n setSelectedDate,\n ],\n );\n\n const cancel = useCallback(\n (event?: Event) => {\n setCancelled(true);\n setOpen(false, event, \"cancel\");\n onCancel?.();\n },\n [setCancelled, setOpen, onCancel],\n );\n\n const returnValue = {\n state: {\n selectionVariant,\n selectedDate,\n cancelled,\n enableApply,\n disabled: isDisabled,\n readOnly: isReadOnly,\n containerRef,\n minDate,\n maxDate,\n },\n helpers: {\n cancel,\n setEnableApply,\n },\n };\n if (props.selectionVariant === \"range\") {\n return {\n ...returnValue,\n helpers: {\n ...returnValue.helpers,\n apply: applyRange,\n select: selectRange,\n },\n } as RangeDatePickerState<TDate>;\n }\n return {\n ...returnValue,\n helpers: {\n ...returnValue.helpers,\n apply: applySingle,\n select: selectSingle,\n },\n } as SingleDatePickerState<TDate>;\n}\n"],"names":[],"mappings":"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"}
|