@mezzanine-ui/react 1.0.0-beta.5 → 1.0.0-beta.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 (199) hide show
  1. package/Accordion/Accordion.d.ts +23 -1
  2. package/Accordion/Accordion.js +59 -11
  3. package/Accordion/AccordionActions.d.ts +13 -0
  4. package/Accordion/AccordionActions.js +24 -0
  5. package/Accordion/AccordionContent.d.ts +9 -0
  6. package/Accordion/{AccordionDetails.js → AccordionContent.js} +4 -6
  7. package/Accordion/AccordionControlContext.d.ts +2 -2
  8. package/Accordion/AccordionGroup.d.ts +10 -0
  9. package/Accordion/AccordionGroup.js +26 -0
  10. package/Accordion/AccordionTitle.d.ts +14 -0
  11. package/Accordion/AccordionTitle.js +56 -0
  12. package/Accordion/index.d.ts +8 -4
  13. package/Accordion/index.js +4 -2
  14. package/AutoComplete/AutoComplete.d.ts +25 -6
  15. package/AutoComplete/AutoComplete.js +119 -30
  16. package/Backdrop/Backdrop.js +15 -19
  17. package/Breadcrumb/BreadcrumbDropdown.js +1 -1
  18. package/Breadcrumb/BreadcrumbItem.js +1 -1
  19. package/Breadcrumb/BreadcrumbOverflowMenuItem.js +1 -1
  20. package/Calendar/CalendarDays.js +1 -1
  21. package/Card/BaseCard.d.ts +11 -0
  22. package/Card/BaseCard.js +48 -0
  23. package/Card/BaseCardSkeleton.d.ts +14 -0
  24. package/Card/BaseCardSkeleton.js +18 -0
  25. package/Card/CardGroup.d.ts +47 -0
  26. package/Card/CardGroup.js +147 -0
  27. package/Card/FourThumbnailCard.d.ts +14 -0
  28. package/Card/FourThumbnailCard.js +73 -0
  29. package/Card/FourThumbnailCardSkeleton.d.ts +14 -0
  30. package/Card/FourThumbnailCardSkeleton.js +20 -0
  31. package/Card/QuickActionCard.d.ts +12 -0
  32. package/Card/QuickActionCard.js +23 -0
  33. package/Card/QuickActionCardSkeleton.d.ts +14 -0
  34. package/Card/QuickActionCardSkeleton.js +18 -0
  35. package/Card/SingleThumbnailCard.d.ts +13 -0
  36. package/Card/SingleThumbnailCard.js +44 -0
  37. package/Card/SingleThumbnailCardSkeleton.d.ts +19 -0
  38. package/Card/SingleThumbnailCardSkeleton.js +18 -0
  39. package/Card/Thumbnail.d.ts +12 -0
  40. package/Card/Thumbnail.js +18 -0
  41. package/Card/ThumbnailCardInfo.d.ts +34 -0
  42. package/Card/ThumbnailCardInfo.js +43 -0
  43. package/Card/index.d.ts +43 -4
  44. package/Card/index.js +19 -2
  45. package/Card/typings.d.ts +442 -0
  46. package/Checkbox/Checkbox.d.ts +8 -0
  47. package/Checkbox/Checkbox.js +3 -2
  48. package/Checkbox/CheckboxGroup.js +1 -1
  49. package/ContentHeader/ContentHeader.d.ts +22 -70
  50. package/ContentHeader/ContentHeader.js +1 -1
  51. package/ContentHeader/ContentHeaderResponsive.d.ts +9 -0
  52. package/ContentHeader/ContentHeaderResponsive.js +7 -0
  53. package/ContentHeader/utils.d.ts +3 -3
  54. package/ContentHeader/utils.js +66 -20
  55. package/Cropper/Cropper.d.ts +66 -0
  56. package/Cropper/Cropper.js +115 -0
  57. package/Cropper/CropperElement.d.ts +10 -0
  58. package/Cropper/CropperElement.js +892 -0
  59. package/Cropper/index.d.ts +18 -0
  60. package/Cropper/index.js +8 -0
  61. package/Cropper/tools.d.ts +90 -0
  62. package/Cropper/tools.js +143 -0
  63. package/Cropper/typings.d.ts +69 -0
  64. package/Cropper/utils/cropper-calculations.d.ts +39 -0
  65. package/Cropper/utils/cropper-calculations.js +95 -0
  66. package/DateTimePicker/DateTimePicker.d.ts +1 -1
  67. package/DateTimePicker/DateTimePicker.js +22 -5
  68. package/DateTimeRangePicker/DateTimeRangePicker.d.ts +34 -0
  69. package/DateTimeRangePicker/DateTimeRangePicker.js +118 -0
  70. package/DateTimeRangePicker/index.d.ts +2 -0
  71. package/DateTimeRangePicker/index.js +1 -0
  72. package/Drawer/Drawer.d.ts +132 -1
  73. package/Drawer/Drawer.js +47 -3
  74. package/Dropdown/Dropdown.d.ts +10 -4
  75. package/Dropdown/Dropdown.js +37 -42
  76. package/Dropdown/DropdownItem.d.ts +7 -1
  77. package/Dropdown/DropdownItem.js +36 -6
  78. package/Dropdown/DropdownItemCard.js +2 -1
  79. package/FloatingButton/FloatingButton.d.ts +21 -0
  80. package/FloatingButton/FloatingButton.js +18 -0
  81. package/FloatingButton/index.d.ts +2 -0
  82. package/FloatingButton/index.js +1 -0
  83. package/Form/FormField.d.ts +30 -7
  84. package/Form/FormField.js +12 -4
  85. package/Input/Input.js +12 -21
  86. package/Input/SelectButton/SelectButton.d.ts +25 -4
  87. package/Input/SelectButton/SelectButton.js +21 -9
  88. package/Message/Message.js +1 -1
  89. package/Modal/MediaPreviewModal.d.ts +11 -0
  90. package/Modal/MediaPreviewModal.js +24 -7
  91. package/Modal/Modal.d.ts +1 -1
  92. package/Modal/Modal.js +1 -1
  93. package/Modal/useModalContainer.js +6 -2
  94. package/MultipleDatePicker/MultipleDatePicker.d.ts +62 -0
  95. package/MultipleDatePicker/MultipleDatePicker.js +176 -0
  96. package/MultipleDatePicker/MultipleDatePickerTrigger.d.ts +56 -0
  97. package/MultipleDatePicker/MultipleDatePickerTrigger.js +92 -0
  98. package/MultipleDatePicker/index.d.ts +6 -0
  99. package/MultipleDatePicker/index.js +3 -0
  100. package/MultipleDatePicker/useMultipleDatePickerValue.d.ts +55 -0
  101. package/MultipleDatePicker/useMultipleDatePickerValue.js +68 -0
  102. package/Navigation/NavigationHeader.js +1 -1
  103. package/NotificationCenter/NotificationCenterDrawer.d.ts +10 -52
  104. package/NotificationCenter/NotificationCenterDrawer.js +128 -0
  105. package/NotificationCenter/index.d.ts +2 -0
  106. package/NotificationCenter/index.js +1 -0
  107. package/OverflowTooltip/index.d.ts +2 -2
  108. package/Picker/FormattedInput.d.ts +1 -1
  109. package/Picker/FormattedInput.js +2 -1
  110. package/Picker/PickerTriggerWithSeparator.d.ts +10 -0
  111. package/Picker/PickerTriggerWithSeparator.js +2 -2
  112. package/Picker/RangePickerTrigger.js +1 -1
  113. package/Picker/useDateInputFormatter.d.ts +6 -0
  114. package/Picker/useDateInputFormatter.js +4 -1
  115. package/Section/Section.d.ts +32 -0
  116. package/Section/Section.js +62 -0
  117. package/Section/index.d.ts +2 -0
  118. package/Select/Select.d.ts +11 -12
  119. package/Select/Select.js +13 -34
  120. package/Select/SelectTrigger.js +21 -7
  121. package/Select/index.d.ts +0 -4
  122. package/Select/index.js +0 -2
  123. package/Select/typings.d.ts +0 -4
  124. package/Select/useSelectTriggerTags.d.ts +1 -1
  125. package/Select/useSelectTriggerTags.js +9 -6
  126. package/Separator/Separator.d.ts +14 -0
  127. package/Separator/Separator.js +17 -0
  128. package/Separator/index.d.ts +2 -0
  129. package/Separator/index.js +1 -0
  130. package/Table/utils/useTableRowSelection.js +6 -0
  131. package/Tag/TagGroup.d.ts +4 -2
  132. package/Tag/TagGroup.js +7 -4
  133. package/TextField/TextField.d.ts +1 -1
  134. package/TextField/TextField.js +63 -9
  135. package/TimePanel/TimePanelColumn.js +30 -21
  136. package/TimeRangePicker/TimeRangePicker.d.ts +29 -0
  137. package/TimeRangePicker/TimeRangePicker.js +96 -0
  138. package/TimeRangePicker/index.d.ts +3 -0
  139. package/TimeRangePicker/index.js +2 -0
  140. package/TimeRangePicker/useTimeRangePickerValue.d.ts +30 -0
  141. package/TimeRangePicker/useTimeRangePickerValue.js +92 -0
  142. package/Transition/Rotate.js +2 -5
  143. package/index.d.ts +30 -28
  144. package/index.js +26 -27
  145. package/package.json +4 -4
  146. package/Accordion/AccordionDetails.d.ts +0 -9
  147. package/Accordion/AccordionSummary.d.ts +0 -18
  148. package/Accordion/AccordionSummary.js +0 -51
  149. package/Alert/Alert.d.ts +0 -20
  150. package/Alert/Alert.js +0 -18
  151. package/Alert/index.d.ts +0 -3
  152. package/Alert/index.js +0 -1
  153. package/AppBar/AppBar.d.ts +0 -14
  154. package/AppBar/AppBar.js +0 -33
  155. package/AppBar/AppBarBrand.d.ts +0 -4
  156. package/AppBar/AppBarBrand.js +0 -11
  157. package/AppBar/AppBarMain.d.ts +0 -4
  158. package/AppBar/AppBarMain.js +0 -11
  159. package/AppBar/AppBarSupport.d.ts +0 -4
  160. package/AppBar/AppBarSupport.js +0 -11
  161. package/AppBar/index.d.ts +0 -8
  162. package/AppBar/index.js +0 -4
  163. package/Card/Card.d.ts +0 -51
  164. package/Card/Card.js +0 -20
  165. package/Card/CardActions.d.ts +0 -34
  166. package/Card/CardActions.js +0 -15
  167. package/ConfirmActions/ConfirmActions.d.ts +0 -46
  168. package/ConfirmActions/ConfirmActions.js +0 -15
  169. package/ConfirmActions/index.d.ts +0 -2
  170. package/ConfirmActions/index.js +0 -1
  171. package/Popconfirm/Popconfirm.d.ts +0 -16
  172. package/Popconfirm/Popconfirm.js +0 -15
  173. package/Popconfirm/index.d.ts +0 -2
  174. package/Popconfirm/index.js +0 -1
  175. package/Popover/Popover.d.ts +0 -23
  176. package/Popover/Popover.js +0 -35
  177. package/Popover/index.d.ts +0 -2
  178. package/Popover/index.js +0 -1
  179. package/Select/Option.d.ts +0 -18
  180. package/Select/Option.js +0 -45
  181. package/Select/TreeSelect.d.ts +0 -67
  182. package/Select/TreeSelect.js +0 -198
  183. package/Tree/Tree.d.ts +0 -70
  184. package/Tree/Tree.js +0 -139
  185. package/Tree/TreeNode.d.ts +0 -40
  186. package/Tree/TreeNode.js +0 -50
  187. package/Tree/TreeNodeList.d.ts +0 -24
  188. package/Tree/TreeNodeList.js +0 -28
  189. package/Tree/getTreeNodeEntities.d.ts +0 -11
  190. package/Tree/getTreeNodeEntities.js +0 -92
  191. package/Tree/index.d.ts +0 -13
  192. package/Tree/index.js +0 -7
  193. package/Tree/toggleValue.d.ts +0 -4
  194. package/Tree/toggleValue.js +0 -19
  195. package/Tree/traverseTree.d.ts +0 -2
  196. package/Tree/traverseTree.js +0 -11
  197. package/Tree/typings.d.ts +0 -16
  198. package/Tree/useTreeExpandedValue.d.ts +0 -14
  199. package/Tree/useTreeExpandedValue.js +0 -33
