@mezzanine-ui/react 1.0.0-rc.5 → 1.0.0-rc.7

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.
Files changed (213) hide show
  1. package/Accordion/Accordion.d.ts +36 -0
  2. package/Accordion/Accordion.js +37 -1
  3. package/AlertBanner/AlertBanner.d.ts +30 -1
  4. package/AlertBanner/AlertBanner.js +56 -12
  5. package/AutoComplete/AutoComplete.d.ts +75 -11
  6. package/AutoComplete/AutoComplete.js +145 -25
  7. package/AutoComplete/AutoCompleteInside.d.ts +54 -0
  8. package/AutoComplete/AutoCompleteInside.js +17 -0
  9. package/AutoComplete/useAutoCompleteKeyboard.d.ts +2 -1
  10. package/AutoComplete/useAutoCompleteKeyboard.js +4 -1
  11. package/Backdrop/Backdrop.d.ts +33 -1
  12. package/Backdrop/Backdrop.js +33 -1
  13. package/Badge/Badge.d.ts +26 -1
  14. package/Badge/Badge.js +26 -1
  15. package/Badge/typings.d.ts +15 -0
  16. package/Breadcrumb/BreadcrumbDropdown.d.ts +1 -1
  17. package/Breadcrumb/BreadcrumbOverflowMenuDropdown.d.ts +1 -1
  18. package/Breadcrumb/typings.d.ts +1 -1
  19. package/Button/Button.d.ts +26 -1
  20. package/Button/Button.js +33 -5
  21. package/COMPONENTS.md +267 -0
  22. package/Calendar/useCalendarControls.d.ts +18 -0
  23. package/Calendar/useCalendarControls.js +18 -0
  24. package/Card/FourThumbnailCard.js +1 -1
  25. package/Card/SingleThumbnailCard.js +1 -1
  26. package/Checkbox/Checkbox.d.ts +30 -1
  27. package/Checkbox/Checkbox.js +54 -4
  28. package/Checkbox/CheckboxGroup.d.ts +39 -1
  29. package/Checkbox/CheckboxGroup.js +49 -3
  30. package/Cropper/Cropper.d.ts +2 -2
  31. package/Cropper/Cropper.js +2 -3
  32. package/Cropper/CropperElement.js +1 -1
  33. package/Cropper/utils/cropper-calculations.d.ts +1 -1
  34. package/Cropper/utils/cropper-calculations.js +16 -14
  35. package/DatePicker/DatePicker.d.ts +36 -2
  36. package/DatePicker/DatePicker.js +36 -2
  37. package/DateRangePicker/useDateRangePickerValue.d.ts +24 -0
  38. package/DateRangePicker/useDateRangePickerValue.js +24 -0
  39. package/Description/Description.d.ts +1 -1
  40. package/Description/Description.js +1 -1
  41. package/Description/DescriptionTitle.d.ts +6 -1
  42. package/Description/DescriptionTitle.js +2 -2
  43. package/Drawer/Drawer.d.ts +78 -33
  44. package/Drawer/Drawer.js +72 -34
  45. package/Dropdown/Dropdown.d.ts +63 -1
  46. package/Dropdown/Dropdown.js +203 -9
  47. package/Dropdown/DropdownItem.d.ts +26 -2
  48. package/Dropdown/DropdownItem.js +91 -43
  49. package/Dropdown/DropdownItemCard.d.ts +3 -2
  50. package/Dropdown/DropdownItemCard.js +8 -5
  51. package/Dropdown/DropdownStatus.d.ts +2 -2
  52. package/Dropdown/DropdownStatus.js +3 -2
  53. package/Dropdown/dropdownKeydownHandler.d.ts +6 -0
  54. package/Dropdown/dropdownKeydownHandler.js +14 -7
  55. package/Empty/icons/EmptyMainInitialDataIcon.js +1 -1
  56. package/Empty/icons/EmptyMainNotificationIcon.js +1 -1
  57. package/Empty/icons/EmptyMainResultIcon.js +1 -1
  58. package/Empty/icons/EmptyMainSystemIcon.js +1 -1
  59. package/FilterArea/Filter.d.ts +25 -2
  60. package/FilterArea/Filter.js +43 -2
  61. package/FilterArea/FilterArea.d.ts +43 -4
  62. package/FilterArea/FilterArea.js +39 -4
  63. package/FilterArea/FilterAreaContext.d.ts +6 -0
  64. package/FilterArea/FilterAreaContext.js +6 -0
  65. package/FilterArea/FilterLine.d.ts +19 -0
  66. package/FilterArea/FilterLine.js +19 -0
  67. package/FilterArea/index.d.ts +2 -2
  68. package/FilterArea/index.js +1 -1
  69. package/Form/FormField.d.ts +43 -2
  70. package/Form/FormField.js +40 -3
  71. package/Form/typings.d.ts +2 -0
  72. package/Form/useAutoCompleteValueControl.d.ts +20 -0
  73. package/Form/useAutoCompleteValueControl.js +20 -0
  74. package/Form/useCheckboxControlValue.d.ts +19 -0
  75. package/Form/useCheckboxControlValue.js +19 -0
  76. package/Form/useControlValueState.d.ts +16 -0
  77. package/Form/useControlValueState.js +16 -0
  78. package/Form/useCustomControlValue.d.ts +17 -0
  79. package/Form/useCustomControlValue.js +17 -0
  80. package/Form/useInputControlValue.d.ts +19 -0
  81. package/Form/useInputControlValue.js +19 -0
  82. package/Form/useInputWithClearControlValue.d.ts +20 -0
  83. package/Form/useInputWithClearControlValue.js +20 -0
  84. package/Form/useRadioControlValue.d.ts +19 -0
  85. package/Form/useRadioControlValue.js +19 -0
  86. package/Form/useSelectValueControl.d.ts +19 -0
  87. package/Form/useSelectValueControl.js +19 -0
  88. package/Form/useSwitchControlValue.d.ts +18 -0
  89. package/Form/useSwitchControlValue.js +18 -0
  90. package/Icon/Icon.d.ts +23 -1
  91. package/Icon/Icon.js +23 -1
  92. package/Input/Input.d.ts +31 -1
  93. package/Input/Input.js +31 -1
  94. package/Input/SpinnerButton/SpinnerButton.js +1 -1
  95. package/Message/Message.d.ts +56 -6
  96. package/Message/Message.js +59 -52
  97. package/Modal/Modal.d.ts +76 -4
  98. package/Modal/Modal.js +117 -6
  99. package/Modal/ModalBodyForVerification.js +3 -1
  100. package/Modal/ModalFooter.d.ts +21 -6
  101. package/Modal/ModalHeader.d.ts +50 -11
  102. package/Modal/ModalHeader.js +1 -1
  103. package/Modal/index.d.ts +1 -1
  104. package/Navigation/Navigation.js +20 -11
  105. package/Navigation/NavigationHeader.js +2 -1
  106. package/Navigation/NavigationIconButton.d.ts +8 -0
  107. package/Navigation/NavigationIconButton.js +2 -2
  108. package/Navigation/NavigationOption.js +6 -3
  109. package/Navigation/NavigationOverflowMenu.js +9 -6
  110. package/Navigation/NavigationUserMenu.js +3 -1
  111. package/Navigation/context.d.ts +1 -0
  112. package/NotificationCenter/NotificationCenter.d.ts +59 -9
  113. package/NotificationCenter/NotificationCenter.js +150 -54
  114. package/NotificationCenter/NotificationCenterDrawer.d.ts +56 -6
  115. package/NotificationCenter/NotificationCenterDrawer.js +6 -8
  116. package/NotificationCenter/index.d.ts +1 -1
  117. package/OverflowTooltip/OverflowTooltip.js +46 -5
  118. package/PageFooter/PageFooter.d.ts +1 -1
  119. package/PageFooter/PageFooter.js +8 -16
  120. package/Pagination/Pagination.d.ts +38 -1
  121. package/Pagination/Pagination.js +38 -1
  122. package/Pagination/PaginationPageSize.js +1 -1
  123. package/Pagination/usePagination.d.ts +20 -0
  124. package/Pagination/usePagination.js +20 -0
  125. package/Progress/Progress.d.ts +24 -1
  126. package/Progress/Progress.js +24 -1
  127. package/README.md +82 -0
  128. package/Radio/Radio.d.ts +35 -1
  129. package/Radio/Radio.js +50 -12
  130. package/Radio/RadioGroup.d.ts +2 -2
  131. package/Radio/RadioGroupContext.d.ts +3 -2
  132. package/Section/SectionGroup.d.ts +20 -0
  133. package/Section/SectionGroup.js +16 -0
  134. package/Section/index.d.ts +2 -0
  135. package/Section/index.js +1 -0
  136. package/Select/Select.d.ts +55 -1
  137. package/Select/Select.js +37 -2
  138. package/Select/typings.d.ts +9 -0
  139. package/{Selection/Selection.d.ts → SelectionCard/SelectionCard.d.ts} +23 -11
  140. package/{Selection/Selection.js → SelectionCard/SelectionCard.js} +14 -14
  141. package/SelectionCard/SelectionCardGroup.d.ts +28 -0
  142. package/SelectionCard/index.d.ts +12 -0
  143. package/SelectionCard/index.js +5 -0
  144. package/Separator/Separator.d.ts +19 -1
  145. package/Separator/Separator.js +19 -1
  146. package/Slider/Slider.d.ts +11 -0
  147. package/Slider/useSlider.d.ts +21 -0
  148. package/Spin/Spin.d.ts +14 -5
  149. package/Spin/Spin.js +6 -8
  150. package/Stepper/Stepper.d.ts +34 -1
  151. package/Stepper/Stepper.js +34 -1
  152. package/Stepper/useStepper.d.ts +18 -0
  153. package/Stepper/useStepper.js +18 -0
  154. package/Tab/Tab.d.ts +33 -1
  155. package/Tab/Tab.js +33 -1
  156. package/Table/Table.d.ts +51 -3
  157. package/Table/Table.js +52 -4
  158. package/Table/hooks/useTableDataSource.d.ts +4 -4
  159. package/Table/hooks/useTableDataSource.js +1 -1
  160. package/Tag/Tag.d.ts +27 -1
  161. package/Tag/Tag.js +27 -1
  162. package/Tag/typings.d.ts +28 -0
  163. package/Textarea/Textarea.d.ts +28 -1
  164. package/Textarea/Textarea.js +25 -1
  165. package/TimePicker/TimePicker.js +1 -1
  166. package/TimeRangePicker/TimeRangePicker.js +1 -1
  167. package/Toggle/Toggle.d.ts +34 -1
  168. package/Toggle/Toggle.js +34 -1
  169. package/Tooltip/Tooltip.d.ts +39 -1
  170. package/Tooltip/Tooltip.js +39 -1
  171. package/Tooltip/useDelayMouseEnterLeave.d.ts +17 -0
  172. package/Tooltip/useDelayMouseEnterLeave.js +17 -0
  173. package/Typography/Typography.d.ts +23 -1
  174. package/Typography/Typography.js +23 -1
  175. package/Upload/Upload.d.ts +13 -7
  176. package/Upload/Upload.js +55 -20
  177. package/Upload/UploadItem.d.ts +3 -3
  178. package/Upload/UploadItem.js +11 -8
  179. package/Upload/UploadPictureCard.d.ts +5 -0
  180. package/Upload/UploadPictureCard.js +10 -6
  181. package/Upload/Uploader.d.ts +32 -31
  182. package/Upload/Uploader.js +10 -9
  183. package/hooks/useClickAway.d.ts +16 -0
  184. package/hooks/useClickAway.js +16 -0
  185. package/hooks/useComposeRefs.d.ts +15 -0
  186. package/hooks/useComposeRefs.js +15 -0
  187. package/hooks/useDocumentEscapeKeyDown.d.ts +15 -0
  188. package/hooks/useDocumentEscapeKeyDown.js +15 -0
  189. package/hooks/useDocumentEvents.d.ts +16 -0
  190. package/hooks/useDocumentEvents.js +16 -0
  191. package/hooks/useDocumentTabKeyDown.d.ts +15 -0
  192. package/hooks/useDocumentTabKeyDown.js +15 -0
  193. package/hooks/useIsomorphicLayoutEffect.d.ts +16 -0
  194. package/hooks/useIsomorphicLayoutEffect.js +16 -0
  195. package/hooks/useLastCallback.d.ts +15 -0
  196. package/hooks/useLastCallback.js +15 -0
  197. package/hooks/useLastValue.d.ts +18 -0
  198. package/hooks/useLastValue.js +18 -0
  199. package/hooks/usePreviousValue.d.ts +14 -0
  200. package/hooks/usePreviousValue.js +14 -0
  201. package/hooks/useScrollLock.d.ts +6 -4
  202. package/hooks/useScrollLock.js +6 -4
  203. package/hooks/useTopStack.d.ts +17 -0
  204. package/hooks/useTopStack.js +17 -0
  205. package/hooks/useWindowWidth.d.ts +14 -0
  206. package/hooks/useWindowWidth.js +14 -0
  207. package/index.d.ts +6 -4
  208. package/index.js +3 -2
  209. package/llms.txt +200 -0
  210. package/package.json +5 -4
  211. package/Selection/SelectionGroup.d.ts +0 -28
  212. package/Selection/index.d.ts +0 -12
  213. package/Selection/index.js +0 -5
