@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
@@ -2,6 +2,25 @@ import { useLastCallback } from '../hooks/useLastCallback.js';
2
2
  import { useControlValueState } from './useControlValueState.js';
3
3
 
4
4
  const equalityFn = (a, b) => a === b;
5
+ /**
6
+ * 管理 Input/Textarea 文字值的受控狀態 Hook。
7
+ *
8
+ * 支援受控(`value`)與非受控(`defaultValue`)兩種用法,
9
+ * 回傳當前文字值與穩定的 `onChange` 事件處理器。
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * import { useInputControlValue } from '@mezzanine-ui/react';
14
+ *
15
+ * function MyInput({ value, onChange }) {
16
+ * const [inputValue, handleChange] = useInputControlValue({ value, onChange });
17
+ * return <input value={inputValue} onChange={handleChange} />;
18
+ * }
19
+ * ```
20
+ *
21
+ * @see {@link Input} 搭配的元件
22
+ * @see {@link Textarea} 搭配的元件
23
+ */
5
24
  function useInputControlValue(props) {
6
25
  const { defaultValue = '', onChange: onChangeProp, value: valueProp } = props;
7
26
  const [value, setValue] = useControlValueState({
@@ -3,4 +3,24 @@ import { UseInputControlValueProps } from './useInputControlValue';
3
3
  export interface UseInputWithClearControlValueProps<E extends HTMLInputElement | HTMLTextAreaElement> extends UseInputControlValueProps<E> {
4
4
  ref: RefObject<E | null>;
5
5
  }
6
+ /**
7
+ * 為可清除 Input 提供值管理的受控狀態 Hook。
8
+ *
9
+ * 在 `useInputControlValue` 的基礎上額外提供 `onClear` 清除處理器,
10
+ * 透過操作原生 DOM ref 模擬一個值為空字串的 change 事件,確保受控流程完整。
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * import { useInputWithClearControlValue } from '@mezzanine-ui/react';
15
+ *
16
+ * const inputRef = useRef<HTMLInputElement>(null);
17
+ * const [value, onChange, onClear] = useInputWithClearControlValue({
18
+ * ref: inputRef,
19
+ * value: controlledValue,
20
+ * onChange: handleChange,
21
+ * });
22
+ * ```
23
+ *
24
+ * @see {@link Input} 搭配的元件(clearable 變體)
25
+ */
6
26
  export declare function useInputWithClearControlValue<E extends HTMLInputElement | HTMLTextAreaElement>(props: UseInputWithClearControlValueProps<E>): readonly [string, (event: ChangeEvent<E>) => void, (event: MouseEvent) => void];
@@ -1,5 +1,25 @@
1
1
  import { useInputControlValue } from './useInputControlValue.js';
2
2
 
3
+ /**
4
+ * 為可清除 Input 提供值管理的受控狀態 Hook。
5
+ *
6
+ * 在 `useInputControlValue` 的基礎上額外提供 `onClear` 清除處理器,
7
+ * 透過操作原生 DOM ref 模擬一個值為空字串的 change 事件,確保受控流程完整。
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { useInputWithClearControlValue } from '@mezzanine-ui/react';
12
+ *
13
+ * const inputRef = useRef<HTMLInputElement>(null);
14
+ * const [value, onChange, onClear] = useInputWithClearControlValue({
15
+ * ref: inputRef,
16
+ * value: controlledValue,
17
+ * onChange: handleChange,
18
+ * });
19
+ * ```
20
+ *
21
+ * @see {@link Input} 搭配的元件(clearable 變體)
22
+ */
3
23
  function useInputWithClearControlValue(props) {
4
24
  const { defaultValue, onChange: onChangeProp, ref, value: valueProp } = props;
5
25
  const [value, onChange] = useInputControlValue({
@@ -8,4 +8,23 @@ export interface UseRadioControlValueProps extends UseSwitchControlValueProps {
8
8
  radioGroup?: RadioGroupControlContextValue;
9
9
  value?: string;
10
10
  }
11
+ /**
12
+ * 管理 Radio 選取狀態的受控 Hook。
13
+ *
14
+ * 支援獨立使用與在 RadioGroup 內使用兩種情境:
15
+ * 當傳入 `radioGroup` 上下文時,會以群組的 `value` 與本身的 `value` 進行比對來決定是否選中。
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * import { useRadioControlValue } from '@mezzanine-ui/react';
20
+ *
21
+ * const [checked, handleChange] = useRadioControlValue({
22
+ * value: 'option-a',
23
+ * radioGroup: { value: selectedValue, onChange: handleGroupChange },
24
+ * });
25
+ * ```
26
+ *
27
+ * @see {@link Radio} 搭配的元件
28
+ * @see {@link RadioGroup} 搭配的元件
29
+ */
11
30
  export declare function useRadioControlValue(props: UseRadioControlValueProps): readonly [boolean, (event: import("react").ChangeEvent<HTMLInputElement>) => void];
@@ -1,5 +1,24 @@
1
1
  import { useSwitchControlValue } from './useSwitchControlValue.js';
2
2
 
3
+ /**
4
+ * 管理 Radio 選取狀態的受控 Hook。
5
+ *
6
+ * 支援獨立使用與在 RadioGroup 內使用兩種情境:
7
+ * 當傳入 `radioGroup` 上下文時,會以群組的 `value` 與本身的 `value` 進行比對來決定是否選中。
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { useRadioControlValue } from '@mezzanine-ui/react';
12
+ *
13
+ * const [checked, handleChange] = useRadioControlValue({
14
+ * value: 'option-a',
15
+ * radioGroup: { value: selectedValue, onChange: handleGroupChange },
16
+ * });
17
+ * ```
18
+ *
19
+ * @see {@link Radio} 搭配的元件
20
+ * @see {@link RadioGroup} 搭配的元件
21
+ */
3
22
  function useRadioControlValue(props) {
4
23
  const { checked: checkedProp, defaultChecked, onChange: onChangeProp, radioGroup, value, } = props;
5
24
  const { onChange: onChangeFromGroup } = radioGroup || {};
@@ -29,4 +29,23 @@ export type SelectSingleValueControl = SelectBaseValueControl & {
29
29
  value: SelectValue | null;
30
30
  };
31
31
  export type SelectValueControl = SelectMultipleValueControl | SelectSingleValueControl;
32
+ /**
33
+ * 管理 Select 單選/多選值的受控狀態 Hook。
34
+ *
35
+ * 根據 `mode` 分別處理單選(`single`)與多選(`multiple`)邏輯,
36
+ * 提供 `value`、`onChange` 與 `onClear` 等操作介面。
37
+ *
38
+ * @example
39
+ * ```tsx
40
+ * import { useSelectValueControl } from '@mezzanine-ui/react';
41
+ *
42
+ * const control = useSelectValueControl({
43
+ * mode: 'single',
44
+ * value: selectedOption,
45
+ * onChange: (option) => setSelectedOption(option),
46
+ * });
47
+ * ```
48
+ *
49
+ * @see {@link Select} 搭配的元件
50
+ */
32
51
  export declare const useSelectValueControl: (props: UseSelectValueControl) => SelectMultipleValueControl | SelectSingleValueControl;
@@ -76,6 +76,25 @@ function useSelectBaseValueControl(props) {
76
76
  },
77
77
  };
78
78
  }
79
+ /**
80
+ * 管理 Select 單選/多選值的受控狀態 Hook。
81
+ *
82
+ * 根據 `mode` 分別處理單選(`single`)與多選(`multiple`)邏輯,
83
+ * 提供 `value`、`onChange` 與 `onClear` 等操作介面。
84
+ *
85
+ * @example
86
+ * ```tsx
87
+ * import { useSelectValueControl } from '@mezzanine-ui/react';
88
+ *
89
+ * const control = useSelectValueControl({
90
+ * mode: 'single',
91
+ * value: selectedOption,
92
+ * onChange: (option) => setSelectedOption(option),
93
+ * });
94
+ * ```
95
+ *
96
+ * @see {@link Select} 搭配的元件
97
+ */
79
98
  const useSelectValueControl = (props) => {
80
99
  if (props.mode === 'multiple') {
81
100
  // eslint-disable-next-line react-hooks/rules-of-hooks
@@ -4,4 +4,22 @@ export interface UseSwitchControlValueProps {
4
4
  defaultChecked?: boolean;
5
5
  onChange?: ChangeEventHandler<HTMLInputElement>;
6
6
  }
7
+ /**
8
+ * 管理布林開關(checked)狀態的受控 Hook。
9
+ *
10
+ * 適用於任何基於 `<input type="checkbox">` 的切換元件,
11
+ * 回傳當前勾選狀態與穩定的 `onChange` 事件處理器。
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * import { useSwitchControlValue } from '@mezzanine-ui/react';
16
+ *
17
+ * const [checked, handleChange] = useSwitchControlValue({
18
+ * defaultChecked: false,
19
+ * onChange: (e) => console.log(e.target.checked),
20
+ * });
21
+ * ```
22
+ *
23
+ * @see {@link Switch} 搭配的元件
24
+ */
7
25
  export declare function useSwitchControlValue(props: UseSwitchControlValueProps): readonly [boolean, (event: import("react").ChangeEvent<HTMLInputElement>) => void];
@@ -2,6 +2,24 @@ import { useLastCallback } from '../hooks/useLastCallback.js';
2
2
  import { useControlValueState } from './useControlValueState.js';
3
3
 
4
4
  const equalityFn = (a, b) => a === b;
5
+ /**
6
+ * 管理布林開關(checked)狀態的受控 Hook。
7
+ *
8
+ * 適用於任何基於 `<input type="checkbox">` 的切換元件,
9
+ * 回傳當前勾選狀態與穩定的 `onChange` 事件處理器。
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * import { useSwitchControlValue } from '@mezzanine-ui/react';
14
+ *
15
+ * const [checked, handleChange] = useSwitchControlValue({
16
+ * defaultChecked: false,
17
+ * onChange: (e) => console.log(e.target.checked),
18
+ * });
19
+ * ```
20
+ *
21
+ * @see {@link Switch} 搭配的元件
22
+ */
5
23
  function useSwitchControlValue(props) {
6
24
  const { checked: checkedProp, defaultChecked = false, onChange: onChangeProp, } = props;
7
25
  const [checked, setChecked] = useControlValueState({
package/Icon/Icon.d.ts CHANGED
@@ -25,7 +25,29 @@ export interface IconProps extends NativeElementPropsWithoutKeyAndRef<'i'> {
25
25
  title?: string;
26
26
  }
27
27
  /**
28
- * The react component for `mezzanine` icon.
28
+ * 渲染來自 `@mezzanine-ui/icons` SVG 圖示元件。
29
+ *
30
+ * 透過 `icon` prop 傳入圖示定義物件,支援調整顏色、尺寸與旋轉動畫。
31
+ * 當元件綁定 `onClick` 或 `onMouseOver` 事件時,游標樣式會自動切換為 pointer。
32
+ * 可透過 `title` prop 提供無障礙標題文字。
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * import Icon from '@mezzanine-ui/react/Icon';
37
+ * import { SearchIcon, LoadingIcon, CheckCircleFilledIcon } from '@mezzanine-ui/icons';
38
+ *
39
+ * // 基本用法
40
+ * <Icon icon={SearchIcon} />
41
+ *
42
+ * // 自訂顏色與尺寸
43
+ * <Icon icon={CheckCircleFilledIcon} color="success" size={24} />
44
+ *
45
+ * // 旋轉動畫(常用於載入狀態)
46
+ * <Icon icon={LoadingIcon} spin />
47
+ *
48
+ * // 加入無障礙標題
49
+ * <Icon icon={SearchIcon} title="搜尋" />
50
+ * ```
29
51
  */
30
52
  declare const Icon: import("react").ForwardRefExoticComponent<IconProps & import("react").RefAttributes<HTMLElement>>;
31
53
  export default Icon;
package/Icon/Icon.js CHANGED
@@ -4,7 +4,29 @@ import { toIconCssVars, iconClasses } from '@mezzanine-ui/core/icon';
4
4
  import cx from 'clsx';
5
5
 
6
6
  /**
7
- * The react component for `mezzanine` icon.
7
+ * 渲染來自 `@mezzanine-ui/icons` SVG 圖示元件。
8
+ *
9
+ * 透過 `icon` prop 傳入圖示定義物件,支援調整顏色、尺寸與旋轉動畫。
10
+ * 當元件綁定 `onClick` 或 `onMouseOver` 事件時,游標樣式會自動切換為 pointer。
11
+ * 可透過 `title` prop 提供無障礙標題文字。
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * import Icon from '@mezzanine-ui/react/Icon';
16
+ * import { SearchIcon, LoadingIcon, CheckCircleFilledIcon } from '@mezzanine-ui/icons';
17
+ *
18
+ * // 基本用法
19
+ * <Icon icon={SearchIcon} />
20
+ *
21
+ * // 自訂顏色與尺寸
22
+ * <Icon icon={CheckCircleFilledIcon} color="success" size={24} />
23
+ *
24
+ * // 旋轉動畫(常用於載入狀態)
25
+ * <Icon icon={LoadingIcon} spin />
26
+ *
27
+ * // 加入無障礙標題
28
+ * <Icon icon={SearchIcon} title="搜尋" />
29
+ * ```
8
30
  */
9
31
  const Icon = forwardRef(function Icon(props, ref) {
10
32
  const { className, color, icon, size, spin = false, style: styleProp, title, ...rest } = props;
package/Input/Input.d.ts CHANGED
@@ -205,7 +205,37 @@ export type PasswordInputProps = InputBaseProps & ClearableInput & WithPasswordS
205
205
  };
206
206
  export type InputProps = BaseInputProps | WithAffixInputProps | SearchInputProps | NumberInputProps | MeasureInputProps | ActionInputProps | SelectInputProps | PasswordInputProps;
207
207
  /**
208
- * The react component for `mezzanine` input.
208
+ * 多功能輸入框元件,透過 `variant` 支援多種輸入類型。
209
+ *
210
+ * 支援以下八種 variant:`base`(基本輸入)、`affix`(帶前後綴裝飾)、`search`(搜尋,預設帶清除鍵)、
211
+ * `number`(原生數字輸入)、`measure`(格式化數字,可選轉盤按鈕)、`action`(帶操作按鈕)、
212
+ * `select`(帶下拉選單按鈕)、`password`(密碼,可切換可見性並顯示強度指示器)。
213
+ * `measure` variant 會自動以千分位格式化顯示值,並在 `onChange` 時回傳原始數值。
214
+ *
215
+ * @example
216
+ * ```tsx
217
+ * import Input from '@mezzanine-ui/react/Input';
218
+ *
219
+ * // 基本輸入(可清除)
220
+ * <Input variant="base" clearable placeholder="請輸入文字" />
221
+ *
222
+ * // 搜尋輸入
223
+ * <Input variant="search" placeholder="搜尋關鍵字" />
224
+ *
225
+ * // 密碼輸入(含強度指示器)
226
+ * <Input
227
+ * variant="password"
228
+ * placeholder="請輸入密碼"
229
+ * showPasswordStrengthIndicator
230
+ * passwordStrengthIndicator={{ strength: 2 }}
231
+ * />
232
+ *
233
+ * // 數字計量輸入(含轉盤按鈕)
234
+ * <Input variant="measure" suffix="px" showSpinner min={0} max={100} />
235
+ * ```
236
+ *
237
+ * @see {@link FormField} 用於包裹 Input 並提供標籤與錯誤訊息
238
+ * @see {@link TextField} Input 底層使用的文字框容器元件
209
239
  */
210
240
  declare const Input: import("react").ForwardRefExoticComponent<InputProps & import("react").RefAttributes<HTMLDivElement>>;
211
241
  export default Input;
package/Input/Input.js CHANGED
@@ -17,7 +17,37 @@ import PasswordStrengthIndicator from './PasswordStrengthIndicator/PasswordStren
17
17
  import cx from 'clsx';
18
18
 
19
19
  /**
20
- * The react component for `mezzanine` input.
20
+ * 多功能輸入框元件,透過 `variant` 支援多種輸入類型。
21
+ *
22
+ * 支援以下八種 variant:`base`(基本輸入)、`affix`(帶前後綴裝飾)、`search`(搜尋,預設帶清除鍵)、
23
+ * `number`(原生數字輸入)、`measure`(格式化數字,可選轉盤按鈕)、`action`(帶操作按鈕)、
24
+ * `select`(帶下拉選單按鈕)、`password`(密碼,可切換可見性並顯示強度指示器)。
25
+ * `measure` variant 會自動以千分位格式化顯示值,並在 `onChange` 時回傳原始數值。
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * import Input from '@mezzanine-ui/react/Input';
30
+ *
31
+ * // 基本輸入(可清除)
32
+ * <Input variant="base" clearable placeholder="請輸入文字" />
33
+ *
34
+ * // 搜尋輸入
35
+ * <Input variant="search" placeholder="搜尋關鍵字" />
36
+ *
37
+ * // 密碼輸入(含強度指示器)
38
+ * <Input
39
+ * variant="password"
40
+ * placeholder="請輸入密碼"
41
+ * showPasswordStrengthIndicator
42
+ * passwordStrengthIndicator={{ strength: 2 }}
43
+ * />
44
+ *
45
+ * // 數字計量輸入(含轉盤按鈕)
46
+ * <Input variant="measure" suffix="px" showSpinner min={0} max={100} />
47
+ * ```
48
+ *
49
+ * @see {@link FormField} 用於包裹 Input 並提供標籤與錯誤訊息
50
+ * @see {@link TextField} Input 底層使用的文字框容器元件
21
51
  */
22
52
  const Input = forwardRef(function Input(props, ref) {
23
53
  const { active, className, defaultValue, disabled = false, error = false, formatter: formatterProp, fullWidth = true, id, inputProps, inputType, inputRef: inputRefProp, name, onChange: onChangeProp, parser: parserProp, placeholder, readonly, size = 'main', typing, variant = 'base', value: valueProp, } = props;
@@ -8,7 +8,7 @@ import cx from 'clsx';
8
8
 
9
9
  const SpinnerButton = forwardRef(function SpinnerButton(props, ref) {
10
10
  const { className, disabled, size = 'main', type, ...rest } = props;
11
- return (jsx("button", { ref: ref, type: "button", disabled: disabled, className: cx(inputSpinnerButtonClasses.host, disabled && inputSpinnerButtonClasses.disabled, size === 'main' ? inputSpinnerButtonClasses.main : inputSpinnerButtonClasses.sub, className), title: type === 'up' ? 'Increase value' : 'Decrease value', ...rest, children: jsx(Icon, { icon: type === 'up' ? CaretUpFlatIcon : CaretDownFlatIcon }) }));
11
+ return (jsx("button", { ref: ref, type: "button", disabled: disabled, className: cx(inputSpinnerButtonClasses.host, disabled && inputSpinnerButtonClasses.disabled, size === 'main' ? inputSpinnerButtonClasses.main : inputSpinnerButtonClasses.sub, className), "aria-label": type === 'up' ? 'Increase value' : 'Decrease value', title: type === 'up' ? 'Increase value' : 'Decrease value', ...rest, children: jsx(Icon, { "aria-hidden": "true", icon: type === 'up' ? CaretUpFlatIcon : CaretDownFlatIcon }) }));
12
12
  });
13
13
 
14
14
  export { SpinnerButton as default };
@@ -1,7 +1,7 @@
1
1
  import { MessageSeverity } from '@mezzanine-ui/core/message';
2
2
  import { IconDefinition } from '@mezzanine-ui/icons';
3
3
  import type { FC, Key } from 'react';
4
- import { Notifier, NotifierData, NotifierConfig } from '../Notifier';
4
+ import { NotifierData, NotifierConfig } from '../Notifier';
5
5
  import { TranslateProps } from '../Transition';
6
6
  export interface MessageConfigProps extends Pick<NotifierConfig, 'duration'>, Pick<TranslateProps, 'onEnter' | 'onEntering' | 'onEntered' | 'onExit' | 'onExiting' | 'onExited' | 'easing' | 'from'> {
7
7
  }
@@ -25,14 +25,64 @@ export interface MessageData extends Omit<NotifierData, 'onClose'>, MessageConfi
25
25
  */
26
26
  severity?: MessageSeverity;
27
27
  }
28
- export type MessageType = FC<MessageData> & Notifier<MessageData, MessageConfigProps> & Record<string, (message: MessageData['children'], props?: Omit<MessageData, 'children' | 'severity' | 'icon'> & {
28
+ /**
29
+ * Props accepted by Message severity shorthand methods such as `Message.success`.
30
+ * Includes an optional `key` to identify the message for later updates or dismissal.
31
+ */
32
+ export type MessageShorthandProps = Omit<MessageData, 'children' | 'severity' | 'icon'> & {
29
33
  key?: Key;
30
- }) => Key>;
34
+ };
35
+ /**
36
+ * Signature shared by all Message severity shorthand methods.
37
+ * @param message - The notification content.
38
+ * @param props - Optional configuration; mirrors {@link MessageData} minus `children`, `severity`, and `icon`.
39
+ */
40
+ export type MessageShorthandMethod = (message: MessageData['children'], props?: MessageShorthandProps) => Key;
41
+ /** Static severity shorthand methods attached to the {@link Message} component. */
42
+ export interface MessageSeverityMethods {
43
+ /** Display an error message. */
44
+ error: MessageShorthandMethod;
45
+ /** Display an informational message. */
46
+ info: MessageShorthandMethod;
47
+ /** Display a loading message that will **not** auto-close. */
48
+ loading: MessageShorthandMethod;
49
+ /** Display a success message. */
50
+ success: MessageShorthandMethod;
51
+ /** Display a warning message. */
52
+ warning: MessageShorthandMethod;
53
+ }
31
54
  /**
32
55
  * The react component for `mezzanine` message.
33
56
  *
34
- * Use the API from the Message instance such as `Message.add` and `Message.success`
35
- * to display a notification message globally.
57
+ * Trigger messages imperatively via severity shorthand methods:
58
+ *
59
+ * @example
60
+ * ```tsx
61
+ * import Message from '@mezzanine-ui/react/message';
62
+ *
63
+ * Message.success('Saved!');
64
+ * Message.error('Something went wrong.');
65
+ *
66
+ * // With custom key for later update/dismissal
67
+ * const key = Message.loading('Uploading…');
68
+ * Message.success('Done!', { key });
69
+ * ```
70
+ *
71
+ * @see {@link MessageData} for the full set of options accepted by `Message.add`.
36
72
  */
37
- declare const Message: MessageType;
73
+ declare const Message: FC<MessageData> & {
74
+ add: (notifier: MessageData & {
75
+ key?: Key;
76
+ }) => Key;
77
+ config: (configs: MessageConfigProps) => void;
78
+ destroy: VoidFunction;
79
+ remove: (key: Key) => void;
80
+ error: (message: MessageData["children"], props?: MessageShorthandProps) => Key;
81
+ info: (message: MessageData["children"], props?: MessageShorthandProps) => Key;
82
+ loading: (message: MessageData["children"], props?: MessageShorthandProps) => Key;
83
+ success: (message: MessageData["children"], props?: MessageShorthandProps) => Key;
84
+ warning: (message: MessageData["children"], props?: MessageShorthandProps) => Key;
85
+ };
86
+ /** Full type of the {@link Message} component including all static notification API methods. */
87
+ export type MessageType = typeof Message;
38
88
  export default Message;
@@ -1,25 +1,21 @@
1
1
  'use client';
2
2
  import { useState, useRef, useCallback, useEffect, createElement } from 'react';
3
3
  import { jsx, jsxs } from 'react/jsx-runtime';
4
- import { messageClasses, messageIcons } from '@mezzanine-ui/core/message';
4
+ import { messageIcons, messageClasses } from '@mezzanine-ui/core/message';
5
5
  import { messageTimerController } from './MessageTimerController.js';
6
6
  import Translate from '../Transition/Translate.js';
7
+ import Spin from '../Spin/Spin.js';
7
8
  import Icon from '../Icon/Icon.js';
8
- import cx from 'clsx';
9
9
  import { createNotifier } from '../Notifier/createNotifier.js';
10
+ import cx from 'clsx';
10
11
 
11
- /**
12
- * The react component for `mezzanine` message.
13
- *
14
- * Use the API from the Message instance such as `Message.add` and `Message.success`
15
- * to display a notification message globally.
16
- */
17
- const Message = ((props) => {
12
+ /** @internal Underlying React element rendered by the Message notifier. */
13
+ const MessageFC = (props) => {
18
14
  const { children, duration, icon, reference, severity, onExited: onExitedProp, ...restTransitionProps } = props;
19
15
  const [open, setOpen] = useState(true);
20
16
  const timerRef = useRef(null);
21
17
  const remainingTimeRef = useRef(duration || 0);
22
- const startTimeRef = useRef(Date.now());
18
+ const startTimeRef = useRef(0);
23
19
  // 清理計時器
24
20
  const clearTimer = useCallback(() => {
25
21
  if (timerRef.current) {
@@ -102,59 +98,70 @@ const Message = ((props) => {
102
98
  const handleBlur = () => {
103
99
  messageTimerController.resume();
104
100
  };
105
- return (jsx(Translate, { in: open, appear: true, onExited: onExited, from: "bottom", ...restTransitionProps, children: jsxs("div", { className: cx(messageClasses.host, severity ? messageClasses.severity(severity) : ''), onBlur: handleBlur, onFocus: handleFocus, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, role: "status", children: [icon ? (jsx(Icon, { className: messageClasses.icon, icon: icon, spin: severity === 'loading' })) : null, jsx("span", { className: messageClasses.content, children: children })] }) }));
106
- });
101
+ return (jsx(Translate, { in: open, appear: true, onExited: onExited, from: "bottom", ...restTransitionProps, children: jsxs("div", { className: cx(messageClasses.host, severity ? messageClasses.severity(severity) : ''), onBlur: handleBlur, onFocus: handleFocus, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, role: "status", children: [severity === 'loading' ? (jsx("span", { className: messageClasses.icon, children: jsx(Spin, { loading: true, size: "minor" }) })) : icon ? (jsx(Icon, { className: messageClasses.icon, icon: icon })) : null, jsx("span", { className: messageClasses.content, children: children })] }) }));
102
+ };
107
103
  const { add, config, destroy, remove } = createNotifier({
108
104
  duration: 3000,
109
105
  maxCount: 4,
110
- render: (message) => (createElement(Message, { ...message, reference: message.key, key: undefined })),
106
+ render: (message) => (createElement(MessageFC, { ...message, reference: message.key, key: undefined })),
111
107
  setRoot: (root) => {
112
108
  root === null || root === void 0 ? void 0 : root.setAttribute('class', messageClasses.root);
113
109
  },
114
110
  });
115
- Message.add = add;
116
- Message.config = config;
117
- Message.destroy = destroy;
118
- Message.remove = remove;
119
- const severities = [
120
- {
121
- key: 'success',
122
- icon: messageIcons.success,
123
- },
124
- {
125
- key: 'warning',
126
- icon: messageIcons.warning,
127
- },
128
- {
129
- key: 'error',
111
+ /**
112
+ * The react component for `mezzanine` message.
113
+ *
114
+ * Trigger messages imperatively via severity shorthand methods:
115
+ *
116
+ * @example
117
+ * ```tsx
118
+ * import Message from '@mezzanine-ui/react/message';
119
+ *
120
+ * Message.success('Saved!');
121
+ * Message.error('Something went wrong.');
122
+ *
123
+ * // With custom key for later update/dismissal
124
+ * const key = Message.loading('Uploading…');
125
+ * Message.success('Done!', { key });
126
+ * ```
127
+ *
128
+ * @see {@link MessageData} for the full set of options accepted by `Message.add`.
129
+ */
130
+ const Message = Object.assign(MessageFC, {
131
+ add,
132
+ config,
133
+ destroy,
134
+ remove,
135
+ error: (message, props) => add({
136
+ ...props,
137
+ children: message,
130
138
  icon: messageIcons.error,
131
- },
132
- {
133
- key: 'info',
139
+ severity: 'error',
140
+ }),
141
+ info: (message, props) => add({
142
+ ...props,
143
+ children: message,
134
144
  icon: messageIcons.info,
135
- },
136
- {
137
- key: 'loading',
138
- icon: messageIcons.loading,
139
- },
140
- ];
141
- const validSeverities = [
142
- 'success',
143
- 'warning',
144
- 'error',
145
- 'info',
146
- 'loading',
147
- ];
148
- severities.forEach((severity) => {
149
- Message[severity.key] = (message, props) => Message.add({
145
+ severity: 'info',
146
+ }),
147
+ loading: (message, props) => add({
148
+ ...props,
149
+ children: message,
150
+ severity: 'loading',
151
+ duration: false,
152
+ }),
153
+ success: (message, props) => add({
150
154
  ...props,
151
155
  children: message,
152
- severity: validSeverities.includes(severity.key)
153
- ? severity.key
154
- : undefined,
155
- icon: severity.icon,
156
- duration: severity.key === 'loading' ? false : props === null || props === void 0 ? void 0 : props.duration,
157
- });
156
+ icon: messageIcons.success,
157
+ severity: 'success',
158
+ }),
159
+ warning: (message, props) => add({
160
+ ...props,
161
+ children: message,
162
+ icon: messageIcons.warning,
163
+ severity: 'warning',
164
+ }),
158
165
  });
159
166
 
160
167
  export { Message as default };