@@ -0,0 +1,176 @@
1
+ 'use client';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+ import { getDefaultModeFormat, calendarClasses } from '@mezzanine-ui/core/calendar';
4
+ import { multipleDatePickerClasses } from '@mezzanine-ui/core/multiple-date-picker';
5
+ import { CalendarIcon } from '@mezzanine-ui/icons';
6
+ import { forwardRef, useState, useCallback, useEffect, useMemo, useRef } from 'react';
7
+ import CalendarFooterActions from '../Calendar/CalendarFooterActions.js';
8
+ import { useComposeRefs } from '../hooks/useComposeRefs.js';
9
+ import MultipleDatePickerTrigger from './MultipleDatePickerTrigger.js';
10
+ import { useMultipleDatePickerValue } from './useMultipleDatePickerValue.js';
11
+ import { useCalendarContext } from '../Calendar/CalendarContext.js';
12
+ import { useCalendarControls } from '../Calendar/useCalendarControls.js';
13
+ import { usePickerDocumentEventClose } from '../Picker/usePickerDocumentEventClose.js';
14
+ import Icon from '../Icon/Icon.js';
15
+ import InputTriggerPopper from '../_internal/InputTriggerPopper/InputTriggerPopper.js';
16
+ import Calendar from '../Calendar/Calendar.js';
17
+ import cx from 'clsx';
18
+
19
+ /**
20
+ * The react component for `mezzanine` multiple date picker.
21
+ * Allows selecting multiple dates from a calendar with manual confirmation.
22
+ * Notice that any component related to date-picker should be used along with `CalendarContext`.
23
+ */
24
+ const MultipleDatePicker = forwardRef(function MultipleDatePicker(props, ref) {
25
+ const { getNow, locale } = useCalendarContext();
26
+ const { actions: actionsProp, calendarProps, className, clearable = true, disabledMonthSwitch = false, disableOnDoubleNext, disableOnDoublePrev, disableOnNext, disableOnPrev, disabledYearSwitch = false, disabled = false, displayMonthLocale = locale, error = false, format: formatProp, fullWidth = false, isDateDisabled: isDateDisabledProp, maxSelections, onCalendarToggle: onCalendarToggleProp, onChange: onChangeProp, overflowStrategy = 'counter', placeholder, popperProps, prefix, required, readOnly = false, referenceDate: referenceDateProp, size = 'main', value = [], } = props;
27
+ const format = formatProp || getDefaultModeFormat('day');
28
+ const { className: calendarClassName, ...restCalendarProps } = calendarProps || {};
29
+ // Calendar open state
30
+ const [open, setOpen] = useState(false);
31
+ const preventOpen = readOnly || disabled;
32
+ const onCalendarToggle = useCallback((currentOpen) => {
33
+ if (!preventOpen) {
34
+ setOpen(currentOpen);
35
+ onCalendarToggleProp === null || onCalendarToggleProp === void 0 ? void 0 : onCalendarToggleProp(currentOpen);
36
+ }
37
+ }, [onCalendarToggleProp, preventOpen]);
38
+ // Value management hook
39
+ const { clearAll, formatDate, getConfirmValue, internalValue, isDateSelected, isMaxReached, removeDate, revertToValue, toggleDate, } = useMultipleDatePickerValue({
40
+ format,
41
+ maxSelections,
42
+ value,
43
+ });
44
+ // Manage referenceDate internally for stable value
45
+ const [internalReferenceDate, setInternalReferenceDate] = useState(() => referenceDateProp || getNow());
46
+ // Sync referenceDate when prop changes
47
+ useEffect(() => {
48
+ if (referenceDateProp) {
49
+ setInternalReferenceDate(referenceDateProp);
50
+ }
51
+ }, [referenceDateProp]);
52
+ // Calendar controls - pass stable referenceDate
53
+ const { currentMode, onMonthControlClick, onNext, onPrev, onDoublePrev, onDoubleNext, onYearControlClick, popModeStack, referenceDate, updateReferenceDate, } = useCalendarControls(internalReferenceDate, 'day');
54
+ // Handle mode switching (month/year selection) with value transformation
55
+ const createModeChangeHandler = useMemo(() => {
56
+ return (transformValue) => {
57
+ return (target) => {
58
+ const result = transformValue
59
+ ? transformValue(target, referenceDate)
60
+ : target;
61
+ updateReferenceDate(result);
62
+ popModeStack();
63
+ };
64
+ };
65
+ }, [referenceDate, updateReferenceDate, popModeStack]);
66
+ // Convert internalValue to DateValue[] for trigger display
67
+ const triggerValues = useMemo(() => internalValue.map((date) => ({
68
+ date,
69
+ id: formatDate(date),
70
+ name: formatDate(date),
71
+ })), [internalValue, formatDate]);
72
+ // Handle calendar date click - toggle selection (only in day mode)
73
+ const onCalendarDateChange = useCallback((date) => {
74
+ if (currentMode === 'day') {
75
+ toggleDate(date);
76
+ }
77
+ else {
78
+ // Handle month/year mode switching
79
+ createModeChangeHandler()(date);
80
+ }
81
+ }, [currentMode, toggleDate, createModeChangeHandler]);
82
+ // Handle tag close - remove date
83
+ const onTagClose = useCallback((date) => {
84
+ removeDate(date);
85
+ }, [removeDate]);
86
+ // Handle confirm action
87
+ const onConfirm = useCallback(() => {
88
+ const confirmedValue = getConfirmValue();
89
+ onChangeProp === null || onChangeProp === void 0 ? void 0 : onChangeProp(confirmedValue);
90
+ onCalendarToggle(false);
91
+ }, [getConfirmValue, onChangeProp, onCalendarToggle]);
92
+ // Handle cancel action
93
+ const onCancel = useCallback(() => {
94
+ revertToValue();
95
+ onCalendarToggle(false);
96
+ }, [revertToValue, onCalendarToggle]);
97
+ // Handle clear
98
+ const onClear = useCallback((e) => {
99
+ e.stopPropagation();
100
+ clearAll();
101
+ onChangeProp === null || onChangeProp === void 0 ? void 0 : onChangeProp([]);
102
+ }, [clearAll, onChangeProp]);
103
+ // Auto-generate actions
104
+ const actions = useMemo(() => {
105
+ const hasValue = internalValue.length > 0;
106
+ return {
107
+ primaryButtonProps: {
108
+ children: 'Confirm',
109
+ disabled: !hasValue,
110
+ onClick: onConfirm,
111
+ ...actionsProp === null || actionsProp === void 0 ? void 0 : actionsProp.primaryButtonProps,
112
+ },
113
+ secondaryButtonProps: {
114
+ children: 'Cancel',
115
+ onClick: onCancel,
116
+ ...actionsProp === null || actionsProp === void 0 ? void 0 : actionsProp.secondaryButtonProps,
117
+ },
118
+ };
119
+ }, [actionsProp, internalValue.length, onConfirm, onCancel]);
120
+ // Enhanced isDateDisabled - disable unselected dates when max is reached
121
+ const isDateDisabled = useCallback((date) => {
122
+ // Check user-provided disabled function first
123
+ if (isDateDisabledProp === null || isDateDisabledProp === void 0 ? void 0 : isDateDisabledProp(date)) {
124
+ return true;
125
+ }
126
+ // If max is reached and date is not already selected, disable it
127
+ if (isMaxReached && !isDateSelected(date)) {
128
+ return true;
129
+ }
130
+ return false;
131
+ }, [isDateDisabledProp, isDateSelected, isMaxReached]);
132
+ // Refs for popper positioning
133
+ const anchorRef = useRef(null);
134
+ const calendarRef = useRef(null);
135
+ const triggerComposedRef = useComposeRefs([ref, anchorRef]);
136
+ // Close handlers for click-away and escape
137
+ const onClose = useCallback(() => {
138
+ revertToValue();
139
+ onCalendarToggle(false);
140
+ }, [revertToValue, onCalendarToggle]);
141
+ const onChangeClose = useCallback(() => {
142
+ // In manual mode, always revert on click-away (don't auto-submit)
143
+ revertToValue();
144
+ onCalendarToggle(false);
145
+ }, [revertToValue, onCalendarToggle]);
146
+ // Use a dummy ref for lastElementRefInFlow since we don't have a focusable input
147
+ const dummyRef = useRef(null);
148
+ usePickerDocumentEventClose({
149
+ anchorRef,
150
+ lastElementRefInFlow: dummyRef,
151
+ onChangeClose,
152
+ onClose,
153
+ open,
154
+ popperRef: calendarRef,
155
+ });
156
+ // Icon click handler
157
+ const onIconClick = useCallback((e) => {
158
+ e.stopPropagation();
159
+ if (open) {
160
+ revertToValue();
161
+ }
162
+ onCalendarToggle(!open);
163
+ }, [open, revertToValue, onCalendarToggle]);
164
+ const suffixActionIcon = (jsx(Icon, { "aria-label": "Open calendar", icon: CalendarIcon, onClick: readOnly || disabled ? undefined : onIconClick }));
165
+ // Trigger click handler
166
+ const onTriggerClick = useCallback(() => {
167
+ if (!preventOpen && !open) {
168
+ onCalendarToggle(true);
169
+ }
170
+ }, [preventOpen, open, onCalendarToggle]);
171
+ return (jsxs(Fragment, { children: [jsx(MultipleDatePickerTrigger, { active: open, className: cx(multipleDatePickerClasses.host, className, {
172
+ [multipleDatePickerClasses.hostFullWidth]: fullWidth,
173
+ }), clearable: clearable, disabled: disabled, error: error, fullWidth: fullWidth, onClick: onTriggerClick, onClear: onClear, onTagClose: onTagClose, overflowStrategy: overflowStrategy, placeholder: placeholder, prefix: prefix, readOnly: readOnly, ref: triggerComposedRef, required: required, size: size, suffix: suffixActionIcon, value: triggerValues }), jsx(InputTriggerPopper, { ...popperProps, anchor: anchorRef, open: open, ref: calendarRef, children: jsx("div", { className: calendarClasses.host, children: jsxs("div", { className: calendarClasses.mainWithFooter, children: [jsx(Calendar, { ...restCalendarProps, className: cx(calendarClasses.noShadowHost, calendarClassName), disabledFooterControl: true, disabledMonthSwitch: disabledMonthSwitch, disableOnDoubleNext: disableOnDoubleNext, disableOnDoublePrev: disableOnDoublePrev, disableOnNext: disableOnNext, disableOnPrev: disableOnPrev, disabledYearSwitch: disabledYearSwitch, displayMonthLocale: displayMonthLocale, isDateDisabled: isDateDisabled, mode: currentMode, onChange: onCalendarDateChange, onMonthControlClick: onMonthControlClick, onNext: onNext, onDoubleNext: onDoubleNext, onPrev: onPrev, onDoublePrev: onDoublePrev, onYearControlClick: onYearControlClick, referenceDate: referenceDate, value: internalValue }), jsx(CalendarFooterActions, { actions: actions })] }) }) })] }));
174
+ });
175
+
176
+ export { MultipleDatePicker as default };
@@ -0,0 +1,56 @@
1
+ import { ReactNode } from 'react';
2
+ import { DateType } from '@mezzanine-ui/core/calendar';
3
+ import { TextFieldProps } from '../TextField';
4
+ export interface DateValue {
5
+ id: string;
6
+ name: string;
7
+ date: DateType;
8
+ }
9
+ export interface MultipleDatePickerTriggerProps extends Omit<TextFieldProps, 'active' | 'children' | 'defaultChecked' | 'disabled' | 'readonly' | 'typing'> {
10
+ /**
11
+ * Whether the panel is currently open (for styling)
12
+ */
13
+ active?: boolean;
14
+ /**
15
+ * Whether the trigger is disabled.
16
+ * @default false
17
+ */
18
+ disabled?: boolean;
19
+ /**
20
+ * Callback when a tag is closed (date removed)
21
+ */
22
+ onTagClose?: (date: DateType) => void;
23
+ /**
24
+ * Overflow strategy for tags display
25
+ * @default 'counter'
26
+ */
27
+ overflowStrategy?: 'counter' | 'wrap';
28
+ /**
29
+ * Placeholder text when no dates are selected
30
+ */
31
+ placeholder?: string;
32
+ /**
33
+ * Whether the trigger is readonly.
34
+ * @default false
35
+ */
36
+ readOnly?: boolean;
37
+ /**
38
+ * Whether the input is required.
39
+ * @default false
40
+ */
41
+ required?: boolean;
42
+ /**
43
+ * Custom suffix element (e.g., calendar icon)
44
+ */
45
+ suffix?: ReactNode;
46
+ /**
47
+ * The selected date values for display
48
+ */
49
+ value?: DateValue[];
50
+ }
51
+ /**
52
+ * The trigger component for MultipleDatePicker.
53
+ * Displays selected dates as tags within a TextField.
54
+ */
55
+ declare const MultipleDatePickerTrigger: import("react").ForwardRefExoticComponent<MultipleDatePickerTriggerProps & import("react").RefAttributes<HTMLDivElement>>;
56
+ export default MultipleDatePickerTrigger;
@@ -0,0 +1,92 @@
1
+ 'use client';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+ import { forwardRef, useRef, useMemo, useCallback } from 'react';
4
+ import { multipleDatePickerClasses } from '@mezzanine-ui/core/multiple-date-picker';
5
+ import TagGroup from '../Tag/TagGroup.js';
6
+ import { useSelectTriggerTags } from '../Select/useSelectTriggerTags.js';
7
+ import Tag from '../Tag/Tag.js';
8
+ import OverflowCounterTag from '../OverflowTooltip/OverflowCounterTag.js';
9
+ import TextField from '../TextField/TextField.js';
10
+ import cx from 'clsx';
11
+
12
+ /**
13
+ * The trigger component for MultipleDatePicker.
14
+ * Displays selected dates as tags within a TextField.
15
+ */
16
+ const MultipleDatePickerTrigger = forwardRef(function MultipleDatePickerTrigger(props, ref) {
17
+ const { active = false, className, clearable = true, disabled = false, error = false, fullWidth = false, onTagClose, overflowStrategy = 'counter', placeholder, readOnly = false, required = false, size = 'main', suffix, value = [], ...restTextFieldProps } = props;
18
+ const tagsContainerRef = useRef(null);
19
+ const tagsRef = useRef(null);
20
+ const tagSize = size === 'main' ? 'main' : 'sub';
21
+ // Convert DateValue[] to SelectValue[] for useSelectTriggerTags
22
+ const selectValues = useMemo(() => value.map((v) => ({ id: v.id, name: v.name })), [value]);
23
+ const { overflowSelections, renderFakeTags, visibleSelections } = useSelectTriggerTags({
24
+ containerRef: tagsContainerRef,
25
+ enabled: overflowStrategy === 'counter',
26
+ size: tagSize,
27
+ tagsRef,
28
+ value: selectValues,
29
+ });
30
+ const displaySelections = useMemo(() => (overflowStrategy === 'counter' ? visibleSelections : selectValues), [overflowStrategy, selectValues, visibleSelections]);
31
+ // Find the original DateValue by id
32
+ const findDateValue = useCallback((id) => value.find((v) => v.id === id), [value]);
33
+ const handleTagClose = useCallback((id) => (e) => {
34
+ e.stopPropagation();
35
+ const dateValue = findDateValue(id);
36
+ if (dateValue && onTagClose) {
37
+ onTagClose(dateValue.date);
38
+ }
39
+ }, [findDateValue, onTagClose]);
40
+ const tagChildren = useMemo(() => {
41
+ const tags = displaySelections.map((selection) => {
42
+ if (readOnly) {
43
+ return (jsx(Tag, { label: selection.name, readOnly: true, size: tagSize, type: "static" }, selection.id));
44
+ }
45
+ return (jsx(Tag, { disabled: disabled, label: selection.name, onClose: handleTagClose(selection.id), size: tagSize, type: "dismissable" }, selection.id));
46
+ });
47
+ if (overflowStrategy === 'counter' && overflowSelections.length) {
48
+ tags.push(jsx(OverflowCounterTag, { disabled: disabled, onClick: (e) => {
49
+ e.stopPropagation();
50
+ }, onTagDismiss: (tagIndex) => {
51
+ const target = overflowSelections[tagIndex];
52
+ if (!target)
53
+ return;
54
+ const dateValue = findDateValue(target.id);
55
+ if (dateValue && onTagClose) {
56
+ onTagClose(dateValue.date);
57
+ }
58
+ }, readOnly: readOnly, tagSize: tagSize, tags: overflowSelections.map((s) => s.name) }, "overflow-counter"));
59
+ }
60
+ return tags;
61
+ }, [
62
+ disabled,
63
+ displaySelections,
64
+ findDateValue,
65
+ handleTagClose,
66
+ onTagClose,
67
+ overflowSelections,
68
+ overflowStrategy,
69
+ readOnly,
70
+ tagSize,
71
+ ]);
72
+ const hasValue = value.length > 0;
73
+ // TextField requires disabled and readonly to be mutually exclusive
74
+ let interactiveProps = {};
75
+ if (disabled) {
76
+ interactiveProps = { disabled: true };
77
+ }
78
+ else if (readOnly) {
79
+ interactiveProps = { readonly: true };
80
+ }
81
+ return (jsx(TextField, { ...restTextFieldProps, ...interactiveProps, active: active, className: cx(multipleDatePickerClasses.trigger, {
82
+ [multipleDatePickerClasses.triggerSelected]: hasValue,
83
+ [multipleDatePickerClasses.triggerDisabled]: disabled,
84
+ [multipleDatePickerClasses.triggerReadOnly]: readOnly,
85
+ }, className), clearable: !readOnly && clearable && hasValue, error: error, fullWidth: fullWidth, ref: ref, size: size, suffix: suffix, children: jsx("div", { ref: tagsContainerRef, className: cx(multipleDatePickerClasses.triggerTagsWrapper, {
86
+ [multipleDatePickerClasses.triggerTagsWrapperEllipsis]: overflowStrategy === 'counter',
87
+ }), children: hasValue ? (jsxs(Fragment, { children: [jsxs("div", { className: cx(multipleDatePickerClasses.triggerTags, {
88
+ [multipleDatePickerClasses.triggerTagsEllipsis]: overflowStrategy === 'counter',
89
+ }), ref: tagsRef, children: [jsx(TagGroup, { children: tagChildren }), overflowStrategy === 'counter' ? renderFakeTags() : null] }), jsx("input", { "aria-disabled": disabled, "aria-multiline": false, "aria-readonly": readOnly, "aria-required": required, className: cx(multipleDatePickerClasses.triggerInput, multipleDatePickerClasses.triggerInputAbsolute), disabled: disabled, readOnly: true, tabIndex: -1, type: "text", value: "" })] })) : (jsx("input", { "aria-disabled": disabled, "aria-multiline": false, "aria-readonly": readOnly, "aria-required": required, className: multipleDatePickerClasses.triggerInput, disabled: disabled, placeholder: placeholder, readOnly: true, tabIndex: -1, type: "text", value: "" })) }) }));
90
+ });
91
+
92
+ export { MultipleDatePickerTrigger as default };
@@ -0,0 +1,6 @@
1
+ export { default } from './MultipleDatePicker';
2
+ export type { MultipleDatePickerProps } from './MultipleDatePicker';
3
+ export { default as MultipleDatePickerTrigger } from './MultipleDatePickerTrigger';
4
+ export type { DateValue as MultipleDatePickerDateValue, MultipleDatePickerTriggerProps, } from './MultipleDatePickerTrigger';
5
+ export { useMultipleDatePickerValue } from './useMultipleDatePickerValue';
6
+ export type { UseMultipleDatePickerValueProps, UseMultipleDatePickerValueReturn, } from './useMultipleDatePickerValue';
@@ -0,0 +1,3 @@
1
+ export { default } from './MultipleDatePicker.js';
2
+ export { default as MultipleDatePickerTrigger } from './MultipleDatePickerTrigger.js';
3
+ export { useMultipleDatePickerValue } from './useMultipleDatePickerValue.js';
@@ -0,0 +1,55 @@
1
+ import { DateType } from '@mezzanine-ui/core/calendar';
2
+ import { MultipleDatePickerValue } from '@mezzanine-ui/core/multiple-date-picker';
3
+ export interface UseMultipleDatePickerValueProps {
4
+ /**
5
+ * The format pattern for displaying dates (e.g., "YYYY-MM-DD")
6
+ */
7
+ format: string;
8
+ /**
9
+ * Maximum number of dates that can be selected
10
+ */
11
+ maxSelections?: number;
12
+ /**
13
+ * Controlled value
14
+ */
15
+ value?: MultipleDatePickerValue;
16
+ }
17
+ export interface UseMultipleDatePickerValueReturn {
18
+ /**
19
+ * The internal value (pending changes)
20
+ */
21
+ internalValue: MultipleDatePickerValue;
22
+ /**
23
+ * Toggle a date in/out of selection
24
+ */
25
+ toggleDate: (date: DateType) => void;
26
+ /**
27
+ * Remove a specific date from selection
28
+ */
29
+ removeDate: (date: DateType) => void;
30
+ /**
31
+ * Clear all selected dates
32
+ */
33
+ clearAll: () => void;
34
+ /**
35
+ * Check if a date is currently selected
36
+ */
37
+ isDateSelected: (date: DateType) => boolean;
38
+ /**
39
+ * Check if selection has reached max limit
40
+ */
41
+ isMaxReached: boolean;
42
+ /**
43
+ * Confirm the current selection (returns the value to be passed to onChange)
44
+ */
45
+ getConfirmValue: () => MultipleDatePickerValue;
46
+ /**
47
+ * Cancel and revert to original value
48
+ */
49
+ revertToValue: () => void;
50
+ /**
51
+ * Format a date to display string
52
+ */
53
+ formatDate: (date: DateType) => string;
54
+ }
55
+ export declare function useMultipleDatePickerValue({ format, maxSelections, value, }: UseMultipleDatePickerValueProps): UseMultipleDatePickerValueReturn;
@@ -0,0 +1,68 @@
1
+ 'use client';
2
+ import { useCallback, useState, useEffect } from 'react';
3
+ import { useCalendarContext } from '../Calendar/CalendarContext.js';
4
+
5
+ function useMultipleDatePickerValue({ format, maxSelections, value = [], }) {
6
+ const { formatToString, isBefore, isSameDate, locale } = useCalendarContext();
7
+ // Sort dates in chronological order
8
+ const sortDates = useCallback((dates) => {
9
+ return [...dates].sort((a, b) => {
10
+ if (isSameDate(a, b))
11
+ return 0;
12
+ return isBefore(a, b) ? -1 : 1;
13
+ });
14
+ }, [isBefore, isSameDate]);
15
+ // Internal state for pending changes
16
+ const [internalValue, setInternalValue] = useState(() => sortDates(value));
17
+ // Sync internal value when controlled value changes
18
+ useEffect(() => {
19
+ setInternalValue(sortDates(value));
20
+ }, [sortDates, value]);
21
+ const formatDate = useCallback((date) => {
22
+ return formatToString(locale, date, format);
23
+ }, [formatToString, locale, format]);
24
+ const isDateSelected = useCallback((date) => {
25
+ return internalValue.some((d) => isSameDate(d, date));
26
+ }, [internalValue, isSameDate]);
27
+ const isMaxReached = typeof maxSelections === 'number' && internalValue.length >= maxSelections;
28
+ const toggleDate = useCallback((date) => {
29
+ setInternalValue((prev) => {
30
+ const existingIndex = prev.findIndex((d) => isSameDate(d, date));
31
+ if (existingIndex >= 0) {
32
+ // Remove the date
33
+ return prev.filter((_, index) => index !== existingIndex);
34
+ }
35
+ // Check max limit before adding
36
+ if (typeof maxSelections === 'number' && prev.length >= maxSelections) {
37
+ return prev;
38
+ }
39
+ // Add the date and sort
40
+ return sortDates([...prev, date]);
41
+ });
42
+ }, [isSameDate, maxSelections, sortDates]);
43
+ const removeDate = useCallback((date) => {
44
+ setInternalValue((prev) => prev.filter((d) => !isSameDate(d, date)));
45
+ }, [isSameDate]);
46
+ const clearAll = useCallback(() => {
47
+ setInternalValue([]);
48
+ }, []);
49
+ const getConfirmValue = useCallback(() => {
50
+ return internalValue;
51
+ }, [internalValue]);
52
+ const revertToValue = useCallback(() => {
53
+ setInternalValue(sortDates(value));
54
+ }, [sortDates, value]);
55
+ return {
56
+ clearAll,
57
+ formatDate,
58
+ getConfirmValue,
59
+ internalValue,
60
+ isDateSelected,
61
+ isMaxReached,
62
+ removeDate,
63
+ revertToValue,
64
+ toggleDate,
65
+ };
66
+ }
67
+
68
+ export { useMultipleDatePickerValue };
@@ -10,7 +10,7 @@ const NavigationHeader = forwardRef((props, ref) => {
10
10
  const { children, className, title, onBrandClick, ...rest } = props;
11
11
  const { collapsed, handleCollapseChange } = use(NavigationActivatedContext);
12
12
  const BrandComponent = onBrandClick ? 'button' : 'span';
13
- return (jsxs("header", { ...rest, ref: ref, className: cx(navigationHeaderClasses.host, collapsed && navigationHeaderClasses.collapsed, className), children: [jsx(NavigationIconButton, { onClick: () => handleCollapseChange(!collapsed), icon: SiderIcon }), jsxs(BrandComponent, { type: "button", className: navigationHeaderClasses.content, onClick: onBrandClick, children: [children, jsx("span", { className: navigationHeaderClasses.title, children: title })] })] }));
13
+ return (jsxs("header", { ...rest, ref: ref, className: cx(navigationHeaderClasses.host, collapsed && navigationHeaderClasses.collapsed, className), children: [jsx(NavigationIconButton, { onClick: () => handleCollapseChange(!collapsed), icon: SiderIcon }), jsxs(BrandComponent, { type: "button", className: navigationHeaderClasses.content, onClick: onBrandClick, children: [children, jsx("span", { className: navigationHeaderClasses.title, children: collapsed ? title === null || title === void 0 ? void 0 : title[0] : title })] })] }));
14
14
  });
