@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
|
@@ -7,9 +7,9 @@ import { type GetErrorIcon, type GetErrorMessage, type IsErrored, type TextField
|
|
|
7
7
|
* @since 2.5.0
|
|
8
8
|
* @since 6.0.0 Added the `onInvalid` handler
|
|
9
9
|
*/
|
|
10
|
-
export type TextFieldChangeHandlers<E extends HTMLInputElement | HTMLTextAreaElement> = Pick<HTMLAttributes<E>, "onBlur" | "onChange" | "onInvalid">;
|
|
10
|
+
export type TextFieldChangeHandlers<E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement> = Pick<HTMLAttributes<E>, "onBlur" | "onChange" | "onInvalid">;
|
|
11
11
|
/** @since 6.0.0 */
|
|
12
|
-
export interface ErrorChangeHandlerOptions<E extends HTMLInputElement | HTMLTextAreaElement> {
|
|
12
|
+
export interface ErrorChangeHandlerOptions<E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement> {
|
|
13
13
|
/**
|
|
14
14
|
* A ref containing the `TextField` or `TextArea` if you need access to that
|
|
15
15
|
* DOM node for error reporting.
|
|
@@ -51,7 +51,7 @@ export interface ErrorChangeHandlerOptions<E extends HTMLInputElement | HTMLText
|
|
|
51
51
|
* @since 2.5.0
|
|
52
52
|
* @since 6.0.0 Changed to object argument.
|
|
53
53
|
*/
|
|
54
|
-
export type ErrorChangeHandler<E extends HTMLInputElement | HTMLTextAreaElement> = (options: ErrorChangeHandlerOptions<E>) => void;
|
|
54
|
+
export type ErrorChangeHandler<E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement> = (options: ErrorChangeHandlerOptions<E>) => void;
|
|
55
55
|
/** @since 2.5.6 */
|
|
56
56
|
export interface TextFieldHookState {
|
|
57
57
|
/**
|
|
@@ -83,7 +83,7 @@ export interface ProvidedFormMessageProps extends Pick<FormMessageProps, "id" |
|
|
|
83
83
|
*
|
|
84
84
|
* @since 2.5.0
|
|
85
85
|
*/
|
|
86
|
-
export interface ProvidedTextFieldProps<E extends HTMLInputElement | HTMLTextAreaElement> extends TextFieldValidationOptions, TextFieldChangeHandlers<E>, Required<Pick<TextFieldProps, "id" | "name" | "value" | "error">>, Pick<TextFieldProps, "aria-describedby" | "rightAddon"> {
|
|
86
|
+
export interface ProvidedTextFieldProps<E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement> extends TextFieldValidationOptions, TextFieldChangeHandlers<E>, Required<Pick<TextFieldProps, "id" | "name" | "value" | "error">>, Pick<TextFieldProps, "aria-describedby" | "rightAddon"> {
|
|
87
87
|
/**
|
|
88
88
|
* A ref that must be passed to the `TextField`/`TextArea` so that the custom
|
|
89
89
|
* validity behavior can work.
|
|
@@ -95,54 +95,33 @@ export interface ProvidedTextFieldProps<E extends HTMLInputElement | HTMLTextAre
|
|
|
95
95
|
/**
|
|
96
96
|
* @since 2.5.0
|
|
97
97
|
*/
|
|
98
|
-
export interface ProvidedTextFieldMessageProps<E extends HTMLInputElement | HTMLTextAreaElement> extends ProvidedTextFieldProps<E> {
|
|
98
|
+
export interface ProvidedTextFieldMessageProps<E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement> extends ProvidedTextFieldProps<E> {
|
|
99
99
|
/**
|
|
100
100
|
* These props will be defined as long as the `disableMessage` prop is not
|
|
101
101
|
* `true` from the `useTextField` hook.
|
|
102
102
|
*/
|
|
103
103
|
messageProps: ProvidedFormMessageProps;
|
|
104
104
|
}
|
|
105
|
-
/**
|
|
106
|
-
|
|
105
|
+
/**
|
|
106
|
+
* @since 6.3.0
|
|
107
|
+
*/
|
|
108
|
+
export interface TextFieldHookComponentOptions<E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement> {
|
|
107
109
|
/**
|
|
108
|
-
* An optional id to use for the `TextField` or `TextArea` that
|
|
109
|
-
* to create an id for the inline help/error messages.
|
|
110
|
+
* An optional id to use for the `TextField`, `Password`, or `TextArea` that
|
|
111
|
+
* is also used to create an id for the inline help/error messages.
|
|
110
112
|
*
|
|
111
113
|
* @defaultValue `"text-field-" + useId()`
|
|
112
114
|
*/
|
|
113
115
|
id?: string;
|
|
114
116
|
/**
|
|
115
|
-
*
|
|
116
|
-
* This should really only be used if you are making a custom component using
|
|
117
|
-
* this hook and forwarding refs. If you need a ref to access the `<input>` or
|
|
118
|
-
* `<textarea>` DOM node, you can use the `fieldRef` returned by this hook
|
|
119
|
-
* instead.
|
|
120
|
-
*
|
|
121
|
-
* @example Accessing TextField DOM Node
|
|
122
|
-
* ```tsx
|
|
123
|
-
* import { TextField } from "@react-md/core/form/TextField";
|
|
124
|
-
* import { useTextField } from "@react-md/core/form/useTextField";
|
|
125
|
-
* import { useEffect } from "react";
|
|
126
|
-
* import type { ReactElement } from "react";
|
|
127
|
-
*
|
|
128
|
-
* function Example(): ReactElement {
|
|
129
|
-
* const { fieldRef, fieldProps } = useTextField({ name: "example" });
|
|
130
|
-
*
|
|
131
|
-
* useEffect(() => {
|
|
132
|
-
* fieldRef.current;
|
|
133
|
-
* // ^ HTMLInputElement | null
|
|
134
|
-
* }, [fieldRef]);
|
|
135
|
-
*
|
|
136
|
-
* return <TextField {...fieldProps} label="Example" />;
|
|
137
|
-
* }
|
|
138
|
-
* ```
|
|
139
|
-
*/
|
|
140
|
-
ref?: Ref<E>;
|
|
141
|
-
/**
|
|
142
|
-
* A unique name to attach to the `TextField`, `TextArea` or `Password`
|
|
117
|
+
* A unique name to attach to the `TextField`, `TextArea`, or `Password`
|
|
143
118
|
* component.
|
|
144
119
|
*/
|
|
145
120
|
name: string;
|
|
121
|
+
/**
|
|
122
|
+
* @since 6.3.0
|
|
123
|
+
*/
|
|
124
|
+
form?: string;
|
|
146
125
|
/**
|
|
147
126
|
* Boolean if the `FormMessage` should also display a counter for the
|
|
148
127
|
* remaining letters allowed based on the `maxLength`.
|
|
@@ -153,23 +132,6 @@ export interface TextFieldHookOptions<E extends HTMLInputElement | HTMLTextAreaE
|
|
|
153
132
|
* @defaultValue `false`
|
|
154
133
|
*/
|
|
155
134
|
counter?: boolean;
|
|
156
|
-
/**
|
|
157
|
-
* This is used internally for the `useNumberField` hook and probably
|
|
158
|
-
* shouldn't be used otherwise. This is just passed into the
|
|
159
|
-
* {@link getErrorMessage} options and is used for additional validation.
|
|
160
|
-
*
|
|
161
|
-
* @defaultValue `false`
|
|
162
|
-
*/
|
|
163
|
-
isNumber?: boolean;
|
|
164
|
-
/**
|
|
165
|
-
* The default value to use for the `TextField` or `TextArea` one initial
|
|
166
|
-
* render. If you want to manually change the value to something else after
|
|
167
|
-
* the initial render, either change the `key` for the component containing
|
|
168
|
-
* this hook, or use the `setState` function returned from this hook.
|
|
169
|
-
*
|
|
170
|
-
* @defaultValue `""`
|
|
171
|
-
*/
|
|
172
|
-
defaultValue?: UseStateInitializer<string>;
|
|
173
135
|
/**
|
|
174
136
|
* An optional help text to display in the `FormMessage` component when there
|
|
175
137
|
* is not an error.
|
|
@@ -214,6 +176,14 @@ export interface TextFieldHookOptions<E extends HTMLInputElement | HTMLTextAreaE
|
|
|
214
176
|
* @defaultValue `() => {}`
|
|
215
177
|
*/
|
|
216
178
|
onErrorChange?: ErrorChangeHandler<E>;
|
|
179
|
+
/**
|
|
180
|
+
* Set to `true` to prevent the state from automatically resetting with a
|
|
181
|
+
* form's `reset` event.
|
|
182
|
+
*
|
|
183
|
+
* @defaultValue `false`
|
|
184
|
+
* @since 6.3.0
|
|
185
|
+
*/
|
|
186
|
+
disableReset?: boolean;
|
|
217
187
|
/**
|
|
218
188
|
* Set this to `true` to prevent the `errorMessage` from being
|
|
219
189
|
* rendered inline below the `TextField`.
|
|
@@ -238,19 +208,66 @@ export interface TextFieldHookOptions<E extends HTMLInputElement | HTMLTextAreaE
|
|
|
238
208
|
*/
|
|
239
209
|
validationType?: TextFieldValidationType;
|
|
240
210
|
}
|
|
211
|
+
/** @since 2.5.6 */
|
|
212
|
+
export interface TextFieldHookOptions<E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement> extends TextFieldValidationOptions, TextFieldHookComponentOptions<E>, TextFieldChangeHandlers<E> {
|
|
213
|
+
/**
|
|
214
|
+
* An optional ref that should be merged with the ref returned by this hook.
|
|
215
|
+
* This should really only be used if you are making a custom component using
|
|
216
|
+
* this hook and forwarding refs. If you need a ref to access the `<input>` or
|
|
217
|
+
* `<textarea>` DOM node, you can use the `fieldRef` returned by this hook
|
|
218
|
+
* instead.
|
|
219
|
+
*
|
|
220
|
+
* @example Accessing TextField DOM Node
|
|
221
|
+
* ```tsx
|
|
222
|
+
* import { TextField } from "@react-md/core/form/TextField";
|
|
223
|
+
* import { useTextField } from "@react-md/core/form/useTextField";
|
|
224
|
+
* import { useEffect } from "react";
|
|
225
|
+
* import type { ReactElement } from "react";
|
|
226
|
+
*
|
|
227
|
+
* function Example(): ReactElement {
|
|
228
|
+
* const { fieldRef, fieldProps } = useTextField({ name: "example" });
|
|
229
|
+
*
|
|
230
|
+
* useEffect(() => {
|
|
231
|
+
* fieldRef.current;
|
|
232
|
+
* // ^ HTMLInputElement | null
|
|
233
|
+
* }, [fieldRef]);
|
|
234
|
+
*
|
|
235
|
+
* return <TextField {...fieldProps} label="Example" />;
|
|
236
|
+
* }
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
ref?: Ref<E>;
|
|
240
|
+
/**
|
|
241
|
+
* This is used internally for the `useNumberField` hook and probably
|
|
242
|
+
* shouldn't be used otherwise. This is just passed into the
|
|
243
|
+
* {@link getErrorMessage} options and is used for additional validation.
|
|
244
|
+
*
|
|
245
|
+
* @defaultValue `false`
|
|
246
|
+
*/
|
|
247
|
+
isNumber?: boolean;
|
|
248
|
+
/**
|
|
249
|
+
* The default value to use for the `TextField` or `TextArea` one initial
|
|
250
|
+
* render. If you want to manually change the value to something else after
|
|
251
|
+
* the initial render, either change the `key` for the component containing
|
|
252
|
+
* this hook, or use the `setState` function returned from this hook.
|
|
253
|
+
*
|
|
254
|
+
* @defaultValue `""`
|
|
255
|
+
*/
|
|
256
|
+
defaultValue?: UseStateInitializer<string>;
|
|
257
|
+
}
|
|
241
258
|
/** @since 6.0.0 */
|
|
242
|
-
export interface TextFieldImplementation<E extends HTMLInputElement | HTMLTextAreaElement> extends TextFieldHookState {
|
|
259
|
+
export interface TextFieldImplementation<E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement> extends TextFieldHookState {
|
|
243
260
|
fieldRef: RefObject<E>;
|
|
244
261
|
reset: () => void;
|
|
245
262
|
setState: UseStateSetter<Readonly<TextFieldHookState>>;
|
|
246
263
|
fieldProps: ProvidedTextFieldProps<E>;
|
|
247
264
|
}
|
|
248
265
|
/** @since 6.0.0 */
|
|
249
|
-
export interface TextFieldWithMessageImplementation<E extends HTMLInputElement | HTMLTextAreaElement> extends TextFieldImplementation<E> {
|
|
266
|
+
export interface TextFieldWithMessageImplementation<E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement> extends TextFieldImplementation<E> {
|
|
250
267
|
fieldProps: ProvidedTextFieldMessageProps<E>;
|
|
251
268
|
}
|
|
252
269
|
/** @since 6.0.0 */
|
|
253
|
-
export interface ValidatedTextFieldImplementation<E extends HTMLInputElement | HTMLTextAreaElement> extends TextFieldImplementation<E> {
|
|
270
|
+
export interface ValidatedTextFieldImplementation<E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement> extends TextFieldImplementation<E> {
|
|
254
271
|
fieldProps: ProvidedTextFieldProps<E> | ProvidedTextFieldMessageProps<E>;
|
|
255
272
|
}
|
|
256
273
|
/**
|
|
@@ -278,7 +295,7 @@ export interface ValidatedTextFieldImplementation<E extends HTMLInputElement | H
|
|
|
278
295
|
* @see {@link https://react-md.dev/components/text-field | TextField Demos}
|
|
279
296
|
* @see {@link https://react-md.dev/hooks/use-text-field | useTextField Demos}
|
|
280
297
|
*/
|
|
281
|
-
export declare function useTextField<E extends HTMLInputElement | HTMLTextAreaElement>(options: TextFieldHookOptions<E> & {
|
|
298
|
+
export declare function useTextField<E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement>(options: TextFieldHookOptions<E> & {
|
|
282
299
|
disableMessage: true;
|
|
283
300
|
}): TextFieldImplementation<E>;
|
|
284
301
|
/**
|
|
@@ -393,4 +410,4 @@ export declare function useTextField<E extends HTMLInputElement | HTMLTextAreaEl
|
|
|
393
410
|
* added the ability to display an inline counter and help text while disabling
|
|
394
411
|
* the error messaging.
|
|
395
412
|
*/
|
|
396
|
-
export declare function useTextField<E extends HTMLInputElement | HTMLTextAreaElement>(options: TextFieldHookOptions<E>): TextFieldWithMessageImplementation<E>;
|
|
413
|
+
export declare function useTextField<E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement>(options: TextFieldHookOptions<E>): TextFieldWithMessageImplementation<E>;
|
|
@@ -3,6 +3,7 @@ import { useCallback, useRef, useState } from "react";
|
|
|
3
3
|
import { getIcon } from "../icon/config.js";
|
|
4
4
|
import { useEnsuredId } from "../useEnsuredId.js";
|
|
5
5
|
import { useEnsuredRef } from "../useEnsuredRef.js";
|
|
6
|
+
import { useFormReset } from "./useFormReset.js";
|
|
6
7
|
import { defaultGetErrorIcon, defaultGetErrorMessage, defaultIsErrored } from "./validation.js";
|
|
7
8
|
const noop = ()=>{
|
|
8
9
|
// do nothing
|
|
@@ -12,7 +13,7 @@ const noop = ()=>{
|
|
|
12
13
|
* @see {@link https://react-md.dev/hooks/use-text-field | useTextField Demos}
|
|
13
14
|
* @since 6.0.0
|
|
14
15
|
*/ export function useTextField(options) {
|
|
15
|
-
const { id: propId, ref: propRef, name, defaultValue = "", isNumber = false, required, pattern, minLength, maxLength, onBlur = noop, onChange = noop, onInvalid = noop, counter = false, helpText, validationType = "recommended", disableMessage = false, disableMaxLength = false, errorIcon: propErrorIcon, isErrored = defaultIsErrored, onErrorChange = noop, getErrorIcon = defaultGetErrorIcon, getErrorMessage = defaultGetErrorMessage } = options;
|
|
16
|
+
const { id: propId, ref: propRef, name, form, defaultValue = "", isNumber = false, required, pattern, minLength, maxLength, onBlur = noop, onChange = noop, onInvalid = noop, counter = false, helpText, disableReset, validationType = "recommended", disableMessage = false, disableMaxLength = false, errorIcon: propErrorIcon, isErrored = defaultIsErrored, onErrorChange = noop, getErrorIcon = defaultGetErrorIcon, getErrorMessage = defaultGetErrorMessage } = options;
|
|
16
17
|
const id = useEnsuredId(propId, "text-field");
|
|
17
18
|
const messageId = `${id}-message`;
|
|
18
19
|
const [fieldRef, ref] = useEnsuredRef(propRef);
|
|
@@ -179,6 +180,11 @@ const noop = ()=>{
|
|
|
179
180
|
children: !disableMessage && errorMessage || helpText
|
|
180
181
|
};
|
|
181
182
|
}
|
|
183
|
+
useFormReset({
|
|
184
|
+
form,
|
|
185
|
+
onReset: disableReset ? undefined : reset,
|
|
186
|
+
elementRef: fieldRef
|
|
187
|
+
});
|
|
182
188
|
return {
|
|
183
189
|
...state,
|
|
184
190
|
reset,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/form/useTextField.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type HTMLAttributes,\n type ReactNode,\n type Ref,\n type RefCallback,\n type RefObject,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\nimport { getIcon } from \"../icon/config.js\";\nimport { type UseStateInitializer, type UseStateSetter } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { type TextFieldProps } from \"./TextField.js\";\nimport {\n type FormMessageInputLengthCounterProps,\n type FormMessageProps,\n} from \"./types.js\";\nimport {\n type ErrorMessageOptions,\n type GetErrorIcon,\n type GetErrorMessage,\n type IsErrored,\n type TextFieldValidationOptions,\n type TextFieldValidationType,\n defaultGetErrorIcon,\n defaultGetErrorMessage,\n defaultIsErrored,\n} from \"./validation.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 2.5.0\n * @since 6.0.0 Added the `onInvalid` handler\n */\nexport type TextFieldChangeHandlers<\n E extends HTMLInputElement | HTMLTextAreaElement,\n> = Pick<HTMLAttributes<E>, \"onBlur\" | \"onChange\" | \"onInvalid\">;\n\n/** @since 6.0.0 */\nexport interface ErrorChangeHandlerOptions<\n E extends HTMLInputElement | HTMLTextAreaElement,\n> {\n /**\n * A ref containing the `TextField` or `TextArea` if you need access to that\n * DOM node for error reporting.\n */\n ref: RefObject<E>;\n\n /**\n * The current name for the `TextField` or `TextArea`.\n */\n name: string;\n\n /**\n * This will be `true` when the `TextField`/`TextArea` has an error.\n */\n error: boolean;\n\n /**\n * The error message returned by {@link GetErrorMessage}/the browser's\n * validation message. This is normally an empty string when the {@link error}\n * state is `false`.\n */\n errorMessage: string;\n}\n\n/**\n * A function that reports the error state changing. A good use-case for this is\n * to keep track of all the errors within your form and keep a submit button\n * disabled until they have been resolved.\n *\n * Example:\n *\n * ```ts\n * const [errors, setErrors] = useState<Record<string, boolean | undefined>>({});\n * const onErrorChange: ErrorChangeHandler = ({ name, error }) =>\n * setErrors((prevErrors) => ({ ...prevErrors, [name]: error }));\n *\n * const invalid = Object.values(errors).some(Boolean);\n *\n * // form implementation is left as an exercise for the reader\n * <Button type=\"submit\" disabled={invalid} onClick={submitForm}>Submit</Button>\n * ```\n *\n * @since 2.5.0\n * @since 6.0.0 Changed to object argument.\n */\nexport type ErrorChangeHandler<\n E extends HTMLInputElement | HTMLTextAreaElement,\n> = (options: ErrorChangeHandlerOptions<E>) => void;\n\n/** @since 2.5.6 */\nexport interface TextFieldHookState {\n /**\n * The current value for the `TextField` or `TextArea`.\n */\n value: string;\n\n /**\n * This will be `true` when the `TextField`/`TextArea` has an error.\n */\n error: boolean;\n\n /**\n * The error message returned by {@link GetErrorMessage}/the browser's\n * validation message. This is normally an empty string when the {@link error}\n * state is `false`.\n */\n errorMessage: string;\n}\n\n/**\n * All the props that will be generated and return from the `useTextField` hook\n * that should be passed to a `FormMessage` component.\n *\n * @since 2.5.0\n */\nexport interface ProvidedFormMessageProps\n extends Pick<FormMessageProps, \"id\" | \"theme\" | \"children\">,\n Required<Pick<TextFieldProps, \"error\">>,\n Partial<Pick<FormMessageInputLengthCounterProps, \"length\" | \"maxLength\">> {}\n\n/**\n * All the props that will be generated and returned by the `useTextField` hook\n * that should be passed to a `TextField` component.\n *\n * @since 2.5.0\n */\nexport interface ProvidedTextFieldProps<\n E extends HTMLInputElement | HTMLTextAreaElement,\n> extends TextFieldValidationOptions,\n TextFieldChangeHandlers<E>,\n Required<Pick<TextFieldProps, \"id\" | \"name\" | \"value\" | \"error\">>,\n Pick<TextFieldProps, \"aria-describedby\" | \"rightAddon\"> {\n /**\n * A ref that must be passed to the `TextField`/`TextArea` so that the custom\n * validity behavior can work.\n *\n * @since 6.0.0\n */\n ref: RefCallback<E>;\n}\n\n/**\n * @since 2.5.0\n */\nexport interface ProvidedTextFieldMessageProps<\n E extends HTMLInputElement | HTMLTextAreaElement,\n> extends ProvidedTextFieldProps<E> {\n /**\n * These props will be defined as long as the `disableMessage` prop is not\n * `true` from the `useTextField` hook.\n */\n messageProps: ProvidedFormMessageProps;\n}\n\n/** @since 2.5.6 */\nexport interface TextFieldHookOptions<\n E extends HTMLInputElement | HTMLTextAreaElement,\n> extends TextFieldValidationOptions,\n TextFieldChangeHandlers<E> {\n /**\n * An optional id to use for the `TextField` or `TextArea` that is also used\n * to create an id for the inline help/error messages.\n *\n * @defaultValue `\"text-field-\" + useId()`\n */\n id?: string;\n\n /**\n * An optional ref that should be merged with the ref returned by this hook.\n * This should really only be used if you are making a custom component using\n * this hook and forwarding refs. If you need a ref to access the `<input>` or\n * `<textarea>` DOM node, you can use the `fieldRef` returned by this hook\n * instead.\n *\n * @example Accessing TextField DOM Node\n * ```tsx\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { useTextField } from \"@react-md/core/form/useTextField\";\n * import { useEffect } from \"react\";\n * import type { ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { fieldRef, fieldProps } = useTextField({ name: \"example\" });\n *\n * useEffect(() => {\n * fieldRef.current;\n * // ^ HTMLInputElement | null\n * }, [fieldRef]);\n *\n * return <TextField {...fieldProps} label=\"Example\" />;\n * }\n * ```\n */\n ref?: Ref<E>;\n\n /**\n * A unique name to attach to the `TextField`, `TextArea` or `Password`\n * component.\n */\n name: string;\n\n /**\n * Boolean if the `FormMessage` should also display a counter for the\n * remaining letters allowed based on the `maxLength`.\n *\n * This will still be considered false if the `maxLength` value is not\n * provided.\n *\n * @defaultValue `false`\n */\n counter?: boolean;\n\n /**\n * This is used internally for the `useNumberField` hook and probably\n * shouldn't be used otherwise. This is just passed into the\n * {@link getErrorMessage} options and is used for additional validation.\n *\n * @defaultValue `false`\n */\n isNumber?: boolean;\n\n /**\n * The default value to use for the `TextField` or `TextArea` one initial\n * render. If you want to manually change the value to something else after\n * the initial render, either change the `key` for the component containing\n * this hook, or use the `setState` function returned from this hook.\n *\n * @defaultValue `\"\"`\n */\n defaultValue?: UseStateInitializer<string>;\n\n /**\n * An optional help text to display in the `FormMessage` component when there\n * is not an error.\n */\n helpText?: ReactNode;\n\n /**\n * A function used to determine if the `TextField` or `TextArea` is an in\n * errored state.\n *\n * @see {@link defaultIsErrored}\n * @defaultValue `defaultIsErrored`\n */\n isErrored?: IsErrored;\n\n /**\n * An optional error icon used in the {@link getErrorIcon} option.\n *\n * @defaultValue `getIcon(\"error\")`\n */\n errorIcon?: ReactNode;\n\n /**\n * A function used to get the error icon to display at the right of the\n * `TextField` or `TextArea`. The default behavior will only show an icon when\n * the `error` state is `true` and an `errorIcon` option has been provided.\n *\n * @see {@link defaultGetErrorIcon}\n * @defaultValue `defaultGetErrorIcon`\n */\n getErrorIcon?: GetErrorIcon;\n\n /**\n * A function to get and display an error message based on the `TextField` or\n * `TextArea` validity.\n *\n * @see {@link defaultGetErrorMessage}\n * @defaultValue `defaultGetErrorMessage`\n */\n getErrorMessage?: GetErrorMessage;\n\n /**\n * An optional function that will be called whenever the `error` state is\n * changed. This can be used for more complex forms to `disable` the Submit\n * button or anything else if any field has an error.\n *\n * @defaultValue `() => {}`\n */\n onErrorChange?: ErrorChangeHandler<E>;\n\n /**\n * Set this to `true` to prevent the `errorMessage` from being\n * rendered inline below the `TextField`.\n *\n * @defaultValue `false`\n * @since 6.0.0 Only disables the `errorMessage` behavior so\n * that counters and help text can still be rendered easily.\n */\n disableMessage?: boolean;\n\n /**\n * Boolean if the `maxLength` prop should not be passed to the `TextField`\n * component since it will prevent any additional characters from being\n * entered in the text field which might feel like weird behavior to some\n * users. This should really only be used when the `counter` option is also\n * enabled and rendering along with a `FormMessage` component.\n *\n * @defaultValue `false`\n */\n disableMaxLength?: boolean;\n\n /**\n * @defaultValue `\"recommended\"`\n */\n validationType?: TextFieldValidationType;\n}\n\n/** @since 6.0.0 */\nexport interface TextFieldImplementation<\n E extends HTMLInputElement | HTMLTextAreaElement,\n> extends TextFieldHookState {\n fieldRef: RefObject<E>;\n reset: () => void;\n setState: UseStateSetter<Readonly<TextFieldHookState>>;\n fieldProps: ProvidedTextFieldProps<E>;\n}\n\n/** @since 6.0.0 */\nexport interface TextFieldWithMessageImplementation<\n E extends HTMLInputElement | HTMLTextAreaElement,\n> extends TextFieldImplementation<E> {\n fieldProps: ProvidedTextFieldMessageProps<E>;\n}\n\n/** @since 6.0.0 */\nexport interface ValidatedTextFieldImplementation<\n E extends HTMLInputElement | HTMLTextAreaElement,\n> extends TextFieldImplementation<E> {\n fieldProps: ProvidedTextFieldProps<E> | ProvidedTextFieldMessageProps<E>;\n}\n\n/**\n * If you do not want to display the error messages below the `TextField` and\n * handle error messages separately, set the `disableMessage` option to `true`.\n *\n * @example No Inline Error Messages\n * ```tsx\n * import { type ReactElement } from \"react\";\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { useTextField } from \"@react-md/core/form/useTextField\";\n *\n * function Example(): ReactElement {\n * const { fieldProps } = useTextField({\n * name: \"example\",\n * disableMessage: true,\n * });\n *\n * return <TextField {...fieldProps} label=\"Example\" />;\n * }\n * ```\n *\n * Look at the other {@link useTextField} override for additional examples.\n *\n * @see {@link https://react-md.dev/components/text-field | TextField Demos}\n * @see {@link https://react-md.dev/hooks/use-text-field | useTextField Demos}\n */\nexport function useTextField<E extends HTMLInputElement | HTMLTextAreaElement>(\n options: TextFieldHookOptions<E> & { disableMessage: true }\n): TextFieldImplementation<E>;\n\n/**\n * @example Simple Example\n * ```tsx\n * import { type ReactElement } from \"react\";\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { useTextField } from \"@react-md/core/form/useTextField\";\n *\n * function Example(): ReactElement {\n * const { fieldProps } = useTextField({\n * name: \"example\",\n * });\n *\n * return <TextField {...fieldProps} label=\"Example\" />;\n * }\n * ```\n *\n * @example Inline Counter\n * ```tsx\n * import { type ReactElement } from \"react\";\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { useTextField } from \"@react-md/core/form/useTextField\";\n *\n * function Example(): ReactElement {\n * const { fieldProps } = useTextField({\n * name: \"example\",\n * counter: true,\n * required: true,\n * maxLength: 20,\n * // this allows the user to type beyond the max length limit and display\n * // an error message. omit or set to `false` to enforce the max length instead\n * disableMaxLength: true,\n * });\n *\n * return <TextField {...fieldProps} label=\"Example\" />;\n * }\n * ```\n *\n * @example Adding Constraints\n * ```tsx\n * import { type ReactElement } from \"react\";\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { useTextField } from \"@react-md/core/form/useTextField\";\n *\n * function Example(): ReactElement {\n * const { fieldProps } = useTextField({\n * name: \"example\",\n * required: true,\n * pattern: \"^[A-Za-z]+$\",\n * minLength: 4,\n * maxLength: 20,\n * });\n *\n * return <TextField {...fieldProps} label=\"Example\" />;\n * }\n * ```\n *\n * @example Custom Validation\n * ```tsx\n * import { type ReactElement } from \"react\";\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { useTextField } from \"@react-md/core/form/useTextField\";\n *\n * function Example(): ReactElement {\n * const { fieldProps } = useTextField({\n * name: \"example\",\n * required: true,\n * getErrorMessage(options) {\n * const {\n * value,\n * pattern,\n * required,\n * minLength,\n * maxLength,\n * validity,\n * validationMessage,\n * isNumber,\n * isBlurEvent,\n * validationType,\n * } = options;\n *\n * if (validity.tooLong) {\n * return `No more than ${maxLength} characters.`;\n * }\n *\n * if (validity.tooShort) {\n * return `No more than ${minLength} characters.`;\n * }\n *\n * if (validity.valueMissing) {\n * return \"This value is required!\";\n * }\n *\n * if (value === \"bad value\") {\n * return \"Value cannot be bad value\";\n * }\n *\n * return defaultGetErrorMessage(options);\n * }\n * });\n *\n * return <TextField {...fieldProps} label=\"Example\" />;\n * }\n * ```\n *\n * @see {@link https://react-md.dev/components/text-field | TextField Demos}\n * @see {@link https://react-md.dev/hooks/use-text-field | useTextField Demos}\n * @see https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation\n * @since 2.5.6\n * @since 6.0.0 This hook returns an object instead of an ordered list. Also\n * added the ability to display an inline counter and help text while disabling\n * the error messaging.\n */\nexport function useTextField<E extends HTMLInputElement | HTMLTextAreaElement>(\n options: TextFieldHookOptions<E>\n): TextFieldWithMessageImplementation<E>;\n/**\n * @see {@link https://react-md.dev/components/text-field | TextField Demos}\n * @see {@link https://react-md.dev/hooks/use-text-field | useTextField Demos}\n * @since 6.0.0\n */\nexport function useTextField<E extends HTMLInputElement | HTMLTextAreaElement>(\n options: TextFieldHookOptions<E>\n): ValidatedTextFieldImplementation<E> {\n const {\n id: propId,\n ref: propRef,\n name,\n defaultValue = \"\",\n isNumber = false,\n required,\n pattern,\n minLength,\n maxLength,\n onBlur = noop,\n onChange = noop,\n onInvalid = noop,\n counter = false,\n helpText,\n validationType = \"recommended\",\n disableMessage = false,\n disableMaxLength = false,\n errorIcon: propErrorIcon,\n isErrored = defaultIsErrored,\n onErrorChange = noop,\n getErrorIcon = defaultGetErrorIcon,\n getErrorMessage = defaultGetErrorMessage,\n } = options;\n\n const id = useEnsuredId(propId, \"text-field\");\n const messageId = `${id}-message`;\n const [fieldRef, ref] = useEnsuredRef(propRef);\n const [state, setState] = useState<TextFieldHookState>(() => {\n const value =\n typeof defaultValue === \"function\" ? defaultValue() : defaultValue;\n\n return {\n value,\n error: false,\n errorMessage: \"\",\n };\n });\n const { value, error, errorMessage } = state;\n\n // using a `ref` instead of a `useCallback` makes it so the `defaultValue`\n // will always be used once reset.\n const reset = useRef(() => {\n fieldRef.current?.setCustomValidity(\"\");\n setState({ value, error: false, errorMessage: \"\" });\n }).current;\n\n const errored = useRef(error);\n const checkValidity = useCallback(\n (isBlurEvent: boolean) => {\n const field = fieldRef.current;\n if (!field) {\n throw new Error(\"Unable to check validity due to missing ref\");\n }\n\n // need to temporarily set the `maxLength` back so it can be \"verified\"\n // through the validity api\n /* istanbul ignore next */\n if (isBlurEvent && disableMaxLength && typeof maxLength === \"number\") {\n field.maxLength = maxLength;\n }\n\n const { value } = field;\n field.setCustomValidity(\"\");\n field.checkValidity();\n\n // remove the temporarily set `maxLength` attribute after checking the\n // validity\n /* istanbul ignore next */\n if (disableMaxLength && typeof maxLength === \"number\") {\n field.removeAttribute(\"maxLength\");\n }\n\n const options: ErrorMessageOptions = {\n value,\n pattern,\n required,\n minLength,\n maxLength,\n isBlurEvent,\n isNumber,\n validationType,\n validity: field.validity,\n validationMessage: field.validationMessage,\n };\n const errorMessage = getErrorMessage(options);\n const error = isErrored({ ...options, errorMessage });\n\n if (errored.current !== error) {\n errored.current = error;\n onErrorChange({\n ref: fieldRef,\n name,\n error,\n errorMessage,\n });\n }\n\n /* istanbul ignore next */\n if (errorMessage !== field.validationMessage) {\n field.setCustomValidity(errorMessage);\n }\n\n setState((prevState) => {\n if (\n prevState.value === value &&\n prevState.error === error &&\n prevState.errorMessage === errorMessage\n ) {\n return prevState;\n }\n\n return {\n value,\n error,\n errorMessage,\n };\n });\n },\n [\n disableMaxLength,\n fieldRef,\n getErrorMessage,\n isErrored,\n isNumber,\n maxLength,\n minLength,\n name,\n onErrorChange,\n pattern,\n required,\n validationType,\n ]\n );\n\n const errorIcon = getIcon(\"error\", propErrorIcon);\n const fieldProps: ProvidedTextFieldProps<E> & {\n messageProps?: ProvidedFormMessageProps;\n } = {\n id,\n ref,\n name,\n value,\n error,\n required,\n pattern,\n minLength,\n maxLength: disableMaxLength ? undefined : maxLength,\n rightAddon: getErrorIcon({\n error,\n errorIcon,\n errorMessage,\n }),\n onBlur(event) {\n onBlur(event);\n if (event.isPropagationStopped()) {\n return;\n }\n\n checkValidity(true);\n },\n onChange(event) {\n onChange(event);\n if (event.isPropagationStopped()) {\n return;\n }\n\n if (validationType === \"blur\") {\n const { value } = event.currentTarget;\n setState((prevState) => ({\n ...prevState,\n value,\n }));\n return;\n }\n\n checkValidity(false);\n },\n onInvalid(event) {\n onInvalid(event);\n if (\n event.isPropagationStopped() ||\n event.currentTarget === document.activeElement\n ) {\n return;\n }\n\n // this makes it so that if a submit button is clicked in a form, all\n // textfields will gain the error state immediately\n // also need to extract the validationMessage immediately because of the\n // SyntheticEvent behavior in React. By the time the `setState` is called,\n // the event might've been deleted\n const { validationMessage } = event.currentTarget;\n\n setState((prevState) => {\n if (prevState.error) {\n return prevState;\n }\n\n return {\n ...prevState,\n error: true,\n errorMessage: validationMessage,\n };\n });\n },\n };\n\n const isCounter = counter && typeof maxLength === \"number\";\n if (isCounter || helpText || !disableMessage) {\n fieldProps[\"aria-describedby\"] = messageId;\n fieldProps.messageProps = {\n id: messageId,\n error,\n length: counter ? value.length : undefined,\n maxLength: (counter && maxLength) || undefined,\n children: (!disableMessage && errorMessage) || helpText,\n };\n }\n\n return {\n ...state,\n reset,\n setState,\n fieldRef,\n fieldProps,\n };\n}\n"],"names":["useCallback","useRef","useState","getIcon","useEnsuredId","useEnsuredRef","defaultGetErrorIcon","defaultGetErrorMessage","defaultIsErrored","noop","useTextField","options","id","propId","ref","propRef","name","defaultValue","isNumber","required","pattern","minLength","maxLength","onBlur","onChange","onInvalid","counter","helpText","validationType","disableMessage","disableMaxLength","errorIcon","propErrorIcon","isErrored","onErrorChange","getErrorIcon","getErrorMessage","messageId","fieldRef","state","setState","value","error","errorMessage","reset","current","setCustomValidity","errored","checkValidity","isBlurEvent","field","Error","removeAttribute","validity","validationMessage","prevState","fieldProps","undefined","rightAddon","event","isPropagationStopped","currentTarget","document","activeElement","isCounter","messageProps","length","children"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/form/useTextField.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type HTMLAttributes,\n type ReactNode,\n type Ref,\n type RefCallback,\n type RefObject,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\nimport { getIcon } from \"../icon/config.js\";\nimport { type UseStateInitializer, type UseStateSetter } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { useEnsuredRef } from \"../useEnsuredRef.js\";\nimport { type TextFieldProps } from \"./TextField.js\";\nimport {\n type FormMessageInputLengthCounterProps,\n type FormMessageProps,\n} from \"./types.js\";\nimport { useFormReset } from \"./useFormReset.js\";\nimport {\n type ErrorMessageOptions,\n type GetErrorIcon,\n type GetErrorMessage,\n type IsErrored,\n type TextFieldValidationOptions,\n type TextFieldValidationType,\n defaultGetErrorIcon,\n defaultGetErrorMessage,\n defaultIsErrored,\n} from \"./validation.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 2.5.0\n * @since 6.0.0 Added the `onInvalid` handler\n */\nexport type TextFieldChangeHandlers<\n E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement,\n> = Pick<HTMLAttributes<E>, \"onBlur\" | \"onChange\" | \"onInvalid\">;\n\n/** @since 6.0.0 */\nexport interface ErrorChangeHandlerOptions<\n E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement,\n> {\n /**\n * A ref containing the `TextField` or `TextArea` if you need access to that\n * DOM node for error reporting.\n */\n ref: RefObject<E>;\n\n /**\n * The current name for the `TextField` or `TextArea`.\n */\n name: string;\n\n /**\n * This will be `true` when the `TextField`/`TextArea` has an error.\n */\n error: boolean;\n\n /**\n * The error message returned by {@link GetErrorMessage}/the browser's\n * validation message. This is normally an empty string when the {@link error}\n * state is `false`.\n */\n errorMessage: string;\n}\n\n/**\n * A function that reports the error state changing. A good use-case for this is\n * to keep track of all the errors within your form and keep a submit button\n * disabled until they have been resolved.\n *\n * Example:\n *\n * ```ts\n * const [errors, setErrors] = useState<Record<string, boolean | undefined>>({});\n * const onErrorChange: ErrorChangeHandler = ({ name, error }) =>\n * setErrors((prevErrors) => ({ ...prevErrors, [name]: error }));\n *\n * const invalid = Object.values(errors).some(Boolean);\n *\n * // form implementation is left as an exercise for the reader\n * <Button type=\"submit\" disabled={invalid} onClick={submitForm}>Submit</Button>\n * ```\n *\n * @since 2.5.0\n * @since 6.0.0 Changed to object argument.\n */\nexport type ErrorChangeHandler<\n E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement,\n> = (options: ErrorChangeHandlerOptions<E>) => void;\n\n/** @since 2.5.6 */\nexport interface TextFieldHookState {\n /**\n * The current value for the `TextField` or `TextArea`.\n */\n value: string;\n\n /**\n * This will be `true` when the `TextField`/`TextArea` has an error.\n */\n error: boolean;\n\n /**\n * The error message returned by {@link GetErrorMessage}/the browser's\n * validation message. This is normally an empty string when the {@link error}\n * state is `false`.\n */\n errorMessage: string;\n}\n\n/**\n * All the props that will be generated and return from the `useTextField` hook\n * that should be passed to a `FormMessage` component.\n *\n * @since 2.5.0\n */\nexport interface ProvidedFormMessageProps\n extends Pick<FormMessageProps, \"id\" | \"theme\" | \"children\">,\n Required<Pick<TextFieldProps, \"error\">>,\n Partial<Pick<FormMessageInputLengthCounterProps, \"length\" | \"maxLength\">> {}\n\n/**\n * All the props that will be generated and returned by the `useTextField` hook\n * that should be passed to a `TextField` component.\n *\n * @since 2.5.0\n */\nexport interface ProvidedTextFieldProps<\n E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement,\n> extends TextFieldValidationOptions,\n TextFieldChangeHandlers<E>,\n Required<Pick<TextFieldProps, \"id\" | \"name\" | \"value\" | \"error\">>,\n Pick<TextFieldProps, \"aria-describedby\" | \"rightAddon\"> {\n /**\n * A ref that must be passed to the `TextField`/`TextArea` so that the custom\n * validity behavior can work.\n *\n * @since 6.0.0\n */\n ref: RefCallback<E>;\n}\n\n/**\n * @since 2.5.0\n */\nexport interface ProvidedTextFieldMessageProps<\n E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement,\n> extends ProvidedTextFieldProps<E> {\n /**\n * These props will be defined as long as the `disableMessage` prop is not\n * `true` from the `useTextField` hook.\n */\n messageProps: ProvidedFormMessageProps;\n}\n\n/**\n * @since 6.3.0\n */\nexport interface TextFieldHookComponentOptions<\n E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement,\n> {\n /**\n * An optional id to use for the `TextField`, `Password`, or `TextArea` that\n * is also used to create an id for the inline help/error messages.\n *\n * @defaultValue `\"text-field-\" + useId()`\n */\n id?: string;\n\n /**\n * A unique name to attach to the `TextField`, `TextArea`, or `Password`\n * component.\n */\n name: string;\n\n /**\n * @since 6.3.0\n */\n form?: string;\n\n /**\n * Boolean if the `FormMessage` should also display a counter for the\n * remaining letters allowed based on the `maxLength`.\n *\n * This will still be considered false if the `maxLength` value is not\n * provided.\n *\n * @defaultValue `false`\n */\n counter?: boolean;\n\n /**\n * An optional help text to display in the `FormMessage` component when there\n * is not an error.\n */\n helpText?: ReactNode;\n\n /**\n * A function used to determine if the `TextField` or `TextArea` is an in\n * errored state.\n *\n * @see {@link defaultIsErrored}\n * @defaultValue `defaultIsErrored`\n */\n isErrored?: IsErrored;\n\n /**\n * An optional error icon used in the {@link getErrorIcon} option.\n *\n * @defaultValue `getIcon(\"error\")`\n */\n errorIcon?: ReactNode;\n\n /**\n * A function used to get the error icon to display at the right of the\n * `TextField` or `TextArea`. The default behavior will only show an icon when\n * the `error` state is `true` and an `errorIcon` option has been provided.\n *\n * @see {@link defaultGetErrorIcon}\n * @defaultValue `defaultGetErrorIcon`\n */\n getErrorIcon?: GetErrorIcon;\n\n /**\n * A function to get and display an error message based on the `TextField` or\n * `TextArea` validity.\n *\n * @see {@link defaultGetErrorMessage}\n * @defaultValue `defaultGetErrorMessage`\n */\n getErrorMessage?: GetErrorMessage;\n\n /**\n * An optional function that will be called whenever the `error` state is\n * changed. This can be used for more complex forms to `disable` the Submit\n * button or anything else if any field has an error.\n *\n * @defaultValue `() => {}`\n */\n onErrorChange?: ErrorChangeHandler<E>;\n\n /**\n * Set to `true` to prevent the state from automatically resetting with a\n * form's `reset` event.\n *\n * @defaultValue `false`\n * @since 6.3.0\n */\n disableReset?: boolean;\n\n /**\n * Set this to `true` to prevent the `errorMessage` from being\n * rendered inline below the `TextField`.\n *\n * @defaultValue `false`\n * @since 6.0.0 Only disables the `errorMessage` behavior so\n * that counters and help text can still be rendered easily.\n */\n disableMessage?: boolean;\n\n /**\n * Boolean if the `maxLength` prop should not be passed to the `TextField`\n * component since it will prevent any additional characters from being\n * entered in the text field which might feel like weird behavior to some\n * users. This should really only be used when the `counter` option is also\n * enabled and rendering along with a `FormMessage` component.\n *\n * @defaultValue `false`\n */\n disableMaxLength?: boolean;\n\n /**\n * @defaultValue `\"recommended\"`\n */\n validationType?: TextFieldValidationType;\n}\n\n/** @since 2.5.6 */\nexport interface TextFieldHookOptions<\n E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement,\n> extends TextFieldValidationOptions,\n TextFieldHookComponentOptions<E>,\n TextFieldChangeHandlers<E> {\n /**\n * An optional ref that should be merged with the ref returned by this hook.\n * This should really only be used if you are making a custom component using\n * this hook and forwarding refs. If you need a ref to access the `<input>` or\n * `<textarea>` DOM node, you can use the `fieldRef` returned by this hook\n * instead.\n *\n * @example Accessing TextField DOM Node\n * ```tsx\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { useTextField } from \"@react-md/core/form/useTextField\";\n * import { useEffect } from \"react\";\n * import type { ReactElement } from \"react\";\n *\n * function Example(): ReactElement {\n * const { fieldRef, fieldProps } = useTextField({ name: \"example\" });\n *\n * useEffect(() => {\n * fieldRef.current;\n * // ^ HTMLInputElement | null\n * }, [fieldRef]);\n *\n * return <TextField {...fieldProps} label=\"Example\" />;\n * }\n * ```\n */\n ref?: Ref<E>;\n\n /**\n * This is used internally for the `useNumberField` hook and probably\n * shouldn't be used otherwise. This is just passed into the\n * {@link getErrorMessage} options and is used for additional validation.\n *\n * @defaultValue `false`\n */\n isNumber?: boolean;\n\n /**\n * The default value to use for the `TextField` or `TextArea` one initial\n * render. If you want to manually change the value to something else after\n * the initial render, either change the `key` for the component containing\n * this hook, or use the `setState` function returned from this hook.\n *\n * @defaultValue `\"\"`\n */\n defaultValue?: UseStateInitializer<string>;\n}\n\n/** @since 6.0.0 */\nexport interface TextFieldImplementation<\n E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement,\n> extends TextFieldHookState {\n fieldRef: RefObject<E>;\n reset: () => void;\n setState: UseStateSetter<Readonly<TextFieldHookState>>;\n fieldProps: ProvidedTextFieldProps<E>;\n}\n\n/** @since 6.0.0 */\nexport interface TextFieldWithMessageImplementation<\n E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement,\n> extends TextFieldImplementation<E> {\n fieldProps: ProvidedTextFieldMessageProps<E>;\n}\n\n/** @since 6.0.0 */\nexport interface ValidatedTextFieldImplementation<\n E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement,\n> extends TextFieldImplementation<E> {\n fieldProps: ProvidedTextFieldProps<E> | ProvidedTextFieldMessageProps<E>;\n}\n\n/**\n * If you do not want to display the error messages below the `TextField` and\n * handle error messages separately, set the `disableMessage` option to `true`.\n *\n * @example No Inline Error Messages\n * ```tsx\n * import { type ReactElement } from \"react\";\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { useTextField } from \"@react-md/core/form/useTextField\";\n *\n * function Example(): ReactElement {\n * const { fieldProps } = useTextField({\n * name: \"example\",\n * disableMessage: true,\n * });\n *\n * return <TextField {...fieldProps} label=\"Example\" />;\n * }\n * ```\n *\n * Look at the other {@link useTextField} override for additional examples.\n *\n * @see {@link https://react-md.dev/components/text-field | TextField Demos}\n * @see {@link https://react-md.dev/hooks/use-text-field | useTextField Demos}\n */\nexport function useTextField<\n E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement,\n>(\n options: TextFieldHookOptions<E> & { disableMessage: true }\n): TextFieldImplementation<E>;\n\n/**\n * @example Simple Example\n * ```tsx\n * import { type ReactElement } from \"react\";\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { useTextField } from \"@react-md/core/form/useTextField\";\n *\n * function Example(): ReactElement {\n * const { fieldProps } = useTextField({\n * name: \"example\",\n * });\n *\n * return <TextField {...fieldProps} label=\"Example\" />;\n * }\n * ```\n *\n * @example Inline Counter\n * ```tsx\n * import { type ReactElement } from \"react\";\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { useTextField } from \"@react-md/core/form/useTextField\";\n *\n * function Example(): ReactElement {\n * const { fieldProps } = useTextField({\n * name: \"example\",\n * counter: true,\n * required: true,\n * maxLength: 20,\n * // this allows the user to type beyond the max length limit and display\n * // an error message. omit or set to `false` to enforce the max length instead\n * disableMaxLength: true,\n * });\n *\n * return <TextField {...fieldProps} label=\"Example\" />;\n * }\n * ```\n *\n * @example Adding Constraints\n * ```tsx\n * import { type ReactElement } from \"react\";\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { useTextField } from \"@react-md/core/form/useTextField\";\n *\n * function Example(): ReactElement {\n * const { fieldProps } = useTextField({\n * name: \"example\",\n * required: true,\n * pattern: \"^[A-Za-z]+$\",\n * minLength: 4,\n * maxLength: 20,\n * });\n *\n * return <TextField {...fieldProps} label=\"Example\" />;\n * }\n * ```\n *\n * @example Custom Validation\n * ```tsx\n * import { type ReactElement } from \"react\";\n * import { TextField } from \"@react-md/core/form/TextField\";\n * import { useTextField } from \"@react-md/core/form/useTextField\";\n *\n * function Example(): ReactElement {\n * const { fieldProps } = useTextField({\n * name: \"example\",\n * required: true,\n * getErrorMessage(options) {\n * const {\n * value,\n * pattern,\n * required,\n * minLength,\n * maxLength,\n * validity,\n * validationMessage,\n * isNumber,\n * isBlurEvent,\n * validationType,\n * } = options;\n *\n * if (validity.tooLong) {\n * return `No more than ${maxLength} characters.`;\n * }\n *\n * if (validity.tooShort) {\n * return `No more than ${minLength} characters.`;\n * }\n *\n * if (validity.valueMissing) {\n * return \"This value is required!\";\n * }\n *\n * if (value === \"bad value\") {\n * return \"Value cannot be bad value\";\n * }\n *\n * return defaultGetErrorMessage(options);\n * }\n * });\n *\n * return <TextField {...fieldProps} label=\"Example\" />;\n * }\n * ```\n *\n * @see {@link https://react-md.dev/components/text-field | TextField Demos}\n * @see {@link https://react-md.dev/hooks/use-text-field | useTextField Demos}\n * @see https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation\n * @since 2.5.6\n * @since 6.0.0 This hook returns an object instead of an ordered list. Also\n * added the ability to display an inline counter and help text while disabling\n * the error messaging.\n */\nexport function useTextField<\n E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement,\n>(options: TextFieldHookOptions<E>): TextFieldWithMessageImplementation<E>;\n/**\n * @see {@link https://react-md.dev/components/text-field | TextField Demos}\n * @see {@link https://react-md.dev/hooks/use-text-field | useTextField Demos}\n * @since 6.0.0\n */\nexport function useTextField<\n E extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement,\n>(options: TextFieldHookOptions<E>): ValidatedTextFieldImplementation<E> {\n const {\n id: propId,\n ref: propRef,\n name,\n form,\n defaultValue = \"\",\n isNumber = false,\n required,\n pattern,\n minLength,\n maxLength,\n onBlur = noop,\n onChange = noop,\n onInvalid = noop,\n counter = false,\n helpText,\n disableReset,\n validationType = \"recommended\",\n disableMessage = false,\n disableMaxLength = false,\n errorIcon: propErrorIcon,\n isErrored = defaultIsErrored,\n onErrorChange = noop,\n getErrorIcon = defaultGetErrorIcon,\n getErrorMessage = defaultGetErrorMessage,\n } = options;\n\n const id = useEnsuredId(propId, \"text-field\");\n const messageId = `${id}-message`;\n const [fieldRef, ref] = useEnsuredRef(propRef);\n const [state, setState] = useState<TextFieldHookState>(() => {\n const value =\n typeof defaultValue === \"function\" ? defaultValue() : defaultValue;\n\n return {\n value,\n error: false,\n errorMessage: \"\",\n };\n });\n const { value, error, errorMessage } = state;\n\n // using a `ref` instead of a `useCallback` makes it so the `defaultValue`\n // will always be used once reset.\n const reset = useRef(() => {\n fieldRef.current?.setCustomValidity(\"\");\n setState({ value, error: false, errorMessage: \"\" });\n }).current;\n\n const errored = useRef(error);\n const checkValidity = useCallback(\n (isBlurEvent: boolean) => {\n const field = fieldRef.current;\n if (!field) {\n throw new Error(\"Unable to check validity due to missing ref\");\n }\n\n // need to temporarily set the `maxLength` back so it can be \"verified\"\n // through the validity api\n /* istanbul ignore next */\n if (isBlurEvent && disableMaxLength && typeof maxLength === \"number\") {\n field.maxLength = maxLength;\n }\n\n const { value } = field;\n field.setCustomValidity(\"\");\n field.checkValidity();\n\n // remove the temporarily set `maxLength` attribute after checking the\n // validity\n /* istanbul ignore next */\n if (disableMaxLength && typeof maxLength === \"number\") {\n field.removeAttribute(\"maxLength\");\n }\n\n const options: ErrorMessageOptions = {\n value,\n pattern,\n required,\n minLength,\n maxLength,\n isBlurEvent,\n isNumber,\n validationType,\n validity: field.validity,\n validationMessage: field.validationMessage,\n };\n const errorMessage = getErrorMessage(options);\n const error = isErrored({ ...options, errorMessage });\n\n if (errored.current !== error) {\n errored.current = error;\n onErrorChange({\n ref: fieldRef,\n name,\n error,\n errorMessage,\n });\n }\n\n /* istanbul ignore next */\n if (errorMessage !== field.validationMessage) {\n field.setCustomValidity(errorMessage);\n }\n\n setState((prevState) => {\n if (\n prevState.value === value &&\n prevState.error === error &&\n prevState.errorMessage === errorMessage\n ) {\n return prevState;\n }\n\n return {\n value,\n error,\n errorMessage,\n };\n });\n },\n [\n disableMaxLength,\n fieldRef,\n getErrorMessage,\n isErrored,\n isNumber,\n maxLength,\n minLength,\n name,\n onErrorChange,\n pattern,\n required,\n validationType,\n ]\n );\n\n const errorIcon = getIcon(\"error\", propErrorIcon);\n const fieldProps: ProvidedTextFieldProps<E> & {\n messageProps?: ProvidedFormMessageProps;\n } = {\n id,\n ref,\n name,\n value,\n error,\n required,\n pattern,\n minLength,\n maxLength: disableMaxLength ? undefined : maxLength,\n rightAddon: getErrorIcon({\n error,\n errorIcon,\n errorMessage,\n }),\n onBlur(event) {\n onBlur(event);\n if (event.isPropagationStopped()) {\n return;\n }\n\n checkValidity(true);\n },\n onChange(event) {\n onChange(event);\n if (event.isPropagationStopped()) {\n return;\n }\n\n if (validationType === \"blur\") {\n const { value } = event.currentTarget;\n setState((prevState) => ({\n ...prevState,\n value,\n }));\n return;\n }\n\n checkValidity(false);\n },\n onInvalid(event) {\n onInvalid(event);\n if (\n event.isPropagationStopped() ||\n event.currentTarget === document.activeElement\n ) {\n return;\n }\n\n // this makes it so that if a submit button is clicked in a form, all\n // textfields will gain the error state immediately\n // also need to extract the validationMessage immediately because of the\n // SyntheticEvent behavior in React. By the time the `setState` is called,\n // the event might've been deleted\n const { validationMessage } = event.currentTarget;\n\n setState((prevState) => {\n if (prevState.error) {\n return prevState;\n }\n\n return {\n ...prevState,\n error: true,\n errorMessage: validationMessage,\n };\n });\n },\n };\n\n const isCounter = counter && typeof maxLength === \"number\";\n if (isCounter || helpText || !disableMessage) {\n fieldProps[\"aria-describedby\"] = messageId;\n fieldProps.messageProps = {\n id: messageId,\n error,\n length: counter ? value.length : undefined,\n maxLength: (counter && maxLength) || undefined,\n children: (!disableMessage && errorMessage) || helpText,\n };\n }\n\n useFormReset({\n form,\n onReset: disableReset ? undefined : reset,\n elementRef: fieldRef,\n });\n\n return {\n ...state,\n reset,\n setState,\n fieldRef,\n fieldProps,\n };\n}\n"],"names":["useCallback","useRef","useState","getIcon","useEnsuredId","useEnsuredRef","useFormReset","defaultGetErrorIcon","defaultGetErrorMessage","defaultIsErrored","noop","useTextField","options","id","propId","ref","propRef","name","form","defaultValue","isNumber","required","pattern","minLength","maxLength","onBlur","onChange","onInvalid","counter","helpText","disableReset","validationType","disableMessage","disableMaxLength","errorIcon","propErrorIcon","isErrored","onErrorChange","getErrorIcon","getErrorMessage","messageId","fieldRef","state","setState","value","error","errorMessage","reset","current","setCustomValidity","errored","checkValidity","isBlurEvent","field","Error","removeAttribute","validity","validationMessage","prevState","fieldProps","undefined","rightAddon","event","isPropagationStopped","currentTarget","document","activeElement","isCounter","messageProps","length","children","onReset","elementRef"],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { DragEventHandler, FocusEventHandler, KeyboardEventHandler, MouseEventHandler, TouchEventHandler } from "react";
|
|
2
2
|
declare module "react" {
|
|
3
3
|
interface CSSProperties {
|
|
4
|
-
"--rmd-ripple-background-color"?: string;
|
|
5
4
|
"--rmd-interaction-background-color"?: string;
|
|
6
5
|
"--rmd-hover-background-color"?: string;
|
|
7
6
|
"--rmd-focus-background-color"?: string;
|
|
@@ -9,6 +8,11 @@ declare module "react" {
|
|
|
9
8
|
"--rmd-selected-background-color"?: string;
|
|
10
9
|
"--rmd-focus-color"?: string;
|
|
11
10
|
"--rmd-focus-width"?: string | number;
|
|
11
|
+
"--rmd-ripple-inset"?: string | number;
|
|
12
|
+
"--rmd-ripple-border-radius"?: string | number;
|
|
13
|
+
"--rmd-ripple-background-color"?: string;
|
|
14
|
+
"--rmd-surface-inset"?: string | number;
|
|
15
|
+
"--rmd-surface-border-radius"?: string | number;
|
|
12
16
|
}
|
|
13
17
|
}
|
|
14
18
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/interaction/types.ts"],"sourcesContent":["import type {\n DragEventHandler,\n FocusEventHandler,\n KeyboardEventHandler,\n MouseEventHandler,\n TouchEventHandler,\n} from \"react\";\n\ndeclare module \"react\" {\n interface CSSProperties {\n \"--rmd-
|
|
1
|
+
{"version":3,"sources":["../../src/interaction/types.ts"],"sourcesContent":["import type {\n DragEventHandler,\n FocusEventHandler,\n KeyboardEventHandler,\n MouseEventHandler,\n TouchEventHandler,\n} from \"react\";\n\ndeclare module \"react\" {\n interface CSSProperties {\n \"--rmd-interaction-background-color\"?: string;\n \"--rmd-hover-background-color\"?: string;\n \"--rmd-focus-background-color\"?: string;\n \"--rmd-press-background-color\"?: string;\n \"--rmd-selected-background-color\"?: string;\n \"--rmd-focus-color\"?: string;\n \"--rmd-focus-width\"?: string | number;\n \"--rmd-ripple-inset\"?: string | number;\n \"--rmd-ripple-border-radius\"?: string | number;\n \"--rmd-ripple-background-color\"?: string;\n \"--rmd-surface-inset\"?: string | number;\n \"--rmd-surface-border-radius\"?: string | number;\n }\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ComponentWithRippleProps {\n /**\n * Set this to `true` to disable the ripple behavior for this single component\n * only. If all components should have the ripple disabled:\n *\n * ```ts\n * INTERACTION_CONFIG.mode = \"none\";\n * // or\n * INTERACTION_CONFIG.mode = \"press\";\n * ```\n *\n * @defaultValue `false`\n */\n disableRipple?: boolean;\n}\n\n/**\n * This is used to provide feedback to the user that they are interacting with\n * elements on the page. It is recommended to not set this to `\"none\"` unless\n * you will implement your own version.\n *\n * When this is set to `\"press\"`, the `background-color` for the element will\n * become slightly darker while the user:\n * - is holding the mouse down on the element\n * - holding the enter or space key on the element\n * - holding their finger on the element for touch devices\n *\n * The `background-color` will transition in and out based on the pressed state.\n *\n * When this is set to `\"ripple\"`, a water droplet type of animation will appear\n * from the current coordinates of the mouse or touch event within the element.\n * Keyboard events will just trigger the animation from the center of the\n * element. Once the user stops pressing the element, the animation will start\n * to fade out.\n *\n * Note: this should match the `$interaction-mode` SCSS variable.\n *\n * @defaultValue `\"ripple\"`\n * @since 6.0.0\n */\nexport type ElementInteractionMode = \"ripple\" | \"press\" | \"none\";\n\n/** @since 6.0.0 */\nexport interface ElementInteractionHandlers<E extends HTMLElement> {\n onBlur: FocusEventHandler<E>;\n\n /**\n * The click event handler is is only used to display a ripple for\n * `<button type=\"submit\" />` since pressing enter on form elements should\n * submit the form. This ripple is really just to help show that the form has\n * been submitted.\n */\n onClick: MouseEventHandler<E>;\n\n /**\n * The keydown event handler is used to either activate the `pressed` state\n * for the element or start the ripple animation when the `enter` or `space`\n * keys are pressed. It will also trigger a click event for elements that do\n * not support this natively (`<button>`, `<a>`).\n *\n * When the space key is pressed, `event.preventDefault()` will also be called\n * to prevent the page from scrolling.\n */\n onKeyDown: KeyboardEventHandler<E>;\n\n /**\n * The keyup event handler is used to either deactivate the `pressed` state\n * for the element or start the exit animation for the ripple if the ripple\n * was activated by the keydown event.\n */\n onKeyUp: KeyboardEventHandler<E>;\n\n /**\n * The mousedown event handler is used to either activate the `pressed` state\n * for the element or start the ripple animation.\n */\n onMouseDown: MouseEventHandler<E>;\n\n /**\n * The mouseup event handler is used to either deactivate the `pressed` state\n * for the element or start the exit animation for the ripple if the ripple\n * was activated by the mousedown event.\n */\n onMouseUp: MouseEventHandler<E>;\n\n /**\n * The mouseleave event handler will remove all ripples and prevent any other\n * interactions if the current {@link UserInteractionMode} is `\"mouse\"`.\n *\n * The ripples have to be cancelled since the user might release the mouse\n * outside of the element which would never trigger the `onMouseUp` flow.\n */\n onMouseLeave: MouseEventHandler<E>;\n\n /**\n * The dragstart event handler will remove the ripples and prevent any other\n * interactions.\n */\n onDragStart: DragEventHandler<E>;\n\n /**\n * The touchstart event handler is used to either activate the `pressed` state\n * for the element or start the ripple animation.\n */\n onTouchStart: TouchEventHandler<E>;\n\n /**\n * The touchend event handler is used to either deactivate the `pressed`\n * state for the element or start the exit animation for the ripple if the\n * ripple was activated by the touchstart event.\n */\n onTouchEnd: TouchEventHandler<E>;\n\n /**\n * The touchmove event handler will remove all ripples and prevent any other\n * interactions if the current {@link UserInteractionMode} is `\"touch\"`.\n */\n onTouchMove: TouchEventHandler<E>;\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport interface RippleStyle {\n readonly left: number;\n readonly top: number;\n readonly height: number;\n readonly width: number;\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport interface RippleState {\n readonly style: RippleStyle;\n readonly exiting: boolean;\n readonly entered: boolean;\n readonly startTime: number;\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport type RippleStateList = readonly RippleState[];\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport interface RippleTransitionCallbacks {\n onEntered: (ripple: RippleState) => void;\n onExited: (ripple: RippleState) => void;\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport interface ProvidedRippleContainerProps\n extends RippleTransitionCallbacks {\n ripples: RippleStateList;\n}\n\n/**\n * @since 6.0.0\n * @internal\n */\nexport interface ElementInteractionState {\n pressed: boolean;\n ripples: RippleStateList;\n}\n"],"names":[],"mappings":"AAkMA;;;CAGC,GACD,WAGC"}
|
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
import { type KeyboardEvent, type MouseEvent, type TouchEvent } from "react";
|
|
2
|
+
import { type Point } from "../types.js";
|
|
2
3
|
import { type ElementInteractionState, type RippleState, type RippleStyle } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* @internal
|
|
6
|
+
* @since 6.3.0
|
|
7
|
+
*/
|
|
8
|
+
interface GetRadiusOptions extends Point {
|
|
9
|
+
height: number;
|
|
10
|
+
width: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* @internal
|
|
14
|
+
* @since 6.3.0
|
|
15
|
+
*/
|
|
16
|
+
export declare function getRadius(options: GetRadiusOptions): number;
|
|
3
17
|
/** @internal */
|
|
4
18
|
export declare function getRippleStyle(event: MouseEvent<HTMLElement> | TouchEvent<HTMLElement> | KeyboardEvent<HTMLElement>, programmatic: boolean): RippleStyle;
|
|
5
19
|
/** @internal */
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import { findSizingContainer } from "../positioning/utils.js";
|
|
2
|
-
|
|
3
|
-
return Math.sqrt(a * a + b * b);
|
|
4
|
-
}
|
|
2
|
+
import { calcHypotenuse } from "../utils/trigonometry.js";
|
|
5
3
|
/**
|
|
6
|
-
* Gets the current radius for a ripple based on the x and y page dimensions
|
|
7
|
-
* as well as the size of the element.
|
|
8
|
-
*
|
|
9
|
-
* This is really just in a separate file so I can easily mock this and write
|
|
10
|
-
* tests.
|
|
11
|
-
*
|
|
12
4
|
* @internal
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
* @since 6.3.0
|
|
6
|
+
*/ export function getRadius(options) {
|
|
7
|
+
const { x, y, height, width } = options;
|
|
8
|
+
return Math.max(calcHypotenuse({
|
|
9
|
+
x,
|
|
10
|
+
y
|
|
11
|
+
}), calcHypotenuse({
|
|
12
|
+
x: width - x,
|
|
13
|
+
y
|
|
14
|
+
}), calcHypotenuse({
|
|
15
|
+
x: width - x,
|
|
16
|
+
y: height - y
|
|
17
|
+
}), calcHypotenuse({
|
|
18
|
+
x,
|
|
19
|
+
y: height - y
|
|
20
|
+
}));
|
|
15
21
|
}
|
|
16
22
|
/** @internal */ export function getRippleStyle(event, programmatic) {
|
|
17
23
|
const element = findSizingContainer(event.currentTarget) || event.currentTarget;
|
|
@@ -33,7 +39,12 @@ import { findSizingContainer } from "../positioning/utils.js";
|
|
|
33
39
|
x = pageX - (left + window.scrollX);
|
|
34
40
|
y = pageY - (top + window.scrollY);
|
|
35
41
|
}
|
|
36
|
-
const radius = getRadius(
|
|
42
|
+
const radius = getRadius({
|
|
43
|
+
x,
|
|
44
|
+
y,
|
|
45
|
+
width,
|
|
46
|
+
height
|
|
47
|
+
});
|
|
37
48
|
const size = radius * 2;
|
|
38
49
|
return {
|
|
39
50
|
left: x - radius,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/interaction/utils.ts"],"sourcesContent":["import { type KeyboardEvent, type MouseEvent, type TouchEvent } from \"react\";\n\nimport { findSizingContainer } from \"../positioning/utils.js\";\nimport {\n type ElementInteractionState,\n type RippleState,\n type RippleStyle,\n} from \"./types.js\";\n\n
|
|
1
|
+
{"version":3,"sources":["../../src/interaction/utils.ts"],"sourcesContent":["import { type KeyboardEvent, type MouseEvent, type TouchEvent } from \"react\";\n\nimport { findSizingContainer } from \"../positioning/utils.js\";\nimport { type Point } from \"../types.js\";\nimport { calcHypotenuse } from \"../utils/trigonometry.js\";\nimport {\n type ElementInteractionState,\n type RippleState,\n type RippleStyle,\n} from \"./types.js\";\n\n/**\n * @internal\n * @since 6.3.0\n */\ninterface GetRadiusOptions extends Point {\n height: number;\n width: number;\n}\n\n/**\n * @internal\n * @since 6.3.0\n */\nexport function getRadius(options: GetRadiusOptions): number {\n const { x, y, height, width } = options;\n\n return Math.max(\n calcHypotenuse({ x, y }),\n calcHypotenuse({ x: width - x, y }),\n calcHypotenuse({ x: width - x, y: height - y }),\n calcHypotenuse({ x, y: height - y })\n );\n}\n\n/** @internal */\nexport function getRippleStyle(\n event:\n | MouseEvent<HTMLElement>\n | TouchEvent<HTMLElement>\n | KeyboardEvent<HTMLElement>,\n programmatic: boolean\n): RippleStyle {\n const element =\n findSizingContainer(event.currentTarget) || event.currentTarget;\n const rect = element.getBoundingClientRect();\n const { left, top, height, width } = rect;\n\n let x: number;\n let y: number;\n if (\"key\" in event || programmatic) {\n x = width / 2;\n y = height / 2;\n } else {\n let pageX: number;\n let pageY: number;\n if (\"touches\" in event) {\n ({ pageX, pageY } = event.touches[0]);\n } else {\n ({ pageX, pageY } = event);\n }\n\n x = pageX - (left + window.scrollX);\n y = pageY - (top + window.scrollY);\n }\n\n const radius = getRadius({ x, y, width, height });\n const size = radius * 2;\n\n return {\n left: x - radius,\n top: y - radius,\n height: size,\n width: size,\n };\n}\n\n/**\n * This is used to set the `exiting` state after a normal \"touch\" duration.\n * 300ms seemed like a good threshold since it is the majority of the scaling\n * duration (450ms)\n */\nconst ENTER_DELAY = 300;\n\n/** @internal */\nexport function releaseRipple(\n state: ElementInteractionState\n): ElementInteractionState {\n // find the first non-exiting ripple which should now be released\n const i = state.ripples.findIndex((ripple) => !ripple.exiting);\n if (i === -1) {\n return state;\n }\n\n const ripples = state.ripples.slice();\n const ripple = ripples[i];\n ripples[i] = {\n ...ripple,\n exiting: ripple.entered || Date.now() - ripple.startTime > ENTER_DELAY,\n };\n return { pressed: false, ripples };\n}\n\n/** @internal */\ninterface UpdateRipplesStateOptions {\n type: \"entered\" | \"exited\";\n state: ElementInteractionState;\n ripple: RippleState;\n holding: boolean;\n}\n\n/** @internal */\nexport function updateRipplesState(\n options: UpdateRipplesStateOptions\n): ElementInteractionState {\n const { type, ripple, state, holding } = options;\n\n const rippleIndex = state.ripples.findIndex((r) => r === ripple);\n if (rippleIndex === -1) {\n return state;\n }\n\n const ripples = state.ripples.slice();\n if (type === \"exited\") {\n ripples.splice(rippleIndex, 1);\n } else {\n const exiting = !holding || Date.now() - ripple.startTime > ENTER_DELAY;\n ripples[rippleIndex] = {\n ...ripple,\n exiting,\n entered: true,\n };\n }\n\n return { ...state, ripples };\n}\n"],"names":["findSizingContainer","calcHypotenuse","getRadius","options","x","y","height","width","Math","max","getRippleStyle","event","programmatic","element","currentTarget","rect","getBoundingClientRect","left","top","pageX","pageY","touches","window","scrollX","scrollY","radius","size","ENTER_DELAY","releaseRipple","state","i","ripples","findIndex","ripple","exiting","slice","entered","Date","now","startTime","pressed","updateRipplesState","type","holding","rippleIndex","r","splice"],"mappings":"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"}
|
package/dist/link/Link.d.ts
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
import { type AnchorHTMLAttributes, type ForwardRefExoticComponent } from "react";
|
|
2
2
|
import { type LinkClassNameOptions } from "./styles.js";
|
|
3
|
-
declare module "react" {
|
|
4
|
-
interface CSSProperties {
|
|
5
|
-
"--rmd-link-color"?: string;
|
|
6
|
-
"--rmd-link-visited-color"?: string;
|
|
7
|
-
"--rmd-link-hover-color"?: string;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
3
|
/**
|
|
11
4
|
* @since 6.0.0
|
|
12
5
|
*/
|
package/dist/link/Link.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/link/Link.tsx"],"sourcesContent":["import {\n type AnchorHTMLAttributes,\n type ForwardRefExoticComponent,\n forwardRef,\n} from \"react\";\n\nimport { type LinkClassNameOptions, link } from \"./styles.js\";\n\
|
|
1
|
+
{"version":3,"sources":["../../src/link/Link.tsx"],"sourcesContent":["import {\n type AnchorHTMLAttributes,\n type ForwardRefExoticComponent,\n forwardRef,\n} from \"react\";\n\nimport { type LinkClassNameOptions, link } from \"./styles.js\";\n\n/**\n * @since 6.0.0\n */\nexport type CustomLinkComponent =\n | ForwardRefExoticComponent<{ href: string }>\n | ForwardRefExoticComponent<{ to: string }>\n | \"a\";\n\n/**\n * @since 6.0.0 Removed the `preventMaliciousTarget` prop since browsers\n * default to `rel=noopener` after updating the {@link https://github.com/whatwg/html/issues/4078|spec}.\n * @since 6.0.0 Removed the `component` prop since all you need for link\n * behavior is `className=\"rmd-link\"`.\n * @since 6.0.0 The `href` prop is required.\n * @since 6.0.0 Renamed `flexCentered` to `flex`.\n */\nexport interface LinkProps\n extends AnchorHTMLAttributes<HTMLAnchorElement>,\n LinkClassNameOptions {\n /**\n * All links **must** have a valid href.\n */\n href: string;\n\n /**\n * Set this to `true` if your link contains icons that should be centered and\n * spaced with additional text. This is not used by default so that links can\n * correctly line wrap while rendered within paragraphs of text.\n *\n * @defaultValue `false`\n */\n flex?: boolean;\n}\n\n/**\n * @example Simple Example\n * ```tsx\n * import { Link } from \"@react-md/core/link/Link\";\n * import { Typography } from \"@react-md/core/typography/Typography\";\n * import type { ReactElement } from \"react\";\n *\n * function Element(): ReactElement {\n * return (\n * <Typography>\n * Here is a paragraph of text with a {\" \"}\n * <Link href=\"/some-url\">link to some content</Link>.\n * </Typography>\n * );\n * }\n * ```\n *\n *\n * @see {@link https://react-md.dev/components/link | Link Demos}\n * @since 6.0.0 Removed the `preventMaliciousTarget` prop since browsers\n * default to `rel=noopener` after updating the {@link https://github.com/whatwg/html/issues/4078|spec}.\n * @since 6.0.0 Removed the `component` prop since all you need for link\n * behavior is `className=\"rmd-link\"`.\n * @since 6.0.0 The `href` prop is required.\n * @since 6.0.0 Renamed `flexCentered` to `flex`.\n */\nexport const Link = forwardRef<HTMLAnchorElement, LinkProps>(\n function Link(props, ref) {\n const { className, flex, children, ...remaining } = props;\n\n return (\n <a {...remaining} ref={ref} className={link({ flex, className })}>\n {children}\n </a>\n );\n }\n);\n"],"names":["forwardRef","link","Link","props","ref","className","flex","children","remaining","a"],"mappings":";AAAA,SAGEA,UAAU,QACL,QAAQ;AAEf,SAAoCC,IAAI,QAAQ,cAAc;AAoC9D;;;;;;;;;;;;;;;;;;;;;;;;;CAyBC,GACD,OAAO,MAAMC,qBAAOF,WAClB,SAASE,KAAKC,KAAK,EAAEC,GAAG;IACtB,MAAM,EAAEC,SAAS,EAAEC,IAAI,EAAEC,QAAQ,EAAE,GAAGC,WAAW,GAAGL;IAEpD,qBACE,KAACM;QAAG,GAAGD,SAAS;QAAEJ,KAAKA;QAAKC,WAAWJ,KAAK;YAAEK;YAAMD;QAAU;kBAC3DE;;AAGP,GACA"}
|
package/dist/link/styles.d.ts
CHANGED
package/dist/link/styles.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/link/styles.ts"],"sourcesContent":["import { cnb } from \"cnbuilder\";\n\nimport { bem } from \"../utils/bem.js\";\n\nconst styles = bem(\"rmd-link\");\n\n/** @since 6.0.0 */\nexport interface LinkClassNameOptions {\n className?: string;\n\n /** @defaultValue `false` */\n flex?: boolean;\n}\n\n/**\n * This really doesn't do much at this time since it only merges `rmd-link` with\n * the optional className. This was mostly added just for convention purposes.\n *\n * @since 6.0.0\n */\nexport function link(options: LinkClassNameOptions = {}): string {\n const { flex, className } = options;\n\n return cnb(styles({ flex }), className);\n}\n\n/** @since 6.0.0 */\nexport interface SkipToMainContentClassNameOptions {\n className?: string;\n\n /**\n * @defaultValue `false`\n */\n unstyled?: boolean;\n}\n\n/**\n * @since 6.0.0\n */\nexport function skipToMainContent(\n options: SkipToMainContentClassNameOptions = {}\n): string {\n const { unstyled = false, className } = options;\n\n return cnb(\n styles({\n skip: true,\n \"skip-styled\": !unstyled,\n }),\n className\n );\n}\n"],"names":["cnb","bem","styles","link","options","flex","className","skipToMainContent","unstyled","skip"],"mappings":"AAAA,SAASA,GAAG,QAAQ,YAAY;AAEhC,SAASC,GAAG,QAAQ,kBAAkB;AAEtC,MAAMC,SAASD,IAAI;
|
|
1
|
+
{"version":3,"sources":["../../src/link/styles.ts"],"sourcesContent":["import { cnb } from \"cnbuilder\";\n\nimport { bem } from \"../utils/bem.js\";\n\nconst styles = bem(\"rmd-link\");\n\ndeclare module \"react\" {\n interface CSSProperties {\n \"--rmd-link-color\"?: string;\n \"--rmd-link-visited-color\"?: string;\n \"--rmd-link-hover-color\"?: string;\n }\n}\n\n/** @since 6.0.0 */\nexport interface LinkClassNameOptions {\n className?: string;\n\n /** @defaultValue `false` */\n flex?: boolean;\n}\n\n/**\n * This really doesn't do much at this time since it only merges `rmd-link` with\n * the optional className. This was mostly added just for convention purposes.\n *\n * @since 6.0.0\n */\nexport function link(options: LinkClassNameOptions = {}): string {\n const { flex, className } = options;\n\n return cnb(styles({ flex }), className);\n}\n\n/** @since 6.0.0 */\nexport interface SkipToMainContentClassNameOptions {\n className?: string;\n\n /**\n * @defaultValue `false`\n */\n unstyled?: boolean;\n}\n\n/**\n * @since 6.0.0\n */\nexport function skipToMainContent(\n options: SkipToMainContentClassNameOptions = {}\n): string {\n const { unstyled = false, className } = options;\n\n return cnb(\n styles({\n skip: true,\n \"skip-styled\": !unstyled,\n }),\n className\n );\n}\n"],"names":["cnb","bem","styles","link","options","flex","className","skipToMainContent","unstyled","skip"],"mappings":"AAAA,SAASA,GAAG,QAAQ,YAAY;AAEhC,SAASC,GAAG,QAAQ,kBAAkB;AAEtC,MAAMC,SAASD,IAAI;AAkBnB;;;;;CAKC,GACD,OAAO,SAASE,KAAKC,UAAgC,CAAC,CAAC;IACrD,MAAM,EAAEC,IAAI,EAAEC,SAAS,EAAE,GAAGF;IAE5B,OAAOJ,IAAIE,OAAO;QAAEG;IAAK,IAAIC;AAC/B;AAYA;;CAEC,GACD,OAAO,SAASC,kBACdH,UAA6C,CAAC,CAAC;IAE/C,MAAM,EAAEI,WAAW,KAAK,EAAEF,SAAS,EAAE,GAAGF;IAExC,OAAOJ,IACLE,OAAO;QACLO,MAAM;QACN,eAAe,CAACD;IAClB,IACAF;AAEJ"}
|