@@ -1,5 +1,5 @@
1
1
  import { ChangeEventHandler, ReactNode, Ref } from 'react';
2
- import { type UploaderHintType, type UploadPictureControl, type UploadType } from '@mezzanine-ui/core/upload';
2
+ import { type UploaderHintType, type UploaderMode, type UploadPictureControl, type UploadType } from '@mezzanine-ui/core/upload';
3
3
  import { type IconDefinition } from '@mezzanine-ui/icons';
4
4
  import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
5
5
  type UploaderInputElementProps = Omit<NativeElementPropsWithoutKeyAndRef<'input'>, 'accept' | 'disabled' | 'multiple' | 'onChange' | 'type' | `aria-${'disabled'}`> & {
@@ -42,7 +42,7 @@ export interface UploaderLabel {
42
42
  */
43
43
  error?: string;
44
44
  /**
45
- * Label text for "Click to upload" when isFillWidth is true.
45
+ * Label text for "Click to upload" in `mode="dropzone"`.
46
46
  * @default 'Click to upload'
47
47
  */
48
48
  clickToUpload?: string;
@@ -87,20 +87,31 @@ export interface UploaderProps extends Omit<NativeElementPropsWithoutKeyAndRef<'
87
87
  * @example 'image/*', '.pdf,.doc,.docx'
88
88
  */
89
89
  accept?: string;
90
+ /**
91
+ * Provide `controllerRef` if you need detail data of file.
92
+ */
93
+ controllerRef?: Ref<UploadPictureControl | null>;
90
94
  /**
91
95
  * Whether the input is disabled.
92
96
  * @default false
93
97
  */
94
98
  disabled?: boolean;
95
99
  /**
96
- * The id of input element.
100
+ * Array of hints to display outside the uploader (below the label element).
97
101
  */
98
- id?: string;
102
+ externalHints?: UploaderHint[];
99
103
  /**
100
- * Whether to fill the width of the container.
101
- * @default false
104
+ * Array of hints to display with the upload component.
105
+ */
106
+ hints?: UploaderHint[];
107
+ /**
108
+ * Icon configuration for different actions and states.
102
109
  */
103
- isFillWidth?: boolean;
110
+ icon?: UploaderIcon;
111
+ /**
112
+ * The id of input element.
113
+ */
114
+ id?: string;
104
115
  /**
105
116
  * Since at Mezzanine we use a host element to wrap our input, most derived props will be passed to the host element.
106
117
  * If you need direct control to the input element, use this prop to provide to it.
@@ -110,37 +121,25 @@ export interface UploaderProps extends Omit<NativeElementPropsWithoutKeyAndRef<'
110
121
  * The react ref passed to input element.
111
122
  */
112
123
  inputRef?: React.Ref<HTMLInputElement>;
124
+ /**
125
+ * Label configuration for different states.
126
+ */
127
+ label?: UploaderLabel;
113
128
  /**
114
129
  * The name attribute of the input element.
115
130
  */
116
131
  name?: string;
132
+ /**
133
+ * The mode for upload component.
134
+ * @default 'basic'
135
+ * @example 'basic' | 'dropzone'
136
+ */
137
+ mode?: UploaderMode;
117
138
  /**
118
139
  * Whether can select multiple files to upload.
119
140
  * @default false
120
141
  */
121
142
  multiple?: boolean;
122
- /**
123
- * The type for upload component.
124
- * @default 'base'
125
- * @example 'base' | 'button'
126
- */
127
- type?: UploadType;
128
- /**
129
- * Array of hints to display with the upload component.
130
- */
131
- hints?: UploaderHint[];
132
- /**
133
- * Label configuration for different states.
134
- */
135
- label?: UploaderLabel;
136
- /**
137
- * Icon configuration for different actions and states.
138
- */
139
- icon?: UploaderIcon;
140
- /**
141
- * Provide `controllerRef` if you need detail data of file.
142
- */
143
- controllerRef?: Ref<UploadPictureControl | null>;
144
143
  /**
145
144
  * Invoked by input change event.
146
145
  */
@@ -150,9 +149,11 @@ export interface UploaderProps extends Omit<NativeElementPropsWithoutKeyAndRef<'
150
149
  */
151
150
  onUpload?: (files: File[]) => void;
152
151
  /**
153
- * Fired after user deletes file.
152
+ * The type for upload component.
153
+ * @default 'base'
154
+ * @example 'base' | 'button'
154
155
  */
155
- onDelete?: () => void;
156
+ type?: UploadType;
156
157
  }
157
158
  /**
158
159
  * The react component for `mezzanine` uploader.
@@ -2,7 +2,7 @@
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import { forwardRef, useId, useRef, useState, useMemo } from 'react';
4
4
  import { uploaderClasses } from '@mezzanine-ui/core/upload';
5
- import { UploadIcon } from '@mezzanine-ui/icons';
5
+ import { UploadIcon, InfoFilledIcon, DangerousFilledIcon } from '@mezzanine-ui/icons';
6
6
  import Button from '../Button/Button.js';
7
7
  import Typography from '../Typography/Typography.js';
8
8
  import { composeRefs } from '../utils/composeRefs.js';
@@ -14,7 +14,7 @@ import cx from 'clsx';
14
14
  */
15
15
  const Uploader = forwardRef(function Uploader(props, ref) {
16
16
  var _a, _b, _c;
17
- const { accept, className, disabled = false, id, inputProps, inputRef: inputRefProp, isFillWidth = false, multiple = false, name, type, hints, label: labelConfig, icon: iconConfig, controllerRef: _controllerRef, onChange: onChangeProp, onUpload, onDelete: _onDelete, ...rest } = props;
17
+ const { accept, className, controllerRef: _controllerRef, disabled = false, externalHints, id, hints, icon: iconConfig, inputProps, inputRef: inputRefProp, label: labelConfig, mode = 'basic', multiple = false, name, onChange: onChangeProp, onUpload, type, ...rest } = props;
18
18
  const { name: nameFromInputProps, id: idFromInputProps, ...restInputProps } = inputProps || {};
19
19
  // Generate unique id if not provided
20
20
  const generatedId = useId();
@@ -23,6 +23,7 @@ const Uploader = forwardRef(function Uploader(props, ref) {
23
23
  const [isDragging, setIsDragging] = useState(false);
24
24
  const composedInputRef = useMemo(() => composeRefs([inputRefProp, inputElementRef]), [inputRefProp]);
25
25
  const resolvedName = (_b = name !== null && name !== void 0 ? name : nameFromInputProps) !== null && _b !== void 0 ? _b : finalInputId;
26
+ const isDropzone = mode === 'dropzone';
26
27
  const handleChange = (event) => {
27
28
  if (onChangeProp) {
28
29
  onChangeProp(event);
@@ -98,7 +99,7 @@ const Uploader = forwardRef(function Uploader(props, ref) {
98
99
  }, [iconConfig]);
99
100
  const uploadLabel = (labelConfig === null || labelConfig === void 0 ? void 0 : labelConfig.uploadLabel)
100
101
  ? labelConfig === null || labelConfig === void 0 ? void 0 : labelConfig.uploadLabel
101
- : isFillWidth
102
+ : isDropzone
102
103
  ? 'Drag the file here or'
103
104
  : 'Upload';
104
105
  const clickToUploadLabel = (_c = labelConfig === null || labelConfig === void 0 ? void 0 : labelConfig.clickToUpload) !== null && _c !== void 0 ? _c : 'Click to upload';
@@ -109,12 +110,12 @@ const Uploader = forwardRef(function Uploader(props, ref) {
109
110
  inputElementRef.current.click();
110
111
  }
111
112
  };
112
- return (jsx("label", { className: cx(uploaderClasses.host, type && uploaderClasses.type(type), type !== 'button' && isFillWidth && uploaderClasses.fillWidth, isDragging && uploaderClasses.dragging, type !== 'button' && disabled && uploaderClasses.disabled, className), onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDragOver: handleDragOver, onDrop: handleDrop, ref: ref, ...rest, children: jsxs(Fragment, { children: [type === 'base'
113
- && isFillWidth
114
- && jsxs("div", { className: uploaderClasses.uploadContent, children: [uploadIcon, jsxs(Typography, { className: uploaderClasses.uploadLabel, children: [uploadLabel && jsxs(Fragment, { children: [uploadLabel, ' '] }), jsx("span", { className: uploaderClasses.clickToUpload, children: clickToUploadLabel })] }), hints === null || hints === void 0 ? void 0 : hints.map((hint, index) => (jsx(Typography, { className: uploaderClasses.fillWidthHints, children: hint.label }, index)))] }), type === 'base'
115
- && !isFillWidth
116
- && jsxs("div", { className: uploaderClasses.uploadContent, children: [uploadIcon, jsx(Typography, { className: uploaderClasses.uploadLabel, children: uploadLabel })] }), type === 'button'
117
- && (jsxs(Button, { disabled: disabled, onClick: handleClickToUpload, children: [uploadIcon, jsx(Typography, { children: uploadLabel })] })), jsx("input", { ...restInputProps, accept: accept, "aria-disabled": disabled, className: uploaderClasses.input, disabled: disabled, id: finalInputId, multiple: multiple, name: resolvedName, onChange: handleChange, ref: composedInputRef, type: "file" })] }) }));
113
+ return (jsxs(Fragment, { children: [jsx("label", { className: cx(uploaderClasses.host, type && uploaderClasses.type(type), type !== 'button' && isDropzone && uploaderClasses.fillWidth, isDragging && uploaderClasses.dragging, type !== 'button' && disabled && uploaderClasses.disabled, className), onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDragOver: handleDragOver, onDrop: handleDrop, ref: ref, ...rest, children: jsxs(Fragment, { children: [type === 'base'
114
+ && isDropzone
115
+ && jsxs("div", { className: uploaderClasses.uploadContent, children: [uploadIcon, jsxs(Typography, { className: uploaderClasses.uploadLabel, children: [uploadLabel && jsxs(Fragment, { children: [uploadLabel, ' '] }), jsx("span", { className: uploaderClasses.clickToUpload, children: clickToUploadLabel })] }), hints === null || hints === void 0 ? void 0 : hints.map((hint, index) => (jsx(Typography, { className: uploaderClasses.fillWidthHints, children: hint.label }, index)))] }), type === 'base'
116
+ && !isDropzone
117
+ && jsxs("div", { className: uploaderClasses.uploadContent, children: [uploadIcon, jsx(Typography, { className: uploaderClasses.uploadLabel, children: uploadLabel })] }), type === 'button'
118
+ && (jsx(Button, { disabled: disabled, iconType: "leading", icon: UploadIcon, onClick: handleClickToUpload, children: jsx(Typography, { align: "center", color: "text-fixed-light", variant: "button-highlight", className: uploaderClasses.uploadButtonText, children: uploadLabel }) })), jsx("input", { ...restInputProps, accept: accept, "aria-disabled": disabled, className: uploaderClasses.input, disabled: disabled, id: finalInputId, multiple: multiple, name: resolvedName, onChange: handleChange, ref: composedInputRef, type: "file" })] }) }), externalHints && externalHints.length > 0 && (jsx("ul", { className: uploaderClasses.externalHints, children: externalHints.map((hint) => (jsxs("li", { className: uploaderClasses.externalHint(hint.type || 'info'), children: [jsx(Icon, { icon: hint.type === 'info' ? InfoFilledIcon : DangerousFilledIcon, color: hint.type === 'info' ? 'info' : 'error', size: 14 }), hint.label] }, hint.label))) }))] }));
118
119
  });
119
120
 
120
121
  export { Uploader as default };
@@ -2,4 +2,20 @@ import { RefObject, DependencyList } from 'react';
2
2
  export type ClickAwayEvent = MouseEvent | TouchEvent | PointerEvent;
3
3
  export type ClickAwayHandler = (event: ClickAwayEvent) => void;
4
4
  export type ClickAwayHandlerFactory = () => ClickAwayHandler | undefined;
5
+ /**
6
+ * 偵測點擊發生在指定容器外部的 Hook。
7
+ *
8
+ * 監聽 `click` 與 `touchend` 事件,當點擊目標不在 `containerRef` 的 DOM 節點內時,
9
+ * 呼叫 `factory` 回傳的處理器;若 `factory` 回傳 `undefined` 則不掛載任何監聽器。
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * import { useClickAway } from '@mezzanine-ui/react';
14
+ *
15
+ * const containerRef = useRef<HTMLDivElement>(null);
16
+ * useClickAway(() => {
17
+ * if (open) return () => setOpen(false);
18
+ * }, containerRef, [open]);
19
+ * ```
20
+ */
5
21
  export declare function useClickAway(factory: ClickAwayHandlerFactory, containerRef: RefObject<HTMLElement | null>, deps?: DependencyList): void;
@@ -1,5 +1,21 @@
1
1
  import { useDocumentEvents } from './useDocumentEvents.js';
2
2
 
3
+ /**
4
+ * 偵測點擊發生在指定容器外部的 Hook。
5
+ *
6
+ * 監聽 `click` 與 `touchend` 事件,當點擊目標不在 `containerRef` 的 DOM 節點內時,
7
+ * 呼叫 `factory` 回傳的處理器;若 `factory` 回傳 `undefined` 則不掛載任何監聽器。
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { useClickAway } from '@mezzanine-ui/react';
12
+ *
13
+ * const containerRef = useRef<HTMLDivElement>(null);
14
+ * useClickAway(() => {
15
+ * if (open) return () => setOpen(false);
16
+ * }, containerRef, [open]);
17
+ * ```
18
+ */
3
19
  function useClickAway(factory, containerRef, deps) {
4
20
  useDocumentEvents(() => {
5
21
  const clickAwayHandler = factory();
@@ -1,2 +1,17 @@
1
1
  import { ComposableRef, ComposedRef } from '../utils/composeRefs';
2
+ /**
3
+ * 將多個 React ref 合併成單一 callback ref 的 Hook。
4
+ *
5
+ * 回傳一個穩定的 callback ref(依賴陣列永遠為空),
6
+ * 每次渲染時仍能正確呼叫最新的 ref 集合,適用於需要同時傳遞 forwardRef 與內部 ref 的情境。
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * import { useComposeRefs } from '@mezzanine-ui/react';
11
+ *
12
+ * const internalRef = useRef<HTMLDivElement>(null);
13
+ * const composedRef = useComposeRefs([internalRef, forwardedRef]);
14
+ * return <div ref={composedRef} />;
15
+ * ```
16
+ */
2
17
  export declare function useComposeRefs<T>(refs: ComposableRef<T>[]): ComposedRef<T>;
@@ -1,6 +1,21 @@
1
1
  import { useRef, useCallback } from 'react';
2
2
  import { composeRefs } from '../utils/composeRefs.js';
3
3
 
4
+ /**
5
+ * 將多個 React ref 合併成單一 callback ref 的 Hook。
6
+ *
7
+ * 回傳一個穩定的 callback ref(依賴陣列永遠為空),
8
+ * 每次渲染時仍能正確呼叫最新的 ref 集合,適用於需要同時傳遞 forwardRef 與內部 ref 的情境。
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * import { useComposeRefs } from '@mezzanine-ui/react';
13
+ *
14
+ * const internalRef = useRef<HTMLDivElement>(null);
15
+ * const composedRef = useComposeRefs([internalRef, forwardedRef]);
16
+ * return <div ref={composedRef} />;
17
+ * ```
18
+ */
4
19
  function useComposeRefs(refs) {
5
20
  const refsRef = useRef(refs);
6
21
  refsRef.current = refs;
@@ -1,3 +1,18 @@
1
1
  import { DependencyList } from 'react';
2
2
  export type DocumentEscapeKeyDownHandlerFactory = () => ((event: KeyboardEvent) => void) | undefined;
3
+ /**
4
+ * 在 document 上監聽 Escape 鍵按下事件的 Hook。
5
+ *
6
+ * 當鍵盤觸發 `keydown` 且 `event.key === 'Escape'` 時,呼叫 `factory` 回傳的處理器並阻止預設行為;
7
+ * 若 `factory` 回傳 `undefined` 則不掛載任何監聽器。
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { useDocumentEscapeKeyDown } from '@mezzanine-ui/react';
12
+ *
13
+ * useDocumentEscapeKeyDown(() => {
14
+ * if (open) return () => setOpen(false);
15
+ * }, [open]);
16
+ * ```
17
+ */
3
18
  export declare function useDocumentEscapeKeyDown(factory: DocumentEscapeKeyDownHandlerFactory, deps?: DependencyList): void;
@@ -1,5 +1,20 @@
1
1
  import { useDocumentEvents } from './useDocumentEvents.js';
2
2
 
3
+ /**
4
+ * 在 document 上監聽 Escape 鍵按下事件的 Hook。
5
+ *
6
+ * 當鍵盤觸發 `keydown` 且 `event.key === 'Escape'` 時,呼叫 `factory` 回傳的處理器並阻止預設行為;
7
+ * 若 `factory` 回傳 `undefined` 則不掛載任何監聽器。
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { useDocumentEscapeKeyDown } from '@mezzanine-ui/react';
12
+ *
13
+ * useDocumentEscapeKeyDown(() => {
14
+ * if (open) return () => setOpen(false);
15
+ * }, [open]);
16
+ * ```
17
+ */
3
18
  function useDocumentEscapeKeyDown(factory, deps) {
4
19
  useDocumentEvents(() => {
5
20
  const handler = factory();
@@ -2,4 +2,20 @@ import { DependencyList } from 'react';
2
2
  export type DocumentEventHandlersFactory = () => {
3
3
  [event in keyof DocumentEventMap]?: (event: DocumentEventMap[event]) => void;
4
4
  } | undefined;
5
+ /**
6
+ * 在 document 上批次註冊/移除事件監聽器的 Hook。
7
+ *
8
+ * `factory` 回傳一個事件名稱到處理器的映射物件;依賴項變化時舊監聽器會先被移除,
9
+ * 再重新掛載新的;若 `factory` 回傳 `undefined` 則不掛載任何監聽器。
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * import { useDocumentEvents } from '@mezzanine-ui/react';
14
+ *
15
+ * useDocumentEvents(() => ({
16
+ * click: handleClick,
17
+ * keydown: handleKeyDown,
18
+ * }), [handleClick, handleKeyDown]);
19
+ * ```
20
+ */
5
21
  export declare function useDocumentEvents(factory: DocumentEventHandlersFactory, deps?: DependencyList): void;
@@ -1,5 +1,21 @@
1
1
  import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect.js';
2
2
 
3
+ /**
4
+ * 在 document 上批次註冊/移除事件監聽器的 Hook。
5
+ *
6
+ * `factory` 回傳一個事件名稱到處理器的映射物件;依賴項變化時舊監聽器會先被移除,
7
+ * 再重新掛載新的;若 `factory` 回傳 `undefined` 則不掛載任何監聽器。
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { useDocumentEvents } from '@mezzanine-ui/react';
12
+ *
13
+ * useDocumentEvents(() => ({
14
+ * click: handleClick,
15
+ * keydown: handleKeyDown,
16
+ * }), [handleClick, handleKeyDown]);
17
+ * ```
18
+ */
3
19
  function useDocumentEvents(factory, deps) {
4
20
  useIsomorphicLayoutEffect(() => {
5
21
  const handlers = factory();
@@ -1,3 +1,18 @@
1
1
  import { DependencyList } from 'react';
2
2
  export type DocumentTabKeyDownHandlerFactory = () => ((event: KeyboardEvent) => void) | undefined;
3
+ /**
4
+ * 在 document 上監聽 Tab 鍵按下事件的 Hook。
5
+ *
6
+ * 當鍵盤觸發 `keydown` 且 `event.key === 'Tab'` 時,呼叫 `factory` 回傳的處理器;
7
+ * 若 `factory` 回傳 `undefined` 則不掛載任何監聽器。
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { useDocumentTabKeyDown } from '@mezzanine-ui/react';
12
+ *
13
+ * useDocumentTabKeyDown(() => {
14
+ * if (open) return (e) => trapFocus(e);
15
+ * }, [open]);
16
+ * ```
17
+ */
3
18
  export declare function useDocumentTabKeyDown(factory: DocumentTabKeyDownHandlerFactory, deps?: DependencyList): void;
@@ -1,5 +1,20 @@
1
1
  import { useDocumentEvents } from './useDocumentEvents.js';
2
2
 
3
+ /**
4
+ * 在 document 上監聽 Tab 鍵按下事件的 Hook。
5
+ *
6
+ * 當鍵盤觸發 `keydown` 且 `event.key === 'Tab'` 時,呼叫 `factory` 回傳的處理器;
7
+ * 若 `factory` 回傳 `undefined` 則不掛載任何監聽器。
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { useDocumentTabKeyDown } from '@mezzanine-ui/react';
12
+ *
13
+ * useDocumentTabKeyDown(() => {
14
+ * if (open) return (e) => trapFocus(e);
15
+ * }, [open]);
16
+ * ```
17
+ */
3
18
  function useDocumentTabKeyDown(factory, deps) {
4
19
  useDocumentEvents(() => {
5
20
  const handler = factory();
@@ -1,2 +1,18 @@
1
1
  import { useLayoutEffect } from 'react';
2
+ /**
3
+ * 在瀏覽器環境使用 `useLayoutEffect`、在 SSR 環境降級為 `useEffect` 的 Hook。
4
+ *
5
+ * 用於需要在 DOM 繪製前同步執行副作用的場景(例如讀取 layout 資訊),
6
+ * 同時避免伺服器端渲染時因 `useLayoutEffect` 產生警告。
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * import { useIsomorphicLayoutEffect } from '@mezzanine-ui/react';
11
+ *
12
+ * useIsomorphicLayoutEffect(() => {
13
+ * // 在 DOM 更新後、繪製前同步執行
14
+ * measureElement();
15
+ * }, [deps]);
16
+ * ```
17
+ */
2
18
  export declare const useIsomorphicLayoutEffect: typeof useLayoutEffect;
@@ -1,5 +1,21 @@
1
1
  import { useLayoutEffect, useEffect } from 'react';
2
2
 
3
+ /**
4
+ * 在瀏覽器環境使用 `useLayoutEffect`、在 SSR 環境降級為 `useEffect` 的 Hook。
5
+ *
6
+ * 用於需要在 DOM 繪製前同步執行副作用的場景(例如讀取 layout 資訊),
7
+ * 同時避免伺服器端渲染時因 `useLayoutEffect` 產生警告。
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { useIsomorphicLayoutEffect } from '@mezzanine-ui/react';
12
+ *
13
+ * useIsomorphicLayoutEffect(() => {
14
+ * // 在 DOM 更新後、繪製前同步執行
15
+ * measureElement();
16
+ * }, [deps]);
17
+ * ```
18
+ */
3
19
  const useIsomorphicLayoutEffect = typeof window !== 'undefined' &&
4
20
  window.document &&
5
21
  !!window.document.createElement
@@ -1 +1,16 @@
1
+ /**
2
+ * 回傳一個引用永遠穩定但呼叫時使用最新版本 callback 的 Hook。
3
+ *
4
+ * 內部以 ref 儲存最新的 callback,對外回傳一個依賴陣列為空的 `useCallback` wrapper,
5
+ * 可安全地傳遞給子元件或事件處理器而不觸發不必要的 re-render。
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { useLastCallback } from '@mezzanine-ui/react';
10
+ *
11
+ * const stableOnChange = useLastCallback((value: string) => {
12
+ * doSomethingWith(value);
13
+ * });
14
+ * ```
15
+ */
1
16
  export declare function useLastCallback<F extends (...args: any[]) => any>(callback: F): (...args: Parameters<F>) => ReturnType<F>;
@@ -1,6 +1,21 @@
1
1
  import { useCallback } from 'react';
2
2
  import { useLastValue } from './useLastValue.js';
3
3
 
4
+ /**
5
+ * 回傳一個引用永遠穩定但呼叫時使用最新版本 callback 的 Hook。
6
+ *
7
+ * 內部以 ref 儲存最新的 callback,對外回傳一個依賴陣列為空的 `useCallback` wrapper,
8
+ * 可安全地傳遞給子元件或事件處理器而不觸發不必要的 re-render。
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * import { useLastCallback } from '@mezzanine-ui/react';
13
+ *
14
+ * const stableOnChange = useLastCallback((value: string) => {
15
+ * doSomethingWith(value);
16
+ * });
17
+ * ```
18
+ */
4
19
  function useLastCallback(callback) {
5
20
  const lastCallback = useLastValue(callback);
6
21
  return useCallback(
@@ -1,3 +1,21 @@
1
+ /**
2
+ * 追蹤並回傳最新值的 ref Hook。
3
+ *
4
+ * 每次渲染時同步更新 ref 的 `current` 屬性,
5
+ * 可用於在非同步回調或 effect 中存取最新的 prop 或 state,而無需將其加入依賴陣列。
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { useLastValue } from '@mezzanine-ui/react';
10
+ *
11
+ * const latestCount = useLastValue(count);
12
+ * useEffect(() => {
13
+ * setTimeout(() => {
14
+ * console.log(latestCount.current); // 總是最新的值
15
+ * }, 1000);
16
+ * }, []);
17
+ * ```
18
+ */
1
19
  export declare function useLastValue<T>(value: T): {
2
20
  readonly current: T;
3
21
  };
@@ -1,5 +1,23 @@
1
1
  import { useRef } from 'react';
2
2
 
3
+ /**
4
+ * 追蹤並回傳最新值的 ref Hook。
5
+ *
6
+ * 每次渲染時同步更新 ref 的 `current` 屬性,
7
+ * 可用於在非同步回調或 effect 中存取最新的 prop 或 state,而無需將其加入依賴陣列。
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { useLastValue } from '@mezzanine-ui/react';
12
+ *
13
+ * const latestCount = useLastValue(count);
14
+ * useEffect(() => {
15
+ * setTimeout(() => {
16
+ * console.log(latestCount.current); // 總是最新的值
17
+ * }, 1000);
18
+ * }, []);
19
+ * ```
20
+ */
3
21
  function useLastValue(value) {
4
22
  const ref = useRef(value);
5
23
  ref.current = value;
@@ -1 +1,15 @@
1
+ /**
2
+ * 回傳上一次渲染時的值的 Hook。
3
+ *
4
+ * 以 `useEffect` 在渲染完成後更新 ref,因此在本次渲染中取得的是前一次的值,
5
+ * 適用於需要比較前後值差異的情境。
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { usePreviousValue } from '@mezzanine-ui/react';
10
+ *
11
+ * const previousCount = usePreviousValue(count);
12
+ * // previousCount 為 count 上一次渲染的值
13
+ * ```
14
+ */
1
15
  export declare function usePreviousValue<T>(value: T): T;
@@ -1,5 +1,19 @@
1
1
  import { useRef, useEffect } from 'react';
2
2
 
3
+ /**
4
+ * 回傳上一次渲染時的值的 Hook。
5
+ *
6
+ * 以 `useEffect` 在渲染完成後更新 ref,因此在本次渲染中取得的是前一次的值,
7
+ * 適用於需要比較前後值差異的情境。
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { usePreviousValue } from '@mezzanine-ui/react';
12
+ *
13
+ * const previousCount = usePreviousValue(count);
14
+ * // previousCount 為 count 上一次渲染的值
15
+ * ```
16
+ */
3
17
  function usePreviousValue(value) {
4
18
  const ref = useRef(value);
5
19
  useEffect(() => {
@@ -11,13 +11,15 @@ interface ScrollLockOptions {
11
11
  reserveScrollBarGap?: boolean;
12
12
  }
13
13
  /**
14
- * Hook to lock/unlock body scroll
15
- * Handles multiple concurrent locks (nested modals/overlays)
16
- * Prevents layout shift by reserving scrollbar width
17
- * Handles iOS rubber band scrolling
14
+ * 鎖定/解鎖頁面捲動的 Hook
15
+ *
16
+ * 支援多層巢狀鎖定(nested modals/overlays),保留捲軸寬度以防止版面偏移,
17
+ * 並針對 iOS Safari 的 rubber band scrolling 進行特別處理。
18
18
  *
19
19
  * @example
20
20
  * ```tsx
21
+ * import { useScrollLock } from '@mezzanine-ui/react';
22
+ *
21
23
  * function Modal({ open }) {
22
24
  * useScrollLock({ enabled: open });
23
25
  * return <div>...</div>;
@@ -93,13 +93,15 @@ function isIOS() {
93
93
  return isIOSDevice || isSafariOnMac;
94
94
  }
95
95
  /**
96
- * Hook to lock/unlock body scroll
97
- * Handles multiple concurrent locks (nested modals/overlays)
98
- * Prevents layout shift by reserving scrollbar width
99
- * Handles iOS rubber band scrolling
96
+ * 鎖定/解鎖頁面捲動的 Hook
97
+ *
98
+ * 支援多層巢狀鎖定(nested modals/overlays),保留捲軸寬度以防止版面偏移,
99
+ * 並針對 iOS Safari 的 rubber band scrolling 進行特別處理。
100
100
  *
101
101
  * @example
102
102
  * ```tsx
103
+ * import { useScrollLock } from '@mezzanine-ui/react';
104
+ *
103
105
  * function Modal({ open }) {
104
106
  * useScrollLock({ enabled: open });
105
107
  * return <div>...</div>;
@@ -1 +1,18 @@
1
+ /**
2
+ * 管理多個浮層 z-index 堆疊順序的 Hook。
3
+ *
4
+ * 每個元件呼叫此 Hook 時會取得一個唯一的 seed 值;當 `open` 為 `true` 時,
5
+ * 該 seed 會被推入全域堆疊,回傳的函式可用於查詢自己是否位於最頂層。
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import useTopStack from '@mezzanine-ui/react/hooks/useTopStack';
10
+ *
11
+ * const isTopStack = useTopStack(open);
12
+ * // 在 Escape 鍵處理時,只有最頂層的浮層才關閉
13
+ * useDocumentEscapeKeyDown(() => {
14
+ * if (isTopStack()) return () => setOpen(false);
15
+ * }, [isTopStack]);
16
+ * ```
17
+ */
1
18
  export default function useTopStack(open?: boolean): () => boolean;
@@ -2,6 +2,23 @@ import { useMemo, useEffect, useCallback } from 'react';
2
2
 
3
3
  let seedStack = [];
4
4
  let seed = 1;
5
+ /**
6
+ * 管理多個浮層 z-index 堆疊順序的 Hook。
7
+ *
8
+ * 每個元件呼叫此 Hook 時會取得一個唯一的 seed 值;當 `open` 為 `true` 時,
9
+ * 該 seed 會被推入全域堆疊,回傳的函式可用於查詢自己是否位於最頂層。
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * import useTopStack from '@mezzanine-ui/react/hooks/useTopStack';
14
+ *
15
+ * const isTopStack = useTopStack(open);
16
+ * // 在 Escape 鍵處理時,只有最頂層的浮層才關閉
17
+ * useDocumentEscapeKeyDown(() => {
18
+ * if (isTopStack()) return () => setOpen(false);
19
+ * }, [isTopStack]);
20
+ * ```
21
+ */
5
22
  function useTopStack(open) {
6
23
  const modalSeed = useMemo(() => {
7
24
  // eslint-disable-next-line react-hooks/globals
@@ -1 +1,15 @@
1
+ /**
2
+ * 追蹤目前視窗寬度的 Hook。
3
+ *
4
+ * 在元件掛載時以 `window.innerWidth` 初始化,並監聽 `resize` 事件持續更新,
5
+ * 元件卸載時自動移除監聽器。
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { useWindowWidth } from '@mezzanine-ui/react';
10
+ *
11
+ * const width = useWindowWidth();
12
+ * const isMobile = width !== undefined && width < 768;
13
+ * ```
14
+ */
1
15
  export declare function useWindowWidth(): number | undefined;