@mezzanine-ui/react 1.0.0-beta.0 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/Dropdown/Dropdown.d.ts +116 -15
  2. package/Dropdown/Dropdown.js +235 -32
  3. package/Dropdown/DropdownAction.d.ts +50 -0
  4. package/Dropdown/DropdownAction.js +26 -0
  5. package/Dropdown/DropdownItem.d.ts +60 -0
  6. package/Dropdown/DropdownItem.js +318 -0
  7. package/Dropdown/DropdownItemCard.d.ts +96 -0
  8. package/Dropdown/DropdownItemCard.js +115 -0
  9. package/Dropdown/DropdownStatus.d.ts +22 -0
  10. package/Dropdown/dropdownKeydownHandler.d.ts +15 -0
  11. package/Dropdown/highlightText.d.ts +9 -0
  12. package/Dropdown/highlightText.js +32 -0
  13. package/Dropdown/index.d.ts +1 -1
  14. package/Navigation/Navigation.d.ts +11 -17
  15. package/Navigation/Navigation.js +58 -41
  16. package/Navigation/NavigationFooter.d.ts +10 -0
  17. package/Navigation/NavigationFooter.js +26 -0
  18. package/Navigation/NavigationHeader.d.ts +8 -0
  19. package/Navigation/NavigationHeader.js +13 -0
  20. package/Navigation/NavigationIconButton.d.ts +15 -0
  21. package/Navigation/NavigationIconButton.js +12 -0
  22. package/Navigation/NavigationOption.d.ts +35 -0
  23. package/Navigation/NavigationOption.js +60 -0
  24. package/Navigation/NavigationOptionCategory.d.ts +6 -0
  25. package/Navigation/NavigationOptionCategory.js +12 -0
  26. package/Navigation/NavigationUserMenu.d.ts +8 -0
  27. package/Navigation/NavigationUserMenu.js +18 -0
  28. package/Navigation/context.d.ts +13 -0
  29. package/Navigation/context.js +7 -0
  30. package/Navigation/index.d.ts +12 -6
  31. package/Navigation/index.js +6 -3
  32. package/Navigation/useCurrentPathname.d.ts +1 -0
  33. package/Navigation/useCurrentPathname.js +14 -0
  34. package/Slider/useSlider.js +1 -1
  35. package/hooks/useElementHeight.d.ts +8 -0
  36. package/hooks/useElementHeight.js +41 -0
  37. package/index.d.ts +2 -2
  38. package/index.js +0 -2
  39. package/package.json +5 -4
  40. package/Navigation/NavigationContext.d.ts +0 -5
  41. package/Navigation/NavigationContext.js +0 -8
  42. package/Navigation/NavigationItem.d.ts +0 -31
  43. package/Navigation/NavigationItem.js +0 -23
  44. package/Navigation/NavigationSubMenu.d.ts +0 -22
  45. package/Navigation/NavigationSubMenu.js +0 -50
