@react-md/core 6.2.1 → 6.3.1
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/dist/_base.scss +1 -1
- package/dist/app-bar/styles.d.ts +0 -2
- package/dist/app-bar/styles.js.map +1 -1
- package/dist/autocomplete/types.d.ts +12 -0
- package/dist/autocomplete/types.js.map +1 -1
- package/dist/avatar/Avatar.d.ts +0 -10
- package/dist/avatar/Avatar.js.map +1 -1
- package/dist/avatar/styles.d.ts +10 -0
- package/dist/avatar/styles.js.map +1 -1
- package/dist/badge/Badge.d.ts +11 -0
- package/dist/badge/Badge.js.map +1 -1
- package/dist/badge/styles.d.ts +0 -8
- package/dist/badge/styles.js.map +1 -1
- package/dist/box/_box.scss +8 -8
- package/dist/box/styles.d.ts +9 -0
- package/dist/box/styles.js.map +1 -1
- package/dist/button/_button.scss +4 -0
- package/dist/button/styles.d.ts +5 -1
- package/dist/button/styles.js.map +1 -1
- package/dist/card/Card.d.ts +0 -7
- package/dist/card/Card.js.map +1 -1
- package/dist/card/styles.d.ts +6 -0
- package/dist/card/styles.js +8 -8
- package/dist/card/styles.js.map +1 -1
- package/dist/chip/Chip.d.ts +6 -13
- package/dist/chip/Chip.js.map +1 -1
- package/dist/chip/styles.d.ts +26 -1
- package/dist/chip/styles.js.map +1 -1
- package/dist/datetime/NativeDateField.d.ts +24 -0
- package/dist/datetime/NativeDateField.js +63 -0
- package/dist/datetime/NativeDateField.js.map +1 -0
- package/dist/datetime/NativeTimeField.d.ts +26 -0
- package/dist/datetime/NativeTimeField.js +63 -0
- package/dist/datetime/NativeTimeField.js.map +1 -0
- package/dist/datetime/useDateField.d.ts +120 -0
- package/dist/datetime/useDateField.js +35 -0
- package/dist/datetime/useDateField.js.map +1 -0
- package/dist/datetime/useTimeField.d.ts +124 -0
- package/dist/datetime/useTimeField.js +65 -0
- package/dist/datetime/useTimeField.js.map +1 -0
- package/dist/datetime/utils.d.ts +34 -0
- package/dist/datetime/utils.js +27 -0
- package/dist/datetime/utils.js.map +1 -0
- package/dist/dialog/styles.d.ts +5 -2
- package/dist/dialog/styles.js.map +1 -1
- package/dist/divider/styles.d.ts +1 -1
- package/dist/divider/styles.js.map +1 -1
- package/dist/draggable/utils.d.ts +3 -6
- package/dist/draggable/utils.js.map +1 -1
- package/dist/error-boundary/ErrorBoundary.js.map +1 -1
- package/dist/expansion-panel/ExpansionList.js +1 -1
- package/dist/expansion-panel/ExpansionList.js.map +1 -1
- package/dist/expansion-panel/useExpansionList.d.ts +2 -7
- package/dist/expansion-panel/useExpansionList.js.map +1 -1
- package/dist/files/validation.js.map +1 -1
- package/dist/form/FormMessage.js +3 -1
- package/dist/form/FormMessage.js.map +1 -1
- package/dist/form/FormMessageContainer.d.ts +2 -1
- package/dist/form/FormMessageContainer.js +3 -2
- package/dist/form/FormMessageContainer.js.map +1 -1
- package/dist/form/FormMessageCounter.d.ts +3 -2
- package/dist/form/FormMessageCounter.js +5 -2
- package/dist/form/FormMessageCounter.js.map +1 -1
- package/dist/form/InputToggle.js.map +1 -1
- package/dist/form/Label.d.ts +0 -10
- package/dist/form/Label.js.map +1 -1
- package/dist/form/Listbox.d.ts +3 -10
- package/dist/form/Listbox.js +8 -27
- package/dist/form/Listbox.js.map +1 -1
- package/dist/form/ListboxProvider.d.ts +17 -0
- package/dist/form/ListboxProvider.js +33 -1
- package/dist/form/ListboxProvider.js.map +1 -1
- package/dist/form/NativeSelect.js +1 -0
- package/dist/form/NativeSelect.js.map +1 -1
- package/dist/form/Slider.d.ts +4 -0
- package/dist/form/Slider.js.map +1 -1
- package/dist/form/Switch.js.map +1 -1
- package/dist/form/TextArea.js +1 -0
- package/dist/form/TextArea.js.map +1 -1
- package/dist/form/TextField.js +1 -0
- package/dist/form/TextField.js.map +1 -1
- package/dist/form/TextFieldContainer.d.ts +0 -13
- package/dist/form/TextFieldContainer.js.map +1 -1
- package/dist/form/_form-message.scss +13 -0
- package/dist/form/_select.scss +5 -1
- package/dist/form/_text-area.scss +2 -1
- package/dist/form/_text-field.scss +13 -3
- package/dist/form/formMessageContainerStyles.d.ts +7 -0
- package/dist/form/formMessageContainerStyles.js +4 -2
- package/dist/form/formMessageContainerStyles.js.map +1 -1
- package/dist/form/sliderUtils.d.ts +3 -7
- package/dist/form/sliderUtils.js.map +1 -1
- package/dist/form/types.d.ts +33 -0
- package/dist/form/types.js.map +1 -1
- package/dist/form/useCombobox.d.ts +6 -2
- package/dist/form/useCombobox.js +8 -9
- package/dist/form/useCombobox.js.map +1 -1
- package/dist/form/useFormReset.d.ts +4 -1
- package/dist/form/useFormReset.js +9 -4
- package/dist/form/useFormReset.js.map +1 -1
- package/dist/form/useNumberField.d.ts +5 -5
- package/dist/form/useNumberField.js +10 -2
- package/dist/form/useNumberField.js.map +1 -1
- package/dist/form/useSelectCombobox.js +2 -2
- package/dist/form/useSelectCombobox.js.map +1 -1
- package/dist/form/useTextField.d.ts +76 -59
- package/dist/form/useTextField.js +7 -1
- package/dist/form/useTextField.js.map +1 -1
- package/dist/interaction/types.d.ts +5 -1
- package/dist/interaction/types.js.map +1 -1
- package/dist/interaction/utils.d.ts +14 -0
- package/dist/interaction/utils.js +23 -12
- package/dist/interaction/utils.js.map +1 -1
- package/dist/link/Link.d.ts +0 -7
- package/dist/link/Link.js.map +1 -1
- package/dist/link/styles.d.ts +7 -0
- package/dist/link/styles.js.map +1 -1
- package/dist/list/List.d.ts +5 -20
- package/dist/list/List.js.map +1 -1
- package/dist/list/ListItem.d.ts +4 -38
- package/dist/list/ListItem.js.map +1 -1
- package/dist/list/listItemStyles.d.ts +24 -2
- package/dist/list/listItemStyles.js.map +1 -1
- package/dist/list/listStyles.d.ts +17 -2
- package/dist/list/listStyles.js.map +1 -1
- package/dist/menu/Menu.js.map +1 -1
- package/dist/menu/MenuBar.js +1 -1
- package/dist/menu/MenuBar.js.map +1 -1
- package/dist/menu/MenuItemTextField.d.ts +1 -2
- package/dist/menu/MenuItemTextField.js.map +1 -1
- package/dist/menu/MenuWidget.js +3 -2
- package/dist/menu/MenuWidget.js.map +1 -1
- package/dist/movement/constants.d.ts +10 -0
- package/dist/movement/constants.js +20 -4
- package/dist/movement/constants.js.map +1 -1
- package/dist/movement/types.d.ts +59 -10
- package/dist/movement/types.js.map +1 -1
- package/dist/movement/useKeyboardMovementProvider.d.ts +5 -1
- package/dist/movement/useKeyboardMovementProvider.js +171 -73
- package/dist/movement/useKeyboardMovementProvider.js.map +1 -1
- package/dist/navigation/NavItem.d.ts +4 -1
- package/dist/navigation/NavItem.js.map +1 -1
- package/dist/navigation/navItemStyles.d.ts +7 -0
- package/dist/navigation/navItemStyles.js.map +1 -1
- package/dist/overlay/Overlay.d.ts +4 -23
- package/dist/overlay/Overlay.js.map +1 -1
- package/dist/overlay/styles.d.ts +26 -8
- package/dist/overlay/styles.js.map +1 -1
- package/dist/progress/LinearProgress.d.ts +4 -9
- package/dist/progress/LinearProgress.js.map +1 -1
- package/dist/progress/circularProgressStyles.d.ts +6 -0
- package/dist/progress/circularProgressStyles.js.map +1 -1
- package/dist/progress/linearProgressStyles.d.ts +20 -5
- package/dist/progress/linearProgressStyles.js.map +1 -1
- package/dist/progress/types.d.ts +0 -9
- package/dist/progress/types.js.map +1 -1
- package/dist/segmented-button/SegmentedButton.d.ts +7 -12
- package/dist/segmented-button/SegmentedButton.js.map +1 -1
- package/dist/segmented-button/segmentedButtonStyles.d.ts +26 -3
- package/dist/segmented-button/segmentedButtonStyles.js.map +1 -1
- package/dist/sheet/Sheet.d.ts +0 -12
- package/dist/sheet/Sheet.js.map +1 -1
- package/dist/sheet/styles.d.ts +12 -0
- package/dist/sheet/styles.js.map +1 -1
- package/dist/snackbar/Toast.d.ts +2 -13
- package/dist/snackbar/Toast.js.map +1 -1
- package/dist/snackbar/ToastManager.js.map +1 -1
- package/dist/snackbar/toastStyles.d.ts +17 -2
- package/dist/snackbar/toastStyles.js.map +1 -1
- package/dist/tabs/Tab.d.ts +2 -41
- package/dist/tabs/Tab.js.map +1 -1
- package/dist/tabs/tabStyles.d.ts +45 -4
- package/dist/tabs/tabStyles.js.map +1 -1
- package/dist/tabs/useTabList.js +1 -1
- package/dist/tabs/useTabList.js.map +1 -1
- package/dist/test-utils/drag.d.ts +6 -9
- package/dist/test-utils/mocks/IntersectionObserver.js.map +1 -1
- package/dist/test-utils/mocks/ResizeObserver.js.map +1 -1
- package/dist/test-utils/utils/createFileList.js.map +1 -1
- package/dist/theme/_theme.scss +0 -1
- package/dist/theme/getDerivedTheme.d.ts +0 -24
- package/dist/theme/getDerivedTheme.js.map +1 -1
- package/dist/theme/types.d.ts +25 -0
- package/dist/theme/types.js.map +1 -1
- package/dist/tooltip/Tooltip.d.ts +4 -32
- package/dist/tooltip/Tooltip.js.map +1 -1
- package/dist/tooltip/styles.d.ts +38 -1
- package/dist/tooltip/styles.js +1 -1
- package/dist/tooltip/styles.js.map +1 -1
- package/dist/transition/SkeletonPlaceholder.d.ts +0 -7
- package/dist/transition/SkeletonPlaceholder.js.map +1 -1
- package/dist/transition/Slide.js.map +1 -1
- package/dist/transition/skeletonPlaceholderUtils.d.ts +7 -0
- package/dist/transition/skeletonPlaceholderUtils.js.map +1 -1
- package/dist/transition/useCarousel.d.ts +2 -2
- package/dist/transition/useCarousel.js.map +1 -1
- package/dist/transition/useMaxWidthTransition.d.ts +14 -2
- package/dist/transition/useMaxWidthTransition.js.map +1 -1
- package/dist/transition/useSlideTransition.d.ts +5 -0
- package/dist/transition/useSlideTransition.js.map +1 -1
- package/dist/tree/Tree.d.ts +5 -9
- package/dist/tree/Tree.js +1 -1
- package/dist/tree/Tree.js.map +1 -1
- package/dist/tree/styles.d.ts +9 -1
- package/dist/tree/styles.js.map +1 -1
- package/dist/tree/useTreeMovement.d.ts +2 -1
- package/dist/tree/useTreeMovement.js +2 -1
- package/dist/tree/useTreeMovement.js.map +1 -1
- package/dist/types.d.ts +14 -0
- package/dist/types.js.map +1 -1
- package/dist/typography/Mark.d.ts +4 -1
- package/dist/typography/Mark.js.map +1 -1
- package/dist/typography/TextContainer.d.ts +0 -6
- package/dist/typography/TextContainer.js.map +1 -1
- package/dist/typography/markStyles.d.ts +5 -0
- package/dist/typography/markStyles.js.map +1 -1
- package/dist/typography/textContainerStyles.d.ts +6 -0
- package/dist/typography/textContainerStyles.js.map +1 -1
- package/dist/typography/typographyStyles.d.ts +9 -0
- package/dist/typography/typographyStyles.js.map +1 -1
- package/dist/useResizeObserver.js.map +1 -1
- package/dist/utils/getMiddleOfRange.d.ts +2 -3
- package/dist/utils/getMiddleOfRange.js.map +1 -1
- package/dist/utils/getPercentage.d.ts +2 -9
- package/dist/utils/getPercentage.js +1 -1
- package/dist/utils/getPercentage.js.map +1 -1
- package/dist/utils/getRangeSteps.d.ts +2 -3
- package/dist/utils/getRangeSteps.js +0 -3
- package/dist/utils/getRangeSteps.js.map +1 -1
- package/dist/utils/nearest.d.ts +2 -3
- package/dist/utils/nearest.js +0 -3
- package/dist/utils/nearest.js.map +1 -1
- package/dist/utils/trigonometry.d.ts +31 -0
- package/dist/utils/trigonometry.js +25 -0
- package/dist/utils/trigonometry.js.map +1 -0
- package/dist/window-splitter/WindowSplitter.d.ts +5 -19
- package/dist/window-splitter/WindowSplitter.js.map +1 -1
- package/dist/window-splitter/styles.d.ts +27 -3
- package/dist/window-splitter/styles.js.map +1 -1
- package/dist/window-splitter/useWindowSplitter.d.ts +1 -1
- package/dist/window-splitter/useWindowSplitter.js.map +1 -1
- package/package.json +8 -8
- package/src/app-bar/styles.ts +0 -2
- package/src/autocomplete/types.ts +17 -0
- package/src/avatar/Avatar.tsx +0 -11
- package/src/avatar/styles.ts +11 -0
- package/src/badge/Badge.tsx +12 -0
- package/src/badge/styles.ts +0 -9
- package/src/box/styles.ts +9 -0
- package/src/button/styles.ts +5 -1
- package/src/card/Card.tsx +0 -8
- package/src/card/styles.ts +15 -8
- package/src/chip/Chip.tsx +9 -15
- package/src/chip/styles.ts +29 -1
- package/src/datetime/NativeDateField.tsx +92 -0
- package/src/datetime/NativeTimeField.tsx +94 -0
- package/src/datetime/useDateField.ts +193 -0
- package/src/datetime/useTimeField.ts +233 -0
- package/src/datetime/utils.ts +48 -0
- package/src/dialog/styles.ts +5 -2
- package/src/divider/styles.ts +1 -1
- package/src/draggable/utils.ts +3 -6
- package/src/expansion-panel/ExpansionList.tsx +2 -1
- package/src/expansion-panel/useExpansionList.ts +6 -12
- package/src/form/FormMessage.tsx +4 -0
- package/src/form/FormMessageContainer.tsx +8 -4
- package/src/form/FormMessageCounter.tsx +17 -6
- package/src/form/InputToggle.tsx +2 -0
- package/src/form/Label.tsx +0 -11
- package/src/form/Listbox.tsx +18 -46
- package/src/form/ListboxProvider.ts +61 -1
- package/src/form/NativeSelect.tsx +1 -0
- package/src/form/Slider.tsx +6 -0
- package/src/form/Switch.tsx +2 -0
- package/src/form/TextArea.tsx +3 -0
- package/src/form/TextField.tsx +1 -0
- package/src/form/TextFieldContainer.tsx +0 -14
- package/src/form/formMessageContainerStyles.ts +10 -2
- package/src/form/sliderUtils.ts +3 -7
- package/src/form/types.ts +44 -0
- package/src/form/useCombobox.ts +15 -10
- package/src/form/useFormReset.ts +12 -5
- package/src/form/useNumberField.ts +17 -14
- package/src/form/useSelectCombobox.ts +2 -2
- package/src/form/useTextField.ts +102 -69
- package/src/interaction/types.ts +5 -1
- package/src/interaction/utils.ts +18 -20
- package/src/link/Link.tsx +0 -8
- package/src/link/styles.ts +8 -0
- package/src/list/List.tsx +7 -24
- package/src/list/ListItem.tsx +7 -43
- package/src/list/listItemStyles.ts +26 -2
- package/src/list/listStyles.ts +18 -2
- package/src/menu/Menu.tsx +2 -0
- package/src/menu/MenuBar.tsx +1 -1
- package/src/menu/MenuItemTextField.tsx +1 -3
- package/src/menu/MenuWidget.tsx +4 -2
- package/src/movement/constants.ts +26 -4
- package/src/movement/types.ts +84 -19
- package/src/movement/useKeyboardMovementProvider.ts +209 -95
- package/src/navigation/NavItem.tsx +6 -2
- package/src/navigation/navItemStyles.ts +8 -0
- package/src/overlay/Overlay.tsx +4 -26
- package/src/overlay/styles.ts +29 -10
- package/src/progress/LinearProgress.tsx +8 -10
- package/src/progress/circularProgressStyles.ts +7 -0
- package/src/progress/linearProgressStyles.ts +22 -5
- package/src/progress/types.ts +0 -10
- package/src/segmented-button/SegmentedButton.tsx +14 -15
- package/src/segmented-button/segmentedButtonStyles.ts +28 -3
- package/src/sheet/Sheet.tsx +0 -13
- package/src/sheet/styles.ts +13 -0
- package/src/snackbar/Toast.tsx +2 -15
- package/src/snackbar/toastStyles.ts +20 -2
- package/src/tabs/Tab.tsx +4 -49
- package/src/tabs/tabStyles.ts +52 -4
- package/src/tabs/useTabList.ts +1 -1
- package/src/test-utils/drag.ts +8 -12
- package/src/theme/getDerivedTheme.ts +0 -26
- package/src/theme/types.ts +26 -0
- package/src/tooltip/Tooltip.tsx +4 -36
- package/src/tooltip/styles.ts +43 -2
- package/src/transition/SkeletonPlaceholder.tsx +0 -8
- package/src/transition/Slide.tsx +2 -0
- package/src/transition/skeletonPlaceholderUtils.ts +8 -0
- package/src/transition/useCarousel.ts +2 -2
- package/src/transition/useMaxWidthTransition.ts +17 -2
- package/src/transition/useSlideTransition.ts +8 -0
- package/src/tree/Tree.tsx +6 -11
- package/src/tree/styles.ts +10 -1
- package/src/tree/useTreeMovement.ts +4 -0
- package/src/types.ts +16 -0
- package/src/typography/Mark.tsx +6 -2
- package/src/typography/TextContainer.tsx +0 -7
- package/src/typography/markStyles.ts +6 -0
- package/src/typography/textContainerStyles.ts +7 -0
- package/src/typography/typographyStyles.ts +10 -0
- package/src/utils/getMiddleOfRange.ts +2 -3
- package/src/utils/getPercentage.ts +3 -11
- package/src/utils/getRangeSteps.ts +3 -3
- package/src/utils/nearest.ts +3 -3
- package/src/utils/trigonometry.ts +46 -0
- package/src/window-splitter/WindowSplitter.tsx +9 -22
- package/src/window-splitter/styles.ts +31 -3
- package/src/window-splitter/useWindowSplitter.ts +3 -2
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { type InputHTMLAttributes, useRef } from "react";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
type ProvidedFormMessageProps,
|
|
7
|
+
type ProvidedTextFieldProps,
|
|
8
|
+
type TextFieldHookOptions,
|
|
9
|
+
type TextFieldImplementation,
|
|
10
|
+
type TextFieldWithMessageImplementation,
|
|
11
|
+
useTextField,
|
|
12
|
+
} from "../form/useTextField.js";
|
|
13
|
+
import { type TimeFieldStepOptions, getTimeStep } from "./utils.js";
|
|
14
|
+
|
|
15
|
+
/** @since 6.3.0 */
|
|
16
|
+
export interface TimeFieldConstraints {
|
|
17
|
+
/**
|
|
18
|
+
* This **must** be in the format `HH:mm`:
|
|
19
|
+
* - `00:30` (12:30 AM)
|
|
20
|
+
* - `15:15` (03:15 PM)
|
|
21
|
+
*
|
|
22
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/time#time_value_format | Time value format}
|
|
23
|
+
*/
|
|
24
|
+
min?: string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* This **must** be in the format `HH:mm`:
|
|
28
|
+
* - `00:30` (12:30 AM)
|
|
29
|
+
* - `15:15` (03:15 PM)
|
|
30
|
+
*
|
|
31
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/time#time_value_format | Time value format}
|
|
32
|
+
*/
|
|
33
|
+
max?: string;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* For time inputs, the value of step is given in seconds, with a scaling
|
|
37
|
+
* factor of 1000 (since the underlying numeric value is in milliseconds).
|
|
38
|
+
* The default value of step is 60, indicating 60 seconds (or 1 minute, or
|
|
39
|
+
* 60,000 milliseconds).
|
|
40
|
+
*
|
|
41
|
+
* When any is set as the value for step, the default 60 seconds is used, and
|
|
42
|
+
* the seconds value is not displayed in the UI.
|
|
43
|
+
*
|
|
44
|
+
* Here are a few examples:
|
|
45
|
+
*
|
|
46
|
+
* - `15` -> 15 seconds
|
|
47
|
+
* - `60` -> 1 minute
|
|
48
|
+
* - `900` -> 15 minutes
|
|
49
|
+
* - `3600` -> 1 hour
|
|
50
|
+
*
|
|
51
|
+
* Since this might be a bit confusing, the values can be provided in an
|
|
52
|
+
* object instead:
|
|
53
|
+
*
|
|
54
|
+
* ```ts
|
|
55
|
+
* { seconds: 30 }
|
|
56
|
+
* { minutes: 1 }
|
|
57
|
+
* { minutes: 15 }
|
|
58
|
+
* { hours: 1 }
|
|
59
|
+
* { seconds: 15, minutes: 30, hours: 1 }
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* NOTE: The `min` and `max` props **must** be provided as well for the
|
|
63
|
+
* `step` to work.
|
|
64
|
+
*
|
|
65
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/time#step | step attribute}
|
|
66
|
+
*/
|
|
67
|
+
step?: number | "any" | TimeFieldStepOptions;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** @since 6.3.0 */
|
|
71
|
+
export interface TimeFieldOptions
|
|
72
|
+
extends Omit<
|
|
73
|
+
TextFieldHookOptions,
|
|
74
|
+
| "isNumber"
|
|
75
|
+
| "counter"
|
|
76
|
+
| "pattern"
|
|
77
|
+
| "maxLength"
|
|
78
|
+
| "minLength"
|
|
79
|
+
| "disableMaxLength"
|
|
80
|
+
>,
|
|
81
|
+
TimeFieldConstraints {}
|
|
82
|
+
|
|
83
|
+
/** @since 6.3.0 */
|
|
84
|
+
export interface ProvidedTimeFieldProps
|
|
85
|
+
extends Omit<ProvidedTextFieldProps, "value">,
|
|
86
|
+
Omit<TimeFieldConstraints, "step"> {
|
|
87
|
+
type: "time";
|
|
88
|
+
step?: number | "any";
|
|
89
|
+
defaultValue: Required<InputHTMLAttributes<HTMLInputElement>>["defaultValue"];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** @since 6.3.0 */
|
|
93
|
+
export interface ProvidedTimeFieldMessageProps extends ProvidedTimeFieldProps {
|
|
94
|
+
/**
|
|
95
|
+
* These props will be defined as long as the `disableMessage` prop is not
|
|
96
|
+
* `true` from the `useTextField` hook.
|
|
97
|
+
*/
|
|
98
|
+
messageProps: ProvidedFormMessageProps;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** @since 6.3.0 */
|
|
102
|
+
export interface TimeFieldImplementation
|
|
103
|
+
extends Omit<TextFieldImplementation, "fieldProps"> {
|
|
104
|
+
fieldProps: ProvidedTimeFieldProps;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** @since 6.3.0 */
|
|
108
|
+
export interface TimeFieldWithMessageImplementation
|
|
109
|
+
extends Omit<TextFieldWithMessageImplementation, "fieldProps"> {
|
|
110
|
+
fieldProps: ProvidedTimeFieldMessageProps;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** @since 6.3.0 */
|
|
114
|
+
export interface ValidatedTimeFieldImplementation
|
|
115
|
+
extends TimeFieldImplementation {
|
|
116
|
+
fieldProps: ProvidedTimeFieldProps | ProvidedTimeFieldMessageProps;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @since 6.3.0
|
|
121
|
+
* @see {@link https://react-md.dev/components/native-time-field | NativeTimeField Demos}
|
|
122
|
+
* @see {@link https://react-md.dev/hooks/use-time-field | useTimeField Demos}
|
|
123
|
+
*/
|
|
124
|
+
export function useTimeField(
|
|
125
|
+
options: TimeFieldOptions & { disableMessage: true }
|
|
126
|
+
): TimeFieldImplementation;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The `useTimeField` is a small wrapper around the {@link useTextField} to be used
|
|
130
|
+
* with `<input type="time" />`. It is used in the `NativeTimeField` if an example
|
|
131
|
+
* implementation would like to be seen.
|
|
132
|
+
*
|
|
133
|
+
* @example Simple Example
|
|
134
|
+
* ```tsx
|
|
135
|
+
* import { useTimeField } from "@react-md/core/datetime/useTimeField";
|
|
136
|
+
* import { TextField } from "@react-md/core/form/TextField";
|
|
137
|
+
* import { type ReactElement } from "react";
|
|
138
|
+
*
|
|
139
|
+
* function Example(): ReactElement {
|
|
140
|
+
* const { value, fieldProps, error, errorMessage } = useTimeField({
|
|
141
|
+
* name: "appt",
|
|
142
|
+
* required: true,
|
|
143
|
+
* min: "08:00",
|
|
144
|
+
* max: "17:00",
|
|
145
|
+
* step: { minute: 15 },
|
|
146
|
+
* disableMessage: true,
|
|
147
|
+
* });
|
|
148
|
+
*
|
|
149
|
+
* // value: `""` or `"HH:mm"`
|
|
150
|
+
*
|
|
151
|
+
* return <TextField label="Appointment" {...fieldProps} />
|
|
152
|
+
* }
|
|
153
|
+
* ```
|
|
154
|
+
*
|
|
155
|
+
* @since 6.3.0
|
|
156
|
+
* @see {@link https://react-md.dev/components/native-time-field | NativeTimeField Demos}
|
|
157
|
+
* @see {@link https://react-md.dev/hooks/use-time-field | useTimeField Demos}
|
|
158
|
+
*/
|
|
159
|
+
export function useTimeField(
|
|
160
|
+
options: TimeFieldOptions
|
|
161
|
+
): TimeFieldWithMessageImplementation;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* The `useTimeField` is a small wrapper around the {@link useTextField} to be used
|
|
165
|
+
* with `<input type="time" />`. It is used in the `NativeTimeField` if an example
|
|
166
|
+
* implementation would like to be seen.
|
|
167
|
+
*
|
|
168
|
+
* @example Simple Example
|
|
169
|
+
* ```tsx
|
|
170
|
+
* import { useTimeField } from "@react-md/core/datetime/useTimeField";
|
|
171
|
+
* import { TextField } from "@react-md/core/form/TextField";
|
|
172
|
+
* import { type ReactElement } from "react";
|
|
173
|
+
*
|
|
174
|
+
* function Example(): ReactElement {
|
|
175
|
+
* const { value, fieldProps } = useTimeField({
|
|
176
|
+
* name: "appt",
|
|
177
|
+
* required: true,
|
|
178
|
+
* min: "08:00",
|
|
179
|
+
* max: "17:00",
|
|
180
|
+
* step: { minute: 15 },
|
|
181
|
+
* });
|
|
182
|
+
*
|
|
183
|
+
* // value: `""` or `"HH:mm"`
|
|
184
|
+
*
|
|
185
|
+
* return <TextField label="Appointment" {...fieldProps} />
|
|
186
|
+
* }
|
|
187
|
+
* ```
|
|
188
|
+
*
|
|
189
|
+
* @since 6.3.0
|
|
190
|
+
* @see {@link https://react-md.dev/components/native-time-field | NativeTimeField Demos}
|
|
191
|
+
* @see {@link https://react-md.dev/hooks/use-time-field | useTimeField Demos}
|
|
192
|
+
*/
|
|
193
|
+
export function useTimeField(
|
|
194
|
+
options: TimeFieldOptions
|
|
195
|
+
): ValidatedTimeFieldImplementation {
|
|
196
|
+
const { min, max, step, ...fieldOptions } = options;
|
|
197
|
+
if (
|
|
198
|
+
process.env.NODE_ENV !== "production" &&
|
|
199
|
+
typeof step !== "undefined" &&
|
|
200
|
+
(!min || !max)
|
|
201
|
+
) {
|
|
202
|
+
throw new Error(
|
|
203
|
+
"A `step` was provided to a time field without the `min` or `max` props."
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const { errorMessage, fieldProps, ...impl } = useTextField(fieldOptions);
|
|
208
|
+
|
|
209
|
+
// NOTE: Unlike the other text field components, the `value` should **not**
|
|
210
|
+
// be provided since the time input behaves a bit weirdly with the `onChange`
|
|
211
|
+
// event and it is better to rely on default browser behavior instead of
|
|
212
|
+
// controlling the value. The flow is:
|
|
213
|
+
// - user types `12:30`
|
|
214
|
+
// - `onChange` is fired with `12:30`
|
|
215
|
+
// - user selects `30` and hits backspace
|
|
216
|
+
// - `onChange` is fired with `""`
|
|
217
|
+
// If the `value` is set, the other time values would be lost
|
|
218
|
+
const { value, ...allowedFieldProps } = fieldProps;
|
|
219
|
+
const initial = useRef(value);
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
...impl,
|
|
223
|
+
errorMessage,
|
|
224
|
+
fieldProps: {
|
|
225
|
+
...allowedFieldProps,
|
|
226
|
+
defaultValue: initial.current,
|
|
227
|
+
min,
|
|
228
|
+
max,
|
|
229
|
+
step: getTimeStep(step),
|
|
230
|
+
type: "time",
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Since time input steps are based on seconds, this is a simple helper to
|
|
3
|
+
* create the step in a human-readable form.
|
|
4
|
+
*
|
|
5
|
+
* @since 6.3.0
|
|
6
|
+
*/
|
|
7
|
+
export interface TimeFieldStepOptions {
|
|
8
|
+
/**
|
|
9
|
+
* @defaultValue `0`
|
|
10
|
+
*/
|
|
11
|
+
seconds?: number;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @defaultValue `0`
|
|
15
|
+
*/
|
|
16
|
+
minutes?: number;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @defaultValue `0`
|
|
20
|
+
*/
|
|
21
|
+
hours?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Since time input steps are based on seconds, this is a simple helper to
|
|
26
|
+
* create the step in a human-readable form.
|
|
27
|
+
*
|
|
28
|
+
* @example Simple Example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* const step1 = getTimeStep({ minutes: 15 });
|
|
31
|
+
* const step2 = getTimeStep({ hours: 1 });
|
|
32
|
+
* const step3 = getTimeStep({ seconds: 15, minutes: 30, hours: 2 });
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @since 6.3.0
|
|
36
|
+
*/
|
|
37
|
+
export function getTimeStep(
|
|
38
|
+
step: TimeFieldStepOptions | "any" | number | undefined
|
|
39
|
+
): number | "any" | undefined {
|
|
40
|
+
if (!step || typeof step === "string" || typeof step === "number") {
|
|
41
|
+
return step;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const { hours = 0, minutes = 0, seconds = 0 } = step;
|
|
45
|
+
|
|
46
|
+
const total = Math.abs(Math.round(seconds + minutes * 60 + hours * 60 * 60));
|
|
47
|
+
return total === 0 ? undefined : total;
|
|
48
|
+
}
|
package/src/dialog/styles.ts
CHANGED
|
@@ -9,8 +9,6 @@ import { DISPLAY_NONE_CLASS } from "../utils/isElementVisible.js";
|
|
|
9
9
|
|
|
10
10
|
declare module "react" {
|
|
11
11
|
interface CSSProperties {
|
|
12
|
-
"--rmd-dialog-background-color"?: string;
|
|
13
|
-
"--rmd-dialog-color"?: string;
|
|
14
12
|
"--rmd-dialog-min-width"?: string | number;
|
|
15
13
|
"--rmd-dialog-horizontal-margin"?: string | number;
|
|
16
14
|
"--rmd-dialog-vertical-margin"?: string | number;
|
|
@@ -19,6 +17,11 @@ declare module "react" {
|
|
|
19
17
|
"--rmd-dialog-header-padding-bottom"?: string | number;
|
|
20
18
|
"--rmd-dialog-content-padding"?: string | number;
|
|
21
19
|
"--rmd-dialog-footer-padding"?: string | number;
|
|
20
|
+
"--rmd-dialog-width"?: string | number;
|
|
21
|
+
"--rmd-dialog-small-width"?: string | number;
|
|
22
|
+
"--rmd-dialog-medium-width"?: string | number;
|
|
23
|
+
"--rmd-dialog-large-width"?: string | number;
|
|
24
|
+
"--rmd-dialog-extra-large-width"?: string | number;
|
|
22
25
|
}
|
|
23
26
|
}
|
|
24
27
|
|
package/src/divider/styles.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { bem } from "../utils/bem.js";
|
|
|
5
5
|
declare module "react" {
|
|
6
6
|
interface CSSProperties {
|
|
7
7
|
"--rmd-divider-size"?: string | number;
|
|
8
|
-
"--rmd-divider-
|
|
8
|
+
"--rmd-divider-border-size"?: string | number;
|
|
9
9
|
"--rmd-divider-color"?: string;
|
|
10
10
|
"--rmd-divider-spacing"?: string | number;
|
|
11
11
|
"--rmd-divider-vertical-spacing"?: string | number;
|
package/src/draggable/utils.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type MouseEvent, type RefObject, type TouchEvent } from "react";
|
|
2
2
|
|
|
3
|
+
import { type MinMaxRange } from "../types.js";
|
|
3
4
|
import {
|
|
4
5
|
type ClientPositionEvent,
|
|
5
6
|
type ClientPositionOptions,
|
|
@@ -62,9 +63,7 @@ export const getDragPosition = (options: DragPositionOptions): number => {
|
|
|
62
63
|
/**
|
|
63
64
|
* @internal
|
|
64
65
|
*/
|
|
65
|
-
interface RelativeDragPositionOptions extends DragPositionOptions {
|
|
66
|
-
min: number;
|
|
67
|
-
max: number;
|
|
66
|
+
interface RelativeDragPositionOptions extends DragPositionOptions, MinMaxRange {
|
|
68
67
|
step: number;
|
|
69
68
|
rangeMin: number;
|
|
70
69
|
rangeMax: number;
|
|
@@ -218,9 +217,7 @@ export const updateDragPosition = (
|
|
|
218
217
|
* @internal
|
|
219
218
|
* @since 6.0.0
|
|
220
219
|
*/
|
|
221
|
-
export interface DeserializeDraggableValueOptions {
|
|
222
|
-
min: number;
|
|
223
|
-
max: number;
|
|
220
|
+
export interface DeserializeDraggableValueOptions extends MinMaxRange {
|
|
224
221
|
item: string;
|
|
225
222
|
}
|
|
226
223
|
|
|
@@ -29,6 +29,7 @@ export const ExpansionList = forwardRef<HTMLDivElement, ExpansionListProps>(
|
|
|
29
29
|
const { onClick, onFocus, onKeyDown, children, ...remaining } = props;
|
|
30
30
|
|
|
31
31
|
const { movementContext, movementProps } = useExpansionList({
|
|
32
|
+
ref,
|
|
32
33
|
onClick,
|
|
33
34
|
onFocus,
|
|
34
35
|
onKeyDown,
|
|
@@ -36,7 +37,7 @@ export const ExpansionList = forwardRef<HTMLDivElement, ExpansionListProps>(
|
|
|
36
37
|
|
|
37
38
|
return (
|
|
38
39
|
<KeyboardMovementProvider value={movementContext}>
|
|
39
|
-
<div {...remaining} {...movementProps}
|
|
40
|
+
<div {...remaining} {...movementProps}>
|
|
40
41
|
{children}
|
|
41
42
|
</div>
|
|
42
43
|
</KeyboardMovementProvider>
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from "react";
|
|
8
|
-
|
|
9
|
-
import type { KeyboardMovementProviderImplementation } from "../movement/types.js";
|
|
3
|
+
import {
|
|
4
|
+
type KeyboardMovementProviderImplementation,
|
|
5
|
+
type SimpleKeyboardMovementWrapperOptions,
|
|
6
|
+
} from "../movement/types.js";
|
|
10
7
|
import { useKeyboardMovementProvider } from "../movement/useKeyboardMovementProvider.js";
|
|
11
8
|
|
|
12
9
|
/**
|
|
@@ -18,11 +15,8 @@ const getPanelsOnly = (container: HTMLElement): readonly HTMLElement[] => [
|
|
|
18
15
|
];
|
|
19
16
|
|
|
20
17
|
/** @since 6.0.0 */
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
onFocus?: FocusEventHandler<E>;
|
|
24
|
-
onKeyDown?: KeyboardEventHandler<E>;
|
|
25
|
-
}
|
|
18
|
+
export type ExpansionListHookOptions<E extends HTMLElement> =
|
|
19
|
+
SimpleKeyboardMovementWrapperOptions<E>;
|
|
26
20
|
|
|
27
21
|
/** @since 6.0.0 */
|
|
28
22
|
export type ExpansionListImplementation<E extends HTMLElement> =
|
package/src/form/FormMessage.tsx
CHANGED
|
@@ -38,6 +38,8 @@ export const FormMessage = forwardRef<
|
|
|
38
38
|
children,
|
|
39
39
|
length,
|
|
40
40
|
maxLength,
|
|
41
|
+
counterProps,
|
|
42
|
+
messageProps,
|
|
41
43
|
...remaining
|
|
42
44
|
} = props;
|
|
43
45
|
const id = useEnsuredId(propId, "form-message");
|
|
@@ -48,6 +50,7 @@ export const FormMessage = forwardRef<
|
|
|
48
50
|
message = (
|
|
49
51
|
<p
|
|
50
52
|
id={`${id}-message`}
|
|
53
|
+
{...messageProps}
|
|
51
54
|
style={messageStyle}
|
|
52
55
|
className={formMessageText({ className: messageClassName })}
|
|
53
56
|
>
|
|
@@ -69,6 +72,7 @@ export const FormMessage = forwardRef<
|
|
|
69
72
|
{typeof length === "number" && typeof maxLength === "number" && (
|
|
70
73
|
<FormMessageCounter
|
|
71
74
|
id={`${id}-counter`}
|
|
75
|
+
{...counterProps}
|
|
72
76
|
style={counterStyle}
|
|
73
77
|
className={counterClassName}
|
|
74
78
|
>
|
|
@@ -2,14 +2,18 @@ import { type HTMLAttributes, forwardRef } from "react";
|
|
|
2
2
|
|
|
3
3
|
import { type PropsWithRef } from "../types.js";
|
|
4
4
|
import { FormMessage } from "./FormMessage.js";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
type FormMessageContainerClassNameOptions,
|
|
7
|
+
formMessageContainer,
|
|
8
|
+
} from "./formMessageContainerStyles.js";
|
|
6
9
|
import { type FormMessageProps } from "./types.js";
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
12
|
* @since 2.5.0
|
|
10
13
|
*/
|
|
11
14
|
export interface FormMessageContainerProps
|
|
12
|
-
extends HTMLAttributes<HTMLDivElement
|
|
15
|
+
extends HTMLAttributes<HTMLDivElement>,
|
|
16
|
+
FormMessageContainerClassNameOptions {
|
|
13
17
|
/**
|
|
14
18
|
* If the extension doesn't actually want to render the `FormMessage`
|
|
15
19
|
* component, these props are optional. It kind of eliminates the whole
|
|
@@ -29,7 +33,7 @@ export const FormMessageContainer = forwardRef<
|
|
|
29
33
|
HTMLDivElement,
|
|
30
34
|
FormMessageContainerProps
|
|
31
35
|
>(function FormMessageContainer(props, ref) {
|
|
32
|
-
const { className, children, messageProps, ...remaining } = props;
|
|
36
|
+
const { className, children, inline, messageProps, ...remaining } = props;
|
|
33
37
|
if (!messageProps) {
|
|
34
38
|
return <>{children}</>;
|
|
35
39
|
}
|
|
@@ -38,7 +42,7 @@ export const FormMessageContainer = forwardRef<
|
|
|
38
42
|
<div
|
|
39
43
|
{...remaining}
|
|
40
44
|
ref={ref}
|
|
41
|
-
className={formMessageContainer({ className })}
|
|
45
|
+
className={formMessageContainer({ className, inline })}
|
|
42
46
|
>
|
|
43
47
|
{children}
|
|
44
48
|
<FormMessage {...messageProps} />
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type HTMLAttributes,
|
|
3
|
+
type ReactElement,
|
|
4
|
+
type ReactNode,
|
|
5
|
+
forwardRef,
|
|
6
|
+
} from "react";
|
|
2
7
|
|
|
3
8
|
import { formMessageCounter } from "./formMessageStyles.js";
|
|
4
9
|
|
|
@@ -44,15 +49,21 @@ export interface FormMessageCounterProps
|
|
|
44
49
|
* @see {@link https://react-md.dev/components/form-message | FormMessage Demos}
|
|
45
50
|
* @see {@link https://react-md.dev/components/text-field | TextField Demos}
|
|
46
51
|
* @since 2.9.0
|
|
52
|
+
* @since 6.3.0 Supports refs.
|
|
47
53
|
*/
|
|
48
|
-
export
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
export const FormMessageCounter = forwardRef<
|
|
55
|
+
HTMLSpanElement,
|
|
56
|
+
FormMessageCounterProps
|
|
57
|
+
>(function FormMessageCounter(props, ref): ReactElement {
|
|
51
58
|
const { children, className, ...remaining } = props;
|
|
52
59
|
|
|
53
60
|
return (
|
|
54
|
-
<span
|
|
61
|
+
<span
|
|
62
|
+
ref={ref}
|
|
63
|
+
{...remaining}
|
|
64
|
+
className={formMessageCounter({ className })}
|
|
65
|
+
>
|
|
55
66
|
{children}
|
|
56
67
|
</span>
|
|
57
68
|
);
|
|
58
|
-
}
|
|
69
|
+
});
|
package/src/form/InputToggle.tsx
CHANGED
|
@@ -18,6 +18,8 @@ import { FormMessageContainer } from "./FormMessageContainer.js";
|
|
|
18
18
|
import { InputToggleIcon } from "./InputToggleIcon.js";
|
|
19
19
|
import { Label } from "./Label.js";
|
|
20
20
|
import { type InputToggleSize } from "./inputToggleStyles.js";
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
22
|
+
import { type LabelClassNameOptions } from "./types.js";
|
|
21
23
|
import {
|
|
22
24
|
type FormComponentStates,
|
|
23
25
|
type FormMessageContainerExtension,
|
package/src/form/Label.tsx
CHANGED
|
@@ -3,17 +3,6 @@ import { forwardRef } from "react";
|
|
|
3
3
|
import { label } from "./labelStyles.js";
|
|
4
4
|
import { type LabelProps } from "./types.js";
|
|
5
5
|
|
|
6
|
-
declare module "react" {
|
|
7
|
-
interface CSSProperties {
|
|
8
|
-
"--rmd-label-floating-x"?: string | number;
|
|
9
|
-
"--rmd-label-floating-y"?: string | number;
|
|
10
|
-
"--rmd-label-floating-active-x"?: string | number;
|
|
11
|
-
"--rmd-label-floating-active-y"?: string | number;
|
|
12
|
-
"--rmd-label-active-padding"?: string | number;
|
|
13
|
-
"--rmd-label-active-background-color"?: string;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
6
|
/**
|
|
18
7
|
* Most of the form components already use this `Label` internally when a
|
|
19
8
|
* `label` prop has been provided. You should generally use this component if
|
package/src/form/Listbox.tsx
CHANGED
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
type ReactNode,
|
|
5
|
-
type Ref,
|
|
6
|
-
useMemo,
|
|
7
|
-
} from "react";
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { type ReactElement, type ReactNode, type Ref } from "react";
|
|
8
4
|
|
|
9
5
|
import { Menu, type MenuProps } from "../menu/Menu.js";
|
|
10
6
|
import { type LabelRequiredForA11y } from "../types.js";
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
*/
|
|
18
|
-
export type ListboxValue = string | number | null | object;
|
|
7
|
+
import {
|
|
8
|
+
ListboxProvider,
|
|
9
|
+
type ListboxProviderOptions,
|
|
10
|
+
type ListboxValue,
|
|
11
|
+
useListboxProvider,
|
|
12
|
+
} from "./ListboxProvider.js";
|
|
19
13
|
|
|
20
14
|
/**
|
|
21
15
|
* @since 6.0.0
|
|
@@ -23,11 +17,8 @@ export type ListboxValue = string | number | null | object;
|
|
|
23
17
|
*/
|
|
24
18
|
export interface ListboxProps<Value extends ListboxValue>
|
|
25
19
|
extends MenuProps,
|
|
26
|
-
|
|
20
|
+
ListboxProviderOptions<Value> {
|
|
27
21
|
nodeRef?: Ref<HTMLDivElement>;
|
|
28
|
-
|
|
29
|
-
value: Value | readonly NonNullable<ListboxValue>[];
|
|
30
|
-
setValue: Dispatch<NonNullable<Value>>;
|
|
31
22
|
children: ReactNode;
|
|
32
23
|
}
|
|
33
24
|
|
|
@@ -49,36 +40,17 @@ export function Listbox<T extends ListboxValue>(
|
|
|
49
40
|
disableSelectedIcon,
|
|
50
41
|
...remaining
|
|
51
42
|
} = props;
|
|
52
|
-
const values = useMemo(() => {
|
|
53
|
-
if (Array.isArray(value)) {
|
|
54
|
-
return new Set(value);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return new Set([value]);
|
|
58
|
-
}, [value]);
|
|
59
43
|
|
|
60
44
|
return (
|
|
61
45
|
<ListboxProvider
|
|
62
|
-
value={
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
selectedIconAfter,
|
|
71
|
-
disableSelectedIcon,
|
|
72
|
-
}),
|
|
73
|
-
[
|
|
74
|
-
disableSelectedIcon,
|
|
75
|
-
selectedIcon,
|
|
76
|
-
selectedIconAfter,
|
|
77
|
-
setValue,
|
|
78
|
-
unselectedIcon,
|
|
79
|
-
values,
|
|
80
|
-
]
|
|
81
|
-
)}
|
|
46
|
+
value={useListboxProvider({
|
|
47
|
+
value,
|
|
48
|
+
setValue,
|
|
49
|
+
selectedIcon,
|
|
50
|
+
selectedIconAfter,
|
|
51
|
+
disableSelectedIcon,
|
|
52
|
+
unselectedIcon,
|
|
53
|
+
})}
|
|
82
54
|
>
|
|
83
55
|
<Menu {...remaining} ref={nodeRef}>
|
|
84
56
|
{children}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { createContext, useContext } from "react";
|
|
3
|
+
import { type Dispatch, createContext, useContext, useMemo } from "react";
|
|
4
4
|
|
|
5
5
|
import { type OptionSelectedIconProps } from "./Option.js";
|
|
6
6
|
|
|
@@ -37,3 +37,63 @@ export function useListboxContext(): ListboxContext {
|
|
|
37
37
|
|
|
38
38
|
return value;
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @since 6.0.0
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
export type ListboxValue = string | number | null | object;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @since 6.3.0
|
|
49
|
+
*/
|
|
50
|
+
export interface ListboxProviderOptions<Value extends ListboxValue>
|
|
51
|
+
extends OptionSelectedIconProps {
|
|
52
|
+
value: ListboxValue | readonly NonNullable<ListboxValue>[];
|
|
53
|
+
setValue: Dispatch<NonNullable<Value>>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @since 6.3.0
|
|
58
|
+
*/
|
|
59
|
+
export function useListboxProvider<Value extends ListboxValue>(
|
|
60
|
+
options: ListboxProviderOptions<Value>
|
|
61
|
+
): ListboxContext {
|
|
62
|
+
const {
|
|
63
|
+
value,
|
|
64
|
+
setValue,
|
|
65
|
+
selectedIconAfter,
|
|
66
|
+
selectedIcon,
|
|
67
|
+
unselectedIcon,
|
|
68
|
+
disableSelectedIcon,
|
|
69
|
+
} = options;
|
|
70
|
+
|
|
71
|
+
const values = useMemo(() => {
|
|
72
|
+
if (Array.isArray(value)) {
|
|
73
|
+
return new Set(value);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return new Set([value]);
|
|
77
|
+
}, [value]);
|
|
78
|
+
|
|
79
|
+
return useMemo(
|
|
80
|
+
() => ({
|
|
81
|
+
selectOption: setValue,
|
|
82
|
+
isOptionSelected(option) {
|
|
83
|
+
return values.has(option);
|
|
84
|
+
},
|
|
85
|
+
selectedIcon,
|
|
86
|
+
unselectedIcon,
|
|
87
|
+
selectedIconAfter,
|
|
88
|
+
disableSelectedIcon,
|
|
89
|
+
}),
|
|
90
|
+
[
|
|
91
|
+
disableSelectedIcon,
|
|
92
|
+
selectedIcon,
|
|
93
|
+
selectedIconAfter,
|
|
94
|
+
setValue,
|
|
95
|
+
unselectedIcon,
|
|
96
|
+
values,
|
|
97
|
+
]
|
|
98
|
+
);
|
|
99
|
+
}
|