15
15
 
16
16
  export { NavigationHeader as default };
@@ -1,4 +1,4 @@
1
- import { type ChangeEventHandler, type ComponentProps, type Key, type ReactElement } from 'react';
1
+ import { type ComponentProps, type Key, type ReactElement } from 'react';
2
2
  import { DrawerSize } from '@mezzanine-ui/core/drawer';
3
3
  import { type IconDefinition } from '@mezzanine-ui/icons';
4
4
  import { type DrawerProps } from '../Drawer';
@@ -7,24 +7,17 @@ type NotificationDataForDrawer = NotificationData & {
7
7
  key: Key;
8
8
  type: 'drawer';
9
9
  };
10
- type NotificationCenterDrawerPropsBase = Pick<DrawerProps, 'open' | 'onClose'> & {
11
- /**
12
- * The label of the all radio.
13
- */
14
- allRadioLabel?: string;
15
- /**
16
- * The label of the custom radio.
17
- */
18
- customRadioLabel?: string;
19
- /**
20
- * The default value of the radio group.
21
- */
22
- defaultValue?: string;
10
+ type NotificationCenterDrawerPropsBase = Pick<DrawerProps, 'controlBarAllRadioLabel' | 'controlBarCustomButtonLabel' | 'controlBarDefaultValue' | 'controlBarOnCustomButtonClick' | 'controlBarOnRadioChange' | 'controlBarReadRadioLabel' | 'controlBarShow' | 'controlBarShowUnreadButton' | 'controlBarUnreadRadioLabel' | 'controlBarValue' | 'onClose' | 'open' | 'renderControlBar'> & {
23
11
  /**
24
12
  * The size of the drawer.
25
13
  * @default 'narrow'
26
14
  */
27
15
  drawerSize?: DrawerSize;
16
+ /**
17
+ * The label of the "earlier" time group.
18
+ * @default '更早'
19
+ */
20
+ earlierLabel?: string;
28
21
  /**
29
22
  * The icon of the empty notification.
30
23
  */
@@ -34,49 +27,14 @@ type NotificationCenterDrawerPropsBase = Pick<DrawerProps, 'open' | 'onClose'> &
34
27
  */
35
28
  emptyNotificationTitle?: string;
36
29
  /**
37
- * The callback function when the custom button is clicked.
38
- */
39
- onCustomButtonClick?: VoidFunction;
40
- /**
41
- * The callback function when the radio group value changes.
42
- */
43
- onRadioChange?: ChangeEventHandler<HTMLInputElement>;
44
- /**
45
- * The label of the read radio.
46
- */
47
- readRadioLabel?: string;
48
- /**
49
- * Controls whether to display the toolbar.
50
- * @default true
51
- */
52
- showToolbar?: boolean;
53
- /**
54
- * Controls whether to display the unread button.
55
- * @default false
30
+ * The label for the "past 7 days" time group.
31
+ * @default '過去七天'
56
32
  */
57
- showUnreadButton?: boolean;
33
+ past7DaysLabel?: string;
58
34
  /**
59
35
  * The title of the drawer.
60
36
  */
61
37
  title?: string;
62
- /**
63
- * The label of the unread radio.
64
- */
65
- unreadRadioLabel?: string;
66
- /**
67
- * The value of the radio group.
68
- */
69
- value?: string;
70
- /**
71
- * The label for the "earlier" time group.
72
- * @default '更早'
73
- */
74
- earlierLabel?: string;
75
- /**
76
- * The label for the "past 7 days" time group.
77
- * @default '過去七天'
78
- */
79
- past7DaysLabel?: string;
80
38
  /**
81
39
  * The label for the "today" time group.
82
40
  * @default '今天'