@@ -1,25 +1,126 @@
1
- import { DetailedHTMLProps, HTMLAttributes, ReactNode, Ref } from 'react';
2
- import { PopperProps } from '../Popper';
3
- import { ClickAwayEvent } from '../hooks/useClickAway';
4
- export interface DropdownProps extends Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, 'ref' | 'children'> {
5
- children: (ref: Ref<any>) => ReactNode;
1
+ import { ReactElement } from 'react';
2
+ import { dropdownInputPosition, DropdownItemSharedProps, DropdownOption, dropdownType } from '@mezzanine-ui/core/dropdown/dropdown';
3
+ import { ButtonProps } from '../Button';
4
+ import { InputProps } from '../Input';
5
+ import { PopperPlacement } from '../Popper';
6
+ export interface DropdownProps extends DropdownItemSharedProps {
6
7
  /**
7
- * Whether to disable triggering onClose while clicked away.
8
+ * The text of the cancel button.
9
+ */
10
+ actionCancelText?: string;
11
+ /**
12
+ * The text of the clear button.
13
+ */
14
+ actionClearText?: string;
15
+ /**
16
+ * The text of the confirm button.
17
+ */
18
+ actionConfirmText?: string;
19
+ /**
20
+ * The custom action button props of the dropdown.
21
+ */
22
+ actionCustomButtonProps?: ButtonProps;
23
+ /**
24
+ * The text of the custom action button.
25
+ */
26
+ actionText?: string;
27
+ /**
28
+ * The active option index for hover/focus state.
29
+ */
30
+ activeIndex?: number | null;
31
+ /**
32
+ * The children of the dropdown.
33
+ * This can be a button or an input.
34
+ */
35
+ children: ReactElement<ButtonProps> | ReactElement<InputProps>;
36
+ /**
37
+ * Whether the dropdown is disabled.
38
+ */
39
+ disabled?: boolean;
40
+ /**
41
+ * The id of the dropdown.
42
+ */
43
+ id?: string;
44
+ /**
45
+ * The position of the input.
46
+ * @default 'outside'
47
+ */
48
+ inputPosition?: dropdownInputPosition;
49
+ /**
50
+ * Whether to match the input value.
51
+ * @default false
52
+ */
53
+ isMatchInputValue?: boolean;
54
+ /**
55
+ * The listbox id of the dropdown.
56
+ */
57
+ listboxId?: string;
58
+ /**
59
+ * The aria-label for the listbox.
60
+ * If not provided, a default label will be used when there are no options.
61
+ */
62
+ listboxLabel?: string;
63
+ /**
64
+ * The max height of the dropdown list.
65
+ */
66
+ maxHeight?: number | string;
67
+ /**
68
+ * Callback fired when the action cancel is clicked.
69
+ */
70
+ onActionCancel?: () => void;
71
+ /**
72
+ * Callback fired when the action clear is clicked.
73
+ */
74
+ onActionClear?: () => void;
75
+ /**
76
+ * Callback fired when the action confirm is clicked.
77
+ */
78
+ onActionConfirm?: () => void;
79
+ /**
80
+ * Callback fired when the action custom is clicked.
81
+ */
82
+ onActionCustom?: () => void;
83
+ /**
84
+ * Callback fired when the dropdown is closed.
85
+ */
86
+ onClose?: () => void;
87
+ /**
88
+ * Callback fired when the item is hovered.
89
+ */
90
+ onItemHover?: (index: number) => void;
91
+ /**
92
+ * Callback fired when the dropdown is opened.
93
+ */
94
+ onOpen?: () => void;
95
+ /**
96
+ * Callback fired when the item is selected.
97
+ */
98
+ onSelect?: (option: DropdownOption) => void;
99
+ /**
100
+ * The options of the dropdown.
101
+ */
102
+ options: DropdownOption[];
103
+ /**
104
+ * The placement of the dropdown.
105
+ */
106
+ placement?: PopperPlacement;
107
+ /**
108
+ * Whether to set the same width as its anchor element.
8
109
  * @default false
9
110
  */
10
- disableClickAway?: boolean;
111
+ sameWidth?: boolean;
11
112
  /**
12
- * The dropdown menu
113
+ * If true, display a bar at the top of the dropdown action area.
114
+ * @default false
13
115
  */
14
- menu?: ReactNode;
116
+ showActionShowTopBar?: boolean;
15
117
  /**
16
- * The handler fired while clicked away.
118
+ * Whether to show the actions.
17
119
  */
18
- onClose?: (event: ClickAwayEvent) => void;
120
+ showDropdownActions?: boolean;
19
121
  /**
20
- * the props of popper
122
+ * The type of the dropdown.
21
123
  */
22
- popperProps?: PopperProps;
124
+ type?: dropdownType;
23
125
  }
24
- declare const Dropdown: import("react").ForwardRefExoticComponent<DropdownProps & import("react").RefAttributes<HTMLDivElement>>;
25
- export default Dropdown;
126
+ export default function Dropdown(props: DropdownProps): import("react/jsx-runtime").JSX.Element;
@@ -1,42 +1,245 @@
1
- import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
- import { forwardRef, useRef } from 'react';
3
- import { size } from '@floating-ui/react-dom';
4
- import { useClickAway } from '../hooks/useClickAway.js';
5
- import { useComposeRefs } from '../hooks/useComposeRefs.js';
1
+ 'use client';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useId, useMemo, useState, useRef, useEffect, useCallback, cloneElement, createElement } from 'react';
4
+ import cx from 'clsx';
5
+ import { dropdownClasses } from '@mezzanine-ui/core/dropdown/dropdown';
6
+ import { size, offset } from '@floating-ui/react-dom';
7
+ import { MOTION_EASING, MOTION_DURATION } from '@mezzanine-ui/system/motion';
8
+ import { TransitionGroup } from 'react-transition-group';
9
+ import Button from '../Button/Button.js';
10
+ import { useDocumentEvents } from '../hooks/useDocumentEvents.js';
11
+ import Translate from '../Transition/Translate.js';
12
+ import { composeRefs } from '../utils/composeRefs.js';
13
+ import DropdownItem from './DropdownItem.js';
6
14
  import Popper from '../Popper/Popper.js';
7
15
 
8
- // Middleware to make the dropdown menu have the same width as the reference element
9
- const sameWidthMiddleware = size({
10
- apply({ rects, elements }) {
11
- Object.assign(elements.floating.style, {
12
- width: 'auto',
13
- minWidth: `${rects.reference.width}px`,
16
+ function Dropdown(props) {
17
+ const { activeIndex: activeIndexProp, id, children, options = [], type = 'default', maxHeight, disabled = false, showDropdownActions = false, actionCancelText, actionConfirmText, actionText, actionClearText, actionCustomButtonProps, showActionShowTopBar, isMatchInputValue = false, inputPosition = 'outside', placement = 'bottom', sameWidth = false, listboxId: listboxIdProp, listboxLabel, onClose, onOpen, onSelect, onActionConfirm, onActionCancel, onActionCustom, onActionClear, onItemHover, } = props;
18
+ const isInline = inputPosition === 'inside';
19
+ const inputId = useId();
20
+ const defaultListboxId = `${inputId}-listbox`;
21
+ const listboxId = listboxIdProp !== null && listboxIdProp !== void 0 ? listboxIdProp : defaultListboxId;
22
+ const actionConfig = useMemo(() => {
23
+ return {
24
+ showActions: showDropdownActions,
25
+ cancelText: actionCancelText,
26
+ confirmText: actionConfirmText,
27
+ clearText: actionClearText,
28
+ actionText,
29
+ customActionButtonProps: actionCustomButtonProps,
30
+ showTopBar: showActionShowTopBar,
31
+ onConfirm: onActionConfirm,
32
+ onCancel: onActionCancel,
33
+ onClick: onActionCustom,
34
+ onClear: onActionClear,
35
+ };
36
+ }, [showDropdownActions, actionCancelText, actionConfirmText, actionClearText, actionText, actionCustomButtonProps, showActionShowTopBar, onActionConfirm, onActionCancel, onActionCustom, onActionClear]);
37
+ const [isOpen, setIsOpen] = useState(false);
38
+ const [uncontrolledActiveIndex, setUncontrolledActiveIndex] = useState(activeIndexProp !== null && activeIndexProp !== void 0 ? activeIndexProp : null);
39
+ const isActiveIndexControlled = activeIndexProp !== undefined;
40
+ const mergedActiveIndex = isActiveIndexControlled ? activeIndexProp : uncontrolledActiveIndex;
41
+ const containerRef = useRef(null);
42
+ const ariaActivedescendant = useMemo(() => {
43
+ if (mergedActiveIndex !== null && mergedActiveIndex >= 0) {
44
+ return `${listboxId}-option-${mergedActiveIndex}`;
45
+ }
46
+ return undefined;
47
+ }, [mergedActiveIndex, listboxId]);
48
+ const translateProps = useMemo(() => ({
49
+ duration: {
50
+ enter: MOTION_DURATION.moderate,
51
+ exit: MOTION_DURATION.moderate,
52
+ },
53
+ easing: {
54
+ enter: MOTION_EASING.standard,
55
+ exit: MOTION_EASING.standard,
56
+ },
57
+ }), []);
58
+ const followText = useMemo(() => {
59
+ var _a, _b, _c, _d;
60
+ if (children.type === Button) {
61
+ return undefined;
62
+ }
63
+ if (!isMatchInputValue) {
64
+ return undefined;
65
+ }
66
+ // Try to get value from Input component props
67
+ const inputValue = (_d = (_b = (_a = children.props) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : (_c = children.props) === null || _c === void 0 ? void 0 : _c.defaultValue) !== null && _d !== void 0 ? _d : '';
68
+ return inputValue;
69
+ }, [children, isMatchInputValue]);
70
+ const popoverPlacement = useMemo(() => {
71
+ if (inputPosition === 'outside') {
72
+ return placement;
73
+ }
74
+ return 'bottom';
75
+ }, [inputPosition, placement]);
76
+ const sameWidthMiddleware = useMemo(() => {
77
+ if (!sameWidth) {
78
+ return null;
79
+ }
80
+ return size({
81
+ apply({ rects, elements }) {
82
+ Object.assign(elements.floating.style, {
83
+ width: `${rects.reference.width}px`,
84
+ });
85
+ },
14
86
  });
15
- },
16
- });
17
- const Dropdown = forwardRef(function Dropdown(props, ref) {
18
- var _a;
19
- const { children, disableClickAway = false, menu, onClose, popperProps, ...rest } = props;
20
- const anchor = useRef(null);
87
+ }, [sameWidth]);
88
+ const offsetMiddleware = useMemo(() => {
89
+ return offset({ mainAxis: 4 });
90
+ }, []);
91
+ const prevIsOpenRef = useRef(isOpen);
92
+ const translateFrom = useMemo(() => {
93
+ if (isInline) {
94
+ return 'bottom';
95
+ }
96
+ const placementBase = popoverPlacement.split('-')[0];
97
+ return placementBase === 'top' ? 'top' : 'bottom';
98
+ }, [isInline, popoverPlacement]);
99
+ useEffect(() => {
100
+ if (prevIsOpenRef.current === isOpen)
101
+ return;
102
+ if (isOpen) {
103
+ onOpen === null || onOpen === void 0 ? void 0 : onOpen();
104
+ }
105
+ else {
106
+ onClose === null || onClose === void 0 ? void 0 : onClose();
107
+ }
108
+ prevIsOpenRef.current = isOpen;
109
+ }, [isOpen, onClose, onOpen]);
110
+ const anchorRef = useRef(null);
21
111
  const popperRef = useRef(null);
22
- const composedRef = useComposeRefs([ref, popperRef]);
23
- const open = popperProps === null || popperProps === void 0 ? void 0 : popperProps.open;
24
- const middleware = ((_a = popperProps === null || popperProps === void 0 ? void 0 : popperProps.options) === null || _a === void 0 ? void 0 : _a.middleware) || [];
25
- useClickAway(() => {
26
- if (!open || disableClickAway || !onClose) {
112
+ // Extract combobox props logic to avoid duplication
113
+ const getComboboxProps = useMemo(() => {
114
+ const childWithRef = children;
115
+ const isInput = childWithRef.type !== Button;
116
+ if (!isInput)
117
+ return {};
118
+ return {
119
+ role: 'combobox',
120
+ 'aria-controls': listboxId,
121
+ 'aria-expanded': isOpen,
122
+ 'aria-haspopup': 'listbox',
123
+ 'aria-autocomplete': isMatchInputValue ? 'list' : undefined,
124
+ 'aria-activedescendant': ariaActivedescendant,
125
+ };
126
+ }, [children, listboxId, isOpen, isMatchInputValue, ariaActivedescendant]);
127
+ const handleItemHover = useCallback((index) => {
128
+ if (!isActiveIndexControlled) {
129
+ setUncontrolledActiveIndex(index);
130
+ }
131
+ onItemHover === null || onItemHover === void 0 ? void 0 : onItemHover(index);
132
+ }, [isActiveIndexControlled, onItemHover]);
133
+ // Extract shared DropdownItem props to avoid duplication
134
+ const baseDropdownItemProps = useMemo(() => ({
135
+ actionConfig,
136
+ activeIndex: mergedActiveIndex,
137
+ disabled,
138
+ followText,
139
+ listboxId,
140
+ listboxLabel,
141
+ maxHeight,
142
+ sameWidth,
143
+ onHover: handleItemHover,
144
+ onSelect,
145
+ options,
146
+ type,
147
+ }), [actionConfig, mergedActiveIndex, disabled, followText, listboxId, listboxLabel, maxHeight, sameWidth, handleItemHover, onSelect, options, type]);
148
+ const triggerElement = useMemo(() => {
149
+ const childWithRef = children;
150
+ const composedRef = composeRefs([
151
+ anchorRef,
152
+ childWithRef.ref,
153
+ ]);
154
+ return cloneElement(childWithRef, {
155
+ ref: composedRef,
156
+ ...getComboboxProps,
157
+ onClick: (event) => {
158
+ var _a, _b;
159
+ (_b = (_a = childWithRef.props) === null || _a === void 0 ? void 0 : _a.onClick) === null || _b === void 0 ? void 0 : _b.call(_a, event);
160
+ if (event === null || event === void 0 ? void 0 : event.defaultPrevented)
161
+ return;
162
+ if (!isInline) {
163
+ setIsOpen((prev) => !prev);
164
+ }
165
+ },
166
+ });
167
+ }, [children, isInline, getComboboxProps]);
168
+ const inlineTriggerElement = useMemo(() => {
169
+ if (!isInline) {
170
+ return null;
171
+ }
172
+ const childWithRef = children;
173
+ const composedRef = composeRefs([
174
+ childWithRef.ref,
175
+ ]);
176
+ return cloneElement(childWithRef, {
177
+ ref: composedRef,
178
+ ...getComboboxProps,
179
+ onBlur: (event) => {
180
+ var _a, _b;
181
+ (_b = (_a = childWithRef.props) === null || _a === void 0 ? void 0 : _a.onBlur) === null || _b === void 0 ? void 0 : _b.call(_a, event);
182
+ if (event === null || event === void 0 ? void 0 : event.defaultPrevented)
183
+ return;
184
+ const nextFocusTarget = event === null || event === void 0 ? void 0 : event.relatedTarget;
185
+ const container = containerRef.current;
186
+ if (container && nextFocusTarget && container.contains(nextFocusTarget)) {
187
+ return;
188
+ }
189
+ setIsOpen(false);
190
+ },
191
+ onClick: (event) => {
192
+ var _a, _b;
193
+ (_b = (_a = childWithRef.props) === null || _a === void 0 ? void 0 : _a.onClick) === null || _b === void 0 ? void 0 : _b.call(_a, event);
194
+ if (event === null || event === void 0 ? void 0 : event.defaultPrevented)
195
+ return;
196
+ setIsOpen(true);
197
+ },
198
+ onFocus: (event) => {
199
+ var _a, _b;
200
+ (_b = (_a = childWithRef.props) === null || _a === void 0 ? void 0 : _a.onFocus) === null || _b === void 0 ? void 0 : _b.call(_a, event);
201
+ if (event === null || event === void 0 ? void 0 : event.defaultPrevented)
202
+ return;
203
+ setIsOpen(true);
204
+ },
205
+ });
206
+ }, [children, isInline, isOpen, getComboboxProps]);
207
+ useDocumentEvents(() => {
208
+ if (!isOpen) {
27
209
  return;
28
210
  }
29
- return (event) => {
30
- if (onClose) {
31
- onClose(event);
211
+ const handleClickAway = (event) => {
212
+ const target = event.target;
213
+ const anchor = anchorRef.current;
214
+ const popper = popperRef.current;
215
+ const container = containerRef.current;
216
+ if (!target)
217
+ return;
218
+ if (isInline) {
219
+ if (container && !container.contains(target)) {
220
+ setIsOpen(false);
221
+ }
222
+ return;
32
223
  }
224
+ if (anchor && popper && !anchor.contains(target) && !popper.contains(target)) {
225
+ setIsOpen(false);
226
+ }
227
+ };
228
+ return {
229
+ click: handleClickAway,
230
+ touchend: handleClickAway,
33
231
  };
34
- }, popperRef, [disableClickAway, onClose, open, popperRef]);
35
- return (jsxs(Fragment, { children: [children(anchor), jsx(Popper, { ...popperProps, ref: composedRef, ...rest, anchor: anchor, options: {
36
- placement: 'top-start',
37
- ...popperProps === null || popperProps === void 0 ? void 0 : popperProps.options,
38
- middleware: [sameWidthMiddleware, ...middleware],
39
- }, children: menu })] }));
40
- });
232
+ }, [isInline, isOpen]);
233
+ return (jsxs("div", { id: id, ref: containerRef, className: cx(dropdownClasses.root, dropdownClasses.inputPosition(inputPosition)), children: [isInline && (jsxs(TransitionGroup, { component: null, children: [!isOpen && inlineTriggerElement && (createElement(Translate, { ...translateProps, from: translateFrom, key: "inline-trigger", in: true },
234
+ jsx("div", { children: inlineTriggerElement }))), isOpen && (createElement(Translate, { ...translateProps, from: translateFrom, key: "inline-list", in: true },
235
+ jsx("div", { children: jsx(DropdownItem, { ...baseDropdownItemProps, headerContent: inlineTriggerElement }) })))] })), !isInline && (jsx(Popper, { ref: popperRef, anchor: anchorRef, open: isOpen, disablePortal: true, options: {
236
+ placement: popoverPlacement,
237
+ middleware: [
238
+ offsetMiddleware,
239
+ ...(sameWidthMiddleware ? [sameWidthMiddleware] : []),
240
+ ],
241
+ }, children: jsx(TransitionGroup, { component: null, children: isOpen && (createElement(Translate, { ...translateProps, from: translateFrom, key: "popper-list", in: true },
242
+ jsx("div", { children: jsx(DropdownItem, { ...baseDropdownItemProps }) }))) }) })), !isInline && triggerElement] }));
243
+ }
41
244
 
42
245
  export { Dropdown as default };
@@ -0,0 +1,50 @@
1
+ import { ButtonProps } from "../Button";
2
+ export interface DropdownActionProps {
3
+ /**
4
+ * The text of the custom action button.
5
+ */
6
+ actionText?: string;
7
+ /**
8
+ * The text of the cancel button.
9
+ */
10
+ cancelText?: string;
11
+ /**
12
+ * The text of the clear button.
13
+ */
14
+ clearText?: string;
15
+ /**
16
+ * The text of the confirm button.
17
+ */
18
+ confirmText?: string;
19
+ /**
20
+ * The custom action button props of the dropdown.
21
+ */
22
+ customActionButtonProps?: ButtonProps;
23
+ /**
24
+ * Click handler for cancel button.
25
+ */
26
+ onCancel?: () => void;
27
+ /**
28
+ * Click handler for clear button.
29
+ */
30
+ onClear?: () => void;
31
+ /**
32
+ * Click handler for confirm button.
33
+ */
34
+ onConfirm?: () => void;
35
+ /**
36
+ * Click handler for custom action button.
37
+ */
38
+ onClick?: () => void;
39
+ /**
40
+ * Whether to show the actions.
41
+ * @default false
42
+ */
43
+ showActions?: boolean;
44
+ /**
45
+ * If true, display a bar at the top of the dropdown action area.
46
+ * @default false
47
+ */
48
+ showTopBar?: boolean;
49
+ }
50
+ export default function DropdownAction(props: DropdownActionProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,26 @@
1
+ 'use client';
2
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
3
+ import { dropdownClasses } from '@mezzanine-ui/core/dropdown/dropdown';
4
+ import { CloseIcon } from '@mezzanine-ui/icons';
5
+ import Button from '../Button/Button.js';
6
+
7
+ const actionButtonSize = 'minor';
8
+ function DropdownAction(props) {
9
+ const { showActions = false, showTopBar, customActionButtonProps, cancelText, confirmText, actionText, clearText, onCancel, onConfirm, onClick, onClear, } = props;
10
+ const cancelLabel = cancelText || 'Cancel';
11
+ const confirmLabel = confirmText || 'Confirm';
12
+ const actionLabel = actionText || 'Custom Action';
13
+ const clearLabel = clearText || 'Clear Options';
14
+ const hasAnyEvent = Boolean(onCancel || onConfirm || onClick || onClear);
15
+ const isClearMode = Boolean(onClear && !onClick);
16
+ const isCustomMode = Boolean(onClick && !onClear);
17
+ const isDefaultMode = !isClearMode && !isCustomMode;
18
+ const hasCancel = Boolean(onCancel && isDefaultMode);
19
+ const hasConfirm = Boolean(onConfirm && isDefaultMode);
20
+ return (jsx(Fragment, { children: showActions && hasAnyEvent && (jsxs("div", { className: dropdownClasses.action, children: [showTopBar && jsx("i", { className: dropdownClasses.actionTopBar }), jsxs("div", { className: dropdownClasses.actionTools, children: [hasCancel && (jsx(Button, { variant: "base-ghost", size: actionButtonSize, onClick: onCancel, children: cancelLabel })), hasConfirm && (jsx(Button, { size: actionButtonSize, style: hasCancel ? undefined : { marginLeft: 'auto' }, onClick: onConfirm, children: confirmLabel })), isCustomMode && (jsx(Button, { size: actionButtonSize, variant: "base-ghost", ...customActionButtonProps, onClick: onClick, children: actionLabel })), isClearMode && (jsx(Button, { size: actionButtonSize, variant: "base-ghost", icon: {
21
+ position: 'leading',
22
+ src: CloseIcon,
23
+ }, onClick: onClear, children: clearLabel }))] })] })) }));
24
+ }
25
+
26
+ export { DropdownAction as default };
@@ -0,0 +1,60 @@
1
+ import { ReactNode } from 'react';
2
+ import { DropdownItemSharedProps, DropdownOptionsByType, dropdownType } from '@mezzanine-ui/core/dropdown/dropdown';
3
+ import { type DropdownActionProps } from './DropdownAction';
4
+ export interface DropdownItemProps<T extends dropdownType | undefined = dropdownType> extends Omit<DropdownItemSharedProps, 'type'> {
5
+ /**
6
+ * The action configuration for the dropdown.
7
+ */
8
+ actionConfig?: DropdownActionProps;
9
+ /**
10
+ * The active option index for hover/focus state.
11
+ */
12
+ activeIndex: number | null;
13
+ /**
14
+ * The text to follow.
15
+ */
16
+ followText?: string;
17
+ /**
18
+ * Custom content rendered before options (e.g. inline trigger).
19
+ */
20
+ headerContent?: ReactNode;
21
+ /**
22
+ * The listbox id for aria usage.
23
+ */
24
+ listboxId: string;
25
+ /**
26
+ * The aria-label for the listbox.
27
+ * If not provided, a default label will be used when there are no options.
28
+ */
29
+ listboxLabel?: string;
30
+ /**
31
+ * The max height of the dropdown list.
32
+ */
33
+ maxHeight?: number | string;
34
+ /**
35
+ * Whether to set the same width as its anchor element.
36
+ * @default false
37
+ */
38
+ sameWidth?: boolean;
39
+ /**
40
+ * Callback when hovering option index changes.
41
+ */
42
+ onHover?: (index: number) => void;
43
+ /**
44
+ * Options to render.
45
+ * The structure is constrained based on the `type` prop:
46
+ * - 'default': flat array (no children allowed)
47
+ * - 'grouped': array with one level of children (children cannot have children)
48
+ * - 'tree': array with nested children up to 3 levels (strictly enforced at compile time)
49
+ */
50
+ options: DropdownOptionsByType<T>;
51
+ /**
52
+ * The type of the dropdown.
53
+ * This prop determines the structure of the `options` array:
54
+ * - 'default': flat array (no children allowed)
55
+ * - 'grouped': array with one level of children (children cannot have children)
56
+ * - 'tree': array with nested children up to 3 levels
57
+ */
58
+ type?: dropdownType;
59
+ }
60
+ export default function DropdownItem<T extends dropdownType | undefined = dropdownType>(props: DropdownItemProps<T>): import("react/jsx-runtime").JSX.Element;