@astryxdesign/core 0.5.2-canary.c9c8564 → 0.5.2-canary.e4f8e4e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BottomSheet/BottomSheet.d.ts +3 -1
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +4 -3
- package/dist/BottomSheet/BottomSheetEdgeTint.d.ts +2 -2
- package/dist/BottomSheet/BottomSheetEdgeTint.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetEdgeTint.js +7 -10
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetSwitcher.js +1 -1
- package/dist/Button/Button.d.ts +2 -1
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +11 -4
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +2 -2
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +34 -17
- package/dist/ContextMenu/ContextMenu.d.ts +14 -3
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +149 -26
- package/dist/ContextMenu/index.d.ts +1 -0
- package/dist/ContextMenu/index.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.d.ts +24 -5
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +340 -26
- package/dist/DropdownMenu/DropdownMenuContext.d.ts +1 -1
- package/dist/DropdownMenu/DropdownMenuContext.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.js +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +6 -2
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +43 -14
- package/dist/DropdownMenu/MenuBottomSheet.d.ts +20 -0
- package/dist/DropdownMenu/MenuBottomSheet.d.ts.map +1 -0
- package/dist/DropdownMenu/MenuBottomSheet.js +36 -0
- package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts +10 -0
- package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts.map +1 -0
- package/dist/DropdownMenu/MenuBottomSheetActionList.js +111 -0
- package/dist/DropdownMenu/index.d.ts +2 -1
- package/dist/DropdownMenu/index.d.ts.map +1 -1
- package/dist/DropdownMenu/menuWidth.d.ts +14 -0
- package/dist/DropdownMenu/menuWidth.d.ts.map +1 -0
- package/dist/DropdownMenu/menuWidth.js +35 -0
- package/dist/DropdownMenu/useMenuOverflow.d.ts +10 -0
- package/dist/DropdownMenu/useMenuOverflow.d.ts.map +1 -0
- package/dist/DropdownMenu/useMenuOverflow.js +60 -0
- package/dist/MoreMenu/MoreMenu.d.ts +8 -2
- package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
- package/dist/MoreMenu/MoreMenu.js +2 -0
- package/dist/MultiSelector/MultiSelector.d.ts +11 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +97 -68
- package/dist/MultiSelector/index.d.ts +1 -1
- package/dist/MultiSelector/index.d.ts.map +1 -1
- package/dist/Popover/Popover.d.ts +10 -6
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +141 -16
- package/dist/Popover/usePopover.d.ts +4 -0
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +52 -5
- package/dist/Selector/Selector.d.ts +10 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +106 -80
- package/dist/Selector/SelectorBottomSheet.d.ts +21 -0
- package/dist/Selector/SelectorBottomSheet.d.ts.map +1 -0
- package/dist/Selector/SelectorBottomSheet.js +83 -0
- package/dist/Selector/index.d.ts +1 -1
- package/dist/Selector/index.d.ts.map +1 -1
- package/dist/Selector/selectorPresentation.stylex.d.ts +16 -0
- package/dist/Selector/selectorPresentation.stylex.d.ts.map +1 -0
- package/dist/Selector/selectorPresentation.stylex.js +21 -0
- package/dist/Selector/useSelectorPresentation.d.ts +32 -0
- package/dist/Selector/useSelectorPresentation.d.ts.map +1 -0
- package/dist/Selector/useSelectorPresentation.js +90 -0
- package/dist/Toast/useToastGesture.d.ts.map +1 -1
- package/dist/Toast/useToastGesture.js +46 -9
- package/dist/astryx.css +19 -1
- package/dist/hooks/useAdaptivePresentation.d.ts +5 -0
- package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -0
- package/dist/hooks/useAdaptivePresentation.js +19 -0
- package/dist/hooks/useFocusReturnVisibility.d.ts +7 -0
- package/dist/hooks/useFocusReturnVisibility.d.ts.map +1 -0
- package/dist/hooks/useFocusReturnVisibility.js +35 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +12 -0
- package/locales/en.json +20 -0
- package/locales/pseudo.json +15 -0
- package/package.json +2 -2
- package/src/BottomSheet/BottomSheet.doc.mjs +6 -0
- package/src/BottomSheet/BottomSheet.test.tsx +29 -0
- package/src/BottomSheet/BottomSheet.tsx +7 -4
- package/src/BottomSheet/BottomSheetEdgeTint.test.tsx +4 -6
- package/src/BottomSheet/BottomSheetEdgeTint.tsx +7 -10
- package/src/BottomSheet/BottomSheetSwitcher.tsx +1 -2
- package/src/Button/Button.doc.mjs +56 -0
- package/src/Button/Button.test.tsx +10 -0
- package/src/Button/Button.tsx +13 -5
- package/src/ButtonGroup/ButtonGroup.doc.mjs +47 -0
- package/src/Carousel/Carousel.test.tsx +83 -0
- package/src/Carousel/Carousel.tsx +8 -2
- package/src/Chat/ChatToolCalls.test.tsx +44 -0
- package/src/Chat/ChatToolCalls.tsx +36 -15
- package/src/ContextMenu/ContextMenu.doc.mjs +13 -1
- package/src/ContextMenu/ContextMenu.test.tsx +131 -1
- package/src/ContextMenu/ContextMenu.tsx +199 -32
- package/src/ContextMenu/index.ts +1 -0
- package/src/DropdownMenu/DropdownMenu.doc.mjs +201 -40
- package/src/DropdownMenu/DropdownMenu.test.tsx +518 -7
- package/src/DropdownMenu/DropdownMenu.tsx +459 -28
- package/src/DropdownMenu/DropdownMenuContext.tsx +1 -1
- package/src/DropdownMenu/DropdownMenuItem.tsx +2 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +4 -2
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +124 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +72 -17
- package/src/DropdownMenu/MenuBottomSheet.tsx +46 -0
- package/src/DropdownMenu/MenuBottomSheetActionList.tsx +141 -0
- package/src/DropdownMenu/index.ts +2 -0
- package/src/DropdownMenu/menuWidth.ts +51 -0
- package/src/DropdownMenu/useMenuOverflow.ts +77 -0
- package/src/IconButton/IconButton.doc.mjs +38 -0
- package/src/MoreMenu/MoreMenu.doc.mjs +17 -0
- package/src/MoreMenu/MoreMenu.test.tsx +47 -0
- package/src/MoreMenu/MoreMenu.tsx +13 -1
- package/src/MultiSelector/MultiSelector.doc.mjs +16 -0
- package/src/MultiSelector/MultiSelector.test.tsx +127 -0
- package/src/MultiSelector/MultiSelector.tsx +121 -73
- package/src/MultiSelector/index.ts +1 -0
- package/src/Popover/Popover.doc.mjs +11 -11
- package/src/Popover/Popover.test.tsx +397 -2
- package/src/Popover/Popover.tsx +228 -21
- package/src/Popover/usePopover.tsx +92 -15
- package/src/ProgressBar/ProgressBar.spec.md +208 -0
- package/src/SegmentedControl/SegmentedControl.doc.mjs +56 -0
- package/src/Selector/Selector.doc.mjs +12 -0
- package/src/Selector/Selector.test.tsx +135 -0
- package/src/Selector/Selector.tsx +141 -82
- package/src/Selector/SelectorBottomSheet.tsx +97 -0
- package/src/Selector/index.ts +1 -0
- package/src/Selector/selectorPresentation.stylex.ts +20 -0
- package/src/Selector/useSelectorPresentation.ts +147 -0
- package/src/Toast/ToastViewport.test.tsx +118 -4
- package/src/Toast/useToastGesture.ts +61 -8
- package/src/ToggleButton/ToggleButton.doc.mjs +56 -0
- package/src/hooks/useAdaptivePresentation.ts +35 -0
- package/src/hooks/useFocusReturnVisibility.ts +45 -0
- package/src/hooks/useFocusTrap.test.tsx +40 -0
- package/src/hooks/useFocusTrap.ts +13 -0
- package/src/theme/themingTargets.test.ts +91 -25
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file DropdownMenu.tsx
|
|
7
|
-
* @input Uses React, StyleX, usePopover, Button,
|
|
8
|
-
*
|
|
7
|
+
* @input Uses React, StyleX, usePopover, MenuBottomSheet, Button, List,
|
|
8
|
+
* useListFocus, and the shared viewport-safe menu-width resolver
|
|
9
|
+
* @output Exports DropdownMenu with caller-selected popover or bottom-sheet
|
|
10
|
+
* presentation
|
|
9
11
|
* @position Core implementation; consumed by index.ts
|
|
10
12
|
*
|
|
11
13
|
* Supports two modes with a single keyboard/focus path:
|
|
@@ -30,27 +32,54 @@ import React, { useCallback, useEffect, useId, useMemo, useRef, useState } from
|
|
|
30
32
|
import * as stylex from '@stylexjs/stylex';
|
|
31
33
|
import { usePopoverInternal } from "../Popover/usePopover.js";
|
|
32
34
|
import { Button } from "../Button/index.js";
|
|
35
|
+
import { Heading } from "../Heading/index.js";
|
|
33
36
|
import { Icon } from "../Icon/index.js";
|
|
34
37
|
import { renderDropdownItems } from "./renderDropdownItems.js";
|
|
35
38
|
import { MENU_ITEM_ROLES, MENU_ITEM_SELECTOR, MENU_BOUNDARY_SELECTOR } from "./menuItemRoles.js";
|
|
36
39
|
import { DropdownMenuContext } from "./DropdownMenuContext.js";
|
|
37
40
|
import { useListFocus } from "../hooks/useListFocus.js";
|
|
38
41
|
import { useTypeahead } from "../hooks/useTypeahead.js";
|
|
42
|
+
import { useFocusReturnVisibility } from "../hooks/useFocusReturnVisibility.js";
|
|
43
|
+
import { useMenuOverflow } from "./useMenuOverflow.js";
|
|
44
|
+
import { resolveMenuWidth } from "./menuWidth.js";
|
|
45
|
+
import { useAdaptivePresentation } from "../hooks/useAdaptivePresentation.js";
|
|
46
|
+
import { MenuBottomSheet } from "./MenuBottomSheet.js";
|
|
47
|
+
import { MenuBottomSheetActionList } from "./MenuBottomSheetActionList.js";
|
|
39
48
|
import { layerAnimations } from "../Layer/layerAnimations.stylex.js";
|
|
40
49
|
import "../theme/tokens.stylex.js";
|
|
41
|
-
import { spacingVars, radiusVars, durationVars, easeVars } from "../theme/tokens.stylex.js";
|
|
42
|
-
import { mergeProps } from "../utils/index.js";
|
|
50
|
+
import { spacingVars, colorVars, radiusVars, durationVars, easeVars } from "../theme/tokens.stylex.js";
|
|
51
|
+
import { mergeProps, rtlStyles } from "../utils/index.js";
|
|
43
52
|
import { themeProps } from "../utils/themeProps.js";
|
|
53
|
+
import { getInteractionModality, trackInteractionModality } from "../utils/interactionModality.js";
|
|
44
54
|
import { useTranslator } from "../i18n/index.js";
|
|
45
|
-
import {
|
|
55
|
+
import { focusOutlineStyles } from "../utils/focusOutline.stylex.js";
|
|
56
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
57
|
+
const MENU_VIEWPORT_GUTTER = spacingVars['--spacing-4'];
|
|
58
|
+
const MENU_MAX_INLINE_SIZE = `calc(100vi - max(${MENU_VIEWPORT_GUTTER}, env(safe-area-inset-left, 0px)) - max(${MENU_VIEWPORT_GUTTER}, env(safe-area-inset-right, 0px)))`;
|
|
59
|
+
const MENU_MAX_INLINE_SIZE_FALLBACK = `calc(100vw - ${MENU_VIEWPORT_GUTTER} - ${MENU_VIEWPORT_GUTTER})`;
|
|
60
|
+
const MENU_MAX_BLOCK_SIZE = `min(300px, calc(100dvb - max(${MENU_VIEWPORT_GUTTER}, env(safe-area-inset-top, 0px)) - max(${MENU_VIEWPORT_GUTTER}, env(safe-area-inset-bottom, 0px))))`;
|
|
61
|
+
const MENU_MAX_BLOCK_SIZE_FALLBACK = `min(300px, calc(100vh - ${MENU_VIEWPORT_GUTTER} - ${MENU_VIEWPORT_GUTTER}))`;
|
|
62
|
+
const MENU_POSITION_AREA_MAX_INLINE_SIZE = `calc(100% - max(${MENU_VIEWPORT_GUTTER}, env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px)))`;
|
|
63
|
+
const MENU_POSITION_AREA_MAX_INLINE_SIZE_FALLBACK = `calc(100% - ${MENU_VIEWPORT_GUTTER})`;
|
|
64
|
+
const MENU_INLINE_EDGE_GUTTER = `max(${MENU_VIEWPORT_GUTTER}, env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px))`;
|
|
65
|
+
const MENU_TRIGGER_OPEN_BACKGROUND = `linear-gradient(${colorVars['--color-overlay-pressed']}, ${colorVars['--color-overlay-pressed']})`;
|
|
66
|
+
const _temp = {
|
|
67
|
+
kzqmXN: "x1uyokj7",
|
|
68
|
+
"$$css": true
|
|
69
|
+
};
|
|
46
70
|
const styles = {
|
|
71
|
+
triggerOpen: {
|
|
72
|
+
kKwaWg: "xpl5ynk",
|
|
73
|
+
$$css: true
|
|
74
|
+
},
|
|
47
75
|
dropdown: {
|
|
48
76
|
kB7OPa: "x9f619",
|
|
49
77
|
k1xSpc: "x78zum5",
|
|
50
78
|
kXwgrk: "xdt5ytf",
|
|
51
79
|
kOIVth: "x1lsbc85",
|
|
52
|
-
|
|
53
|
-
|
|
80
|
+
kI3sdo: "x1a2a7pz",
|
|
81
|
+
ks0D6T: "xs2v1xk",
|
|
82
|
+
kskxy: "x1hkkhfe",
|
|
54
83
|
"--_dropdown-menu-radius": "x1fcsqxe",
|
|
55
84
|
"--_dropdown-menu-padding": "xgory14",
|
|
56
85
|
kmVPX3: "x9epnlk",
|
|
@@ -61,17 +90,81 @@ const styles = {
|
|
|
61
90
|
kAMwcw: "xlr8y92",
|
|
62
91
|
$$css: true
|
|
63
92
|
},
|
|
64
|
-
|
|
65
|
-
|
|
93
|
+
scrollable: {
|
|
94
|
+
kORKVm: "x1odjw0f",
|
|
95
|
+
kXHlph: "x6ikm8r",
|
|
96
|
+
kZeWKH: "xish69e",
|
|
97
|
+
$$css: true
|
|
98
|
+
},
|
|
99
|
+
popoverViewport: {
|
|
100
|
+
kB7OPa: "x9f619",
|
|
101
|
+
kskxy: "x1hkkhfe",
|
|
102
|
+
$$css: true
|
|
103
|
+
},
|
|
104
|
+
popoverViewportAligned: {
|
|
105
|
+
ks0D6T: "xbd96yr",
|
|
106
|
+
$$css: true
|
|
107
|
+
},
|
|
108
|
+
popoverViewportStart: {
|
|
109
|
+
k71WvV: "xxeicf8",
|
|
110
|
+
$$css: true
|
|
111
|
+
},
|
|
112
|
+
popoverViewportEnd: {
|
|
113
|
+
keTefX: "x47fqr9",
|
|
114
|
+
$$css: true
|
|
115
|
+
},
|
|
116
|
+
popoverViewportBlockStart: {
|
|
117
|
+
k1K539: "x1kps3mo",
|
|
118
|
+
$$css: true
|
|
119
|
+
},
|
|
120
|
+
popoverViewportBlockEnd: {
|
|
121
|
+
keoZOQ: "xsoubt3",
|
|
122
|
+
$$css: true
|
|
123
|
+
},
|
|
124
|
+
popoverViewportCentered: {
|
|
125
|
+
keTefX: "x47fqr9",
|
|
126
|
+
k71WvV: "xxeicf8",
|
|
127
|
+
ks0D6T: "xs2v1xk",
|
|
128
|
+
$$css: true
|
|
129
|
+
},
|
|
130
|
+
popoverViewportBlockCentered: {
|
|
131
|
+
keoZOQ: "xsoubt3",
|
|
132
|
+
k1K539: "x1kps3mo",
|
|
133
|
+
ks0D6T: "xs2v1xk",
|
|
134
|
+
$$css: true
|
|
135
|
+
},
|
|
136
|
+
popoverAligned: {
|
|
137
|
+
k7Eaqz: "x1ks9poc",
|
|
138
|
+
$$css: true
|
|
139
|
+
},
|
|
140
|
+
popoverCentered: {
|
|
141
|
+
k7Eaqz: "xagy28z",
|
|
66
142
|
$$css: true
|
|
67
143
|
},
|
|
68
144
|
popoverCustomWidth: width => [{
|
|
69
|
-
k7Eaqz:
|
|
145
|
+
k7Eaqz: width != null ? "xkj4a21" : width,
|
|
70
146
|
$$css: true
|
|
71
147
|
}, {
|
|
72
|
-
"--x-minWidth": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(
|
|
148
|
+
"--x-minWidth": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(width)
|
|
149
|
+
}],
|
|
150
|
+
popoverCustomIntrinsicWidth: width => [_temp, {
|
|
151
|
+
"--x-inlineSize": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(width)
|
|
73
152
|
}]
|
|
74
153
|
};
|
|
154
|
+
const bottomSheetStyles = {
|
|
155
|
+
content: {
|
|
156
|
+
kzqmXN: "xh8yej3",
|
|
157
|
+
$$css: true
|
|
158
|
+
},
|
|
159
|
+
rootHeading: {
|
|
160
|
+
keTefX: "x6i7dpz",
|
|
161
|
+
$$css: true
|
|
162
|
+
},
|
|
163
|
+
viewHeading: {
|
|
164
|
+
kI3sdo: "x1a2a7pz",
|
|
165
|
+
$$css: true
|
|
166
|
+
}
|
|
167
|
+
};
|
|
75
168
|
|
|
76
169
|
// =============================================================================
|
|
77
170
|
// Types
|
|
@@ -103,15 +196,16 @@ const styles = {
|
|
|
103
196
|
* A dropdown menu component that displays a list of actionable items.
|
|
104
197
|
*
|
|
105
198
|
* Supports two modes:
|
|
106
|
-
* - **Data-driven**: pass `items`
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
199
|
+
* - **Data-driven**: pass `items` and choose either the default anchored
|
|
200
|
+
* popover or the modal bottom-sheet presentation.
|
|
201
|
+
* - **Compound-component**: pass JSX children for dynamic, stateful, or
|
|
202
|
+
* lazy-loaded anchored popover menus.
|
|
110
203
|
*
|
|
111
204
|
* @example
|
|
112
205
|
* ```
|
|
113
206
|
* <DropdownMenu
|
|
114
207
|
* button={{ label: 'Actions' }}
|
|
208
|
+
* presentation={useBottomSheet ? 'bottom-sheet' : 'popover'}
|
|
115
209
|
* items={[
|
|
116
210
|
* { label: 'Edit', onClick: () => handleEdit() },
|
|
117
211
|
* { label: 'Delete', onClick: () => handleDelete() },
|
|
@@ -123,7 +217,179 @@ const styles = {
|
|
|
123
217
|
// at render time so it respects the active InternationalizationProvider
|
|
124
218
|
// locale.
|
|
125
219
|
const DEFAULT_BUTTON_I18N_KEY = '@astryx.dropdownMenu.label';
|
|
126
|
-
|
|
220
|
+
function DropdownMenuBottomSheet({
|
|
221
|
+
button: buttonFromProps,
|
|
222
|
+
isMenuOpen: controlledIsOpen,
|
|
223
|
+
onOpenChange,
|
|
224
|
+
onClick,
|
|
225
|
+
hasChevron = true,
|
|
226
|
+
items,
|
|
227
|
+
presentation: _presentation,
|
|
228
|
+
menuWidth: _menuWidth,
|
|
229
|
+
placement: _placement,
|
|
230
|
+
alignment: _alignment,
|
|
231
|
+
className,
|
|
232
|
+
style,
|
|
233
|
+
xstyle,
|
|
234
|
+
'data-testid': testId,
|
|
235
|
+
...rest
|
|
236
|
+
}) {
|
|
237
|
+
const t = useTranslator();
|
|
238
|
+
const button = buttonFromProps ?? {
|
|
239
|
+
label: t(DEFAULT_BUTTON_I18N_KEY)
|
|
240
|
+
};
|
|
241
|
+
const backLabel = t('@astryx.dropdownMenu.back');
|
|
242
|
+
const buttonRef = useRef(null);
|
|
243
|
+
const actionListRef = useRef(null);
|
|
244
|
+
const openModalityRef = useRef('pointer');
|
|
245
|
+
const {
|
|
246
|
+
isFocusRingSuppressed,
|
|
247
|
+
onFocusReturnTargetFocus,
|
|
248
|
+
prepareFocusReturn,
|
|
249
|
+
resetFocusReturn
|
|
250
|
+
} = useFocusReturnVisibility();
|
|
251
|
+
const viewHeadingRef = useRef(null);
|
|
252
|
+
const previousSubmenuDepthRef = useRef(0);
|
|
253
|
+
const [internalIsOpen, setInternalIsOpen] = useState(false);
|
|
254
|
+
const [submenuPath, setSubmenuPath] = useState([]);
|
|
255
|
+
const isControlled = controlledIsOpen !== undefined;
|
|
256
|
+
const isOpen = isControlled ? controlledIsOpen : internalIsOpen;
|
|
257
|
+
const [previousIsOpen, setPreviousIsOpen] = useState(isOpen);
|
|
258
|
+
if (previousIsOpen !== isOpen) {
|
|
259
|
+
setPreviousIsOpen(isOpen);
|
|
260
|
+
if (!isOpen && submenuPath.length > 0) {
|
|
261
|
+
setSubmenuPath([]);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
const currentSubmenu = submenuPath.at(-1);
|
|
265
|
+
const currentItems = currentSubmenu?.items ?? items;
|
|
266
|
+
const currentTitle = currentSubmenu?.label ?? button.label;
|
|
267
|
+
const sheetLabel = typeof currentTitle === 'string' ? currentTitle : button.label;
|
|
268
|
+
const setOpen = useCallback(nextIsOpen => {
|
|
269
|
+
if (!nextIsOpen) {
|
|
270
|
+
setSubmenuPath([]);
|
|
271
|
+
prepareFocusReturn();
|
|
272
|
+
} else {
|
|
273
|
+
resetFocusReturn();
|
|
274
|
+
}
|
|
275
|
+
onOpenChange?.(nextIsOpen);
|
|
276
|
+
if (!isControlled) {
|
|
277
|
+
setInternalIsOpen(nextIsOpen);
|
|
278
|
+
}
|
|
279
|
+
}, [isControlled, onOpenChange, prepareFocusReturn, resetFocusReturn]);
|
|
280
|
+
const handleSelect = useCallback(item => {
|
|
281
|
+
if (item.isDisabled) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
item.onClick?.();
|
|
285
|
+
if (item.hasCloseOnSelect !== false) {
|
|
286
|
+
setOpen(false);
|
|
287
|
+
}
|
|
288
|
+
}, [setOpen]);
|
|
289
|
+
const isIconOnly = button.isIconOnly === true;
|
|
290
|
+
const resolvedEndContent = button.endContent ?? (hasChevron && !isIconOnly ? /*#__PURE__*/_jsx(Icon, {
|
|
291
|
+
icon: "chevronDown",
|
|
292
|
+
size: "sm",
|
|
293
|
+
color: "inherit"
|
|
294
|
+
}) : undefined);
|
|
295
|
+
useEffect(() => {
|
|
296
|
+
if (!isOpen || openModalityRef.current !== 'keyboard') {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
const frame = requestAnimationFrame(() => {
|
|
300
|
+
actionListRef.current?.querySelector('button:not(:disabled), a[href]')?.focus({
|
|
301
|
+
preventScroll: true
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
return () => cancelAnimationFrame(frame);
|
|
305
|
+
}, [currentItems, isOpen]);
|
|
306
|
+
useEffect(() => {
|
|
307
|
+
if (!isOpen) {
|
|
308
|
+
previousSubmenuDepthRef.current = 0;
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
if (submenuPath.length === previousSubmenuDepthRef.current) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
previousSubmenuDepthRef.current = submenuPath.length;
|
|
315
|
+
const frame = requestAnimationFrame(() => {
|
|
316
|
+
viewHeadingRef.current?.focus({
|
|
317
|
+
preventScroll: true
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
return () => cancelAnimationFrame(frame);
|
|
321
|
+
}, [isOpen, submenuPath.length]);
|
|
322
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
323
|
+
children: [/*#__PURE__*/_jsx(Button, {
|
|
324
|
+
...button,
|
|
325
|
+
ref: buttonRef,
|
|
326
|
+
xstyle: [isOpen && styles.triggerOpen, button.xstyle, isFocusRingSuppressed && focusOutlineStyles.suppressed],
|
|
327
|
+
tooltip: isOpen ? undefined : button.tooltip,
|
|
328
|
+
endContent: resolvedEndContent,
|
|
329
|
+
onPointerDown: event => {
|
|
330
|
+
button.onPointerDown?.(event);
|
|
331
|
+
openModalityRef.current = 'pointer';
|
|
332
|
+
},
|
|
333
|
+
onKeyDown: event => {
|
|
334
|
+
button.onKeyDown?.(event);
|
|
335
|
+
if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {
|
|
336
|
+
openModalityRef.current = 'keyboard';
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
onFocus: event => {
|
|
340
|
+
button.onFocus?.(event);
|
|
341
|
+
onFocusReturnTargetFocus();
|
|
342
|
+
},
|
|
343
|
+
onClick: () => {
|
|
344
|
+
onClick?.();
|
|
345
|
+
setOpen(!isOpen);
|
|
346
|
+
},
|
|
347
|
+
"aria-haspopup": "dialog",
|
|
348
|
+
"aria-expanded": isOpen,
|
|
349
|
+
"data-testid": testId
|
|
350
|
+
}), /*#__PURE__*/_jsx(MenuBottomSheet, {
|
|
351
|
+
isOpen: isOpen,
|
|
352
|
+
onOpenChange: setOpen,
|
|
353
|
+
finalFocusRef: buttonRef,
|
|
354
|
+
label: sheetLabel,
|
|
355
|
+
children: /*#__PURE__*/_jsxs("div", {
|
|
356
|
+
ref: actionListRef,
|
|
357
|
+
...rest,
|
|
358
|
+
...mergeProps(themeProps('dropdown-menu', {
|
|
359
|
+
presentation: 'bottom-sheet'
|
|
360
|
+
}), stylex.props(bottomSheetStyles.content, xstyle), className, style),
|
|
361
|
+
children: [/*#__PURE__*/_jsxs("div", {
|
|
362
|
+
...{
|
|
363
|
+
className: "x78zum5 x1q0g3np x6s0dn4 xzye2dw x1p37lm5"
|
|
364
|
+
},
|
|
365
|
+
children: [submenuPath.length > 0 && /*#__PURE__*/_jsx(Button, {
|
|
366
|
+
label: backLabel,
|
|
367
|
+
variant: "ghost",
|
|
368
|
+
size: "sm",
|
|
369
|
+
icon: /*#__PURE__*/_jsx(Icon, {
|
|
370
|
+
icon: "chevronLeft",
|
|
371
|
+
size: "sm",
|
|
372
|
+
xstyle: rtlStyles.mirror
|
|
373
|
+
}),
|
|
374
|
+
isIconOnly: true,
|
|
375
|
+
onClick: () => setSubmenuPath(path => path.slice(0, -1))
|
|
376
|
+
}), /*#__PURE__*/_jsx(Heading, {
|
|
377
|
+
ref: viewHeadingRef,
|
|
378
|
+
level: 3,
|
|
379
|
+
tabIndex: -1,
|
|
380
|
+
xstyle: [bottomSheetStyles.viewHeading, submenuPath.length === 0 && bottomSheetStyles.rootHeading],
|
|
381
|
+
children: currentTitle
|
|
382
|
+
})]
|
|
383
|
+
}), /*#__PURE__*/_jsx(MenuBottomSheetActionList, {
|
|
384
|
+
items: currentItems,
|
|
385
|
+
onSelect: handleSelect,
|
|
386
|
+
onOpenSubmenu: item => setSubmenuPath(path => [...path, item])
|
|
387
|
+
})]
|
|
388
|
+
})
|
|
389
|
+
})]
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
function DropdownMenuPopover({
|
|
127
393
|
button: buttonFromProps,
|
|
128
394
|
isMenuOpen: controlledIsOpen,
|
|
129
395
|
onOpenChange,
|
|
@@ -132,6 +398,7 @@ export function DropdownMenu({
|
|
|
132
398
|
hasChevron = true,
|
|
133
399
|
placement = 'below',
|
|
134
400
|
alignment = 'start',
|
|
401
|
+
presentation: _presentation,
|
|
135
402
|
className,
|
|
136
403
|
style,
|
|
137
404
|
xstyle,
|
|
@@ -160,14 +427,25 @@ export function DropdownMenu({
|
|
|
160
427
|
const [internalIsOpen, setInternalIsOpen] = useState(false);
|
|
161
428
|
const isControlled = controlledIsOpen !== undefined;
|
|
162
429
|
const isOpen = isControlled ? controlledIsOpen : internalIsOpen;
|
|
430
|
+
useEffect(() => {
|
|
431
|
+
trackInteractionModality();
|
|
432
|
+
}, []);
|
|
163
433
|
|
|
164
|
-
//
|
|
434
|
+
// Keyboard dismissal returns focus to the trigger. Pointer dismissal leaves
|
|
435
|
+
// focus where the browser put it; Safari can otherwise paint a focus-visible
|
|
436
|
+
// ring on the trigger after a touch selection. Native popover restoration
|
|
437
|
+
// can happen before `toggle`, so explicitly blur that pointer-restored case.
|
|
165
438
|
const handleLayerHide = useCallback(() => {
|
|
166
439
|
onOpenChange?.(false);
|
|
167
440
|
if (!isControlled) {
|
|
168
441
|
setInternalIsOpen(false);
|
|
169
442
|
}
|
|
170
|
-
buttonRef.current
|
|
443
|
+
const trigger = buttonRef.current;
|
|
444
|
+
if (getInteractionModality() === 'keyboard') {
|
|
445
|
+
trigger?.focus();
|
|
446
|
+
} else if (document.activeElement === trigger) {
|
|
447
|
+
trigger?.blur();
|
|
448
|
+
}
|
|
171
449
|
}, [isControlled, onOpenChange]);
|
|
172
450
|
|
|
173
451
|
// Defer item focus until the layer has committed open, so focus restore
|
|
@@ -336,7 +614,10 @@ export function DropdownMenu({
|
|
|
336
614
|
size: "sm",
|
|
337
615
|
color: "inherit"
|
|
338
616
|
}) : undefined);
|
|
339
|
-
const
|
|
617
|
+
const requestedWidthLimit = alignment === 'center' ? MENU_MAX_INLINE_SIZE_FALLBACK : MENU_POSITION_AREA_MAX_INLINE_SIZE_FALLBACK;
|
|
618
|
+
const resolvedMenuWidth = menuWidth ? resolveMenuWidth(menuWidth, requestedWidthLimit) : null;
|
|
619
|
+
const popoverXstyle = resolvedMenuWidth ? resolvedMenuWidth.property === 'inlineSize' ? styles.popoverCustomIntrinsicWidth(resolvedMenuWidth.value) : styles.popoverCustomWidth(resolvedMenuWidth.value) : alignment === 'center' ? styles.popoverCentered : styles.popoverAligned;
|
|
620
|
+
const isSidePlacement = placement === 'start' || placement === 'end';
|
|
340
621
|
// Context for compound items
|
|
341
622
|
const contextValue = useMemo(() => ({
|
|
342
623
|
closeMenu,
|
|
@@ -345,6 +626,7 @@ export function DropdownMenu({
|
|
|
345
626
|
|
|
346
627
|
// Resolve menu content: data-driven items become components
|
|
347
628
|
const menuContent = props.items !== undefined ? renderDropdownItems(items) : children;
|
|
629
|
+
const hasOverflow = useMenuOverflow(listRef, menuContent, popover.isOpen);
|
|
348
630
|
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
349
631
|
children: [/*#__PURE__*/_jsx(Button, {
|
|
350
632
|
...button,
|
|
@@ -360,6 +642,7 @@ export function DropdownMenu({
|
|
|
360
642
|
/* eslint-enable react-compiler/react-compiler */
|
|
361
643
|
}
|
|
362
644
|
},
|
|
645
|
+
xstyle: [isOpen && styles.triggerOpen, button.xstyle],
|
|
363
646
|
tooltip: isOpen ? undefined : button.tooltip,
|
|
364
647
|
endContent: resolvedEndContent,
|
|
365
648
|
onClick: handleButtonClick,
|
|
@@ -373,19 +656,19 @@ export function DropdownMenu({
|
|
|
373
656
|
ref: listRef,
|
|
374
657
|
id: menuId,
|
|
375
658
|
role: "menu"
|
|
376
|
-
//
|
|
377
|
-
//
|
|
378
|
-
//
|
|
379
|
-
//
|
|
659
|
+
// Pointer opens focus the container so arrows, typeahead, Escape and
|
|
660
|
+
// Tab remain owned by the menu without pre-highlighting an item.
|
|
661
|
+
// An overflowing menu joins the Tab order so its scrollable region is
|
|
662
|
+
// keyboard-accessible; Tab still dismisses through listKeyDown.
|
|
380
663
|
,
|
|
381
|
-
tabIndex: -1
|
|
664
|
+
tabIndex: hasOverflow ? 0 : -1
|
|
382
665
|
// Give the menu an accessible name from its trigger's label, so
|
|
383
666
|
// screen readers announce e.g. "Actions menu" rather than an unnamed
|
|
384
667
|
// menu (menus-13).
|
|
385
668
|
,
|
|
386
669
|
"aria-label": button.label,
|
|
387
670
|
onKeyDown: listKeyDown,
|
|
388
|
-
...mergeProps(themeProps('dropdown-menu'), stylex.props(styles.dropdown, xstyle), className, style),
|
|
671
|
+
...mergeProps(themeProps('dropdown-menu'), stylex.props(styles.dropdown, hasOverflow && styles.scrollable, xstyle), className, style),
|
|
389
672
|
children: /*#__PURE__*/_jsx(DropdownMenuContext, {
|
|
390
673
|
value: contextValue,
|
|
391
674
|
children: menuContent
|
|
@@ -394,8 +677,39 @@ export function DropdownMenu({
|
|
|
394
677
|
placement,
|
|
395
678
|
alignment,
|
|
396
679
|
offset: spacingVars['--spacing-1'],
|
|
397
|
-
xstyle: [popoverXstyle, layerAnimations[placement]]
|
|
680
|
+
xstyle: [styles.popoverViewport, alignment === 'center' ? isSidePlacement ? styles.popoverViewportBlockCentered : styles.popoverViewportCentered : [styles.popoverViewportAligned, isSidePlacement ? alignment === 'start' ? styles.popoverViewportBlockStart : styles.popoverViewportBlockEnd : alignment === 'start' ? styles.popoverViewportStart : styles.popoverViewportEnd], popoverXstyle, layerAnimations[placement]]
|
|
398
681
|
})]
|
|
399
682
|
});
|
|
400
683
|
}
|
|
684
|
+
export function DropdownMenu(props) {
|
|
685
|
+
const {
|
|
686
|
+
onOpenChange
|
|
687
|
+
} = props;
|
|
688
|
+
const requestedPresentation = 'items' in props ? props.presentation ?? 'popover' : 'popover';
|
|
689
|
+
const resolvedPresentation = useAdaptivePresentation(requestedPresentation);
|
|
690
|
+
const isControlled = props.isMenuOpen !== undefined;
|
|
691
|
+
const [internalIsOpen, setInternalIsOpen] = useState(false);
|
|
692
|
+
const isOpen = isControlled ? props.isMenuOpen : internalIsOpen;
|
|
693
|
+
const handleOpenChange = useCallback(nextIsOpen => {
|
|
694
|
+
onOpenChange?.(nextIsOpen);
|
|
695
|
+
if (!isControlled) {
|
|
696
|
+
setInternalIsOpen(nextIsOpen);
|
|
697
|
+
}
|
|
698
|
+
}, [isControlled, onOpenChange]);
|
|
699
|
+
const sharedProps = {
|
|
700
|
+
...props,
|
|
701
|
+
isMenuOpen: isOpen,
|
|
702
|
+
onOpenChange: handleOpenChange
|
|
703
|
+
};
|
|
704
|
+
if (resolvedPresentation === 'bottom-sheet' && 'items' in props && props.items !== undefined) {
|
|
705
|
+
return /*#__PURE__*/_jsx(DropdownMenuBottomSheet, {
|
|
706
|
+
...sharedProps,
|
|
707
|
+
presentation: "bottom-sheet"
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
return /*#__PURE__*/_jsx(DropdownMenuPopover, {
|
|
711
|
+
...sharedProps,
|
|
712
|
+
presentation: "popover"
|
|
713
|
+
});
|
|
714
|
+
}
|
|
401
715
|
DropdownMenu.displayName = 'DropdownMenu';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Menu size, derived from the trigger button size. */
|
|
2
2
|
export type DropdownMenuSize = 'sm' | 'md' | 'lg';
|
|
3
3
|
export interface DropdownMenuContextValue {
|
|
4
|
-
/** Close the menu
|
|
4
|
+
/** Close the menu; keyboard dismissal returns focus to the trigger. */
|
|
5
5
|
closeMenu: () => void;
|
|
6
6
|
/** Menu size derived from button size */
|
|
7
7
|
menuSize: DropdownMenuSize;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropdownMenuContext.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenuContext.tsx"],"names":[],"mappings":"AAgBA,uDAAuD;AACvD,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAElD,MAAM,WAAW,wBAAwB;IACvC,
|
|
1
|
+
{"version":3,"file":"DropdownMenuContext.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenuContext.tsx"],"names":[],"mappings":"AAgBA,uDAAuD;AACvD,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAElD,MAAM,WAAW,wBAAwB;IACvC,uEAAuE;IACvE,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,yCAAyC;IACzC,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED,eAAO,MAAM,mBAAmB,0DACsB,CAAC;AAGvD;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,wBAAwB,GAAG,IAAI,CAExE;AAMD,MAAM,WAAW,kCAAkC;IACjD,iDAAiD;IACjD,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,uEAAuE;IACvE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,qEAAqE;IACrE,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,6BAA6B,oEACsB,CAAC;AAGjE;;;GAGG;AACH,wBAAgB,gCAAgC,IAAI,kCAAkC,GAAG,IAAI,CAE5F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropdownMenuItem.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenuItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAiC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAErE,OAAO,EAAiB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AAStD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"DropdownMenuItem.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenuItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAiC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAErE,OAAO,EAAiB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AAStD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAuD5C,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CACjD,SAAS,EACT,QAAQ,GAAG,WAAW,GAAG,OAAO,CACjC;IACC,wCAAwC;IACxC,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC5B,0BAA0B;IAC1B,KAAK,EAAE,SAAS,CAAC;IACjB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,mDAAmD;IACnD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gEAAgE;IAChE,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;CACrC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,KAAK,EACL,WAAW,EACX,OAAO,EACP,UAAkB,EAClB,UAAU,EACV,gBAAuB,EACvB,OAAmB,EACnB,MAAM,EACN,SAAS,EACT,KAAK,GACN,EAAE,qBAAqB,+BA0DvB;yBAtEe,gBAAgB"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file DropdownMenuSubMenu.tsx
|
|
3
3
|
* @input React, stylex, useLayer (context mode), useListFocus, useMenuHover,
|
|
4
|
-
* useTypeahead,
|
|
4
|
+
* useTypeahead, the shared viewport-safe menu-width resolver, Item, Icon,
|
|
5
|
+
* Spinner, and DropdownMenu context + item roles
|
|
5
6
|
* @output Exports DropdownMenuSubMenu — a single menu row that reveals a nested
|
|
6
7
|
* flyout menu of its own children/items.
|
|
7
8
|
* @position Sub-component; place inside a DropdownMenu (or ContextMenu)
|
|
@@ -55,7 +56,10 @@ interface DropdownMenuSubMenuBaseProps extends Pick<BaseProps, 'xstyle' | 'class
|
|
|
55
56
|
* @default false
|
|
56
57
|
*/
|
|
57
58
|
hasSpinner?: boolean;
|
|
58
|
-
/**
|
|
59
|
+
/**
|
|
60
|
+
* Minimum flyout width. The flyout may grow for its content but is capped to
|
|
61
|
+
* the available viewport space. Defaults to intrinsic sizing (min 160px).
|
|
62
|
+
*/
|
|
59
63
|
menuWidth?: number | string;
|
|
60
64
|
/** Called when the flyout opens or closes. */
|
|
61
65
|
onOpenChange?: (isOpen: boolean) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropdownMenuSubMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenuSubMenu.tsx"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"DropdownMenuSubMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenuSubMenu.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAc,EAOZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,EAAuB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AAsB5D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AA4H5C,UAAU,4BAA6B,SAAQ,IAAI,CACjD,SAAS,EACT,QAAQ,GAAG,WAAW,GAAG,OAAO,CACjC;IACC,2DAA2D;IAC3D,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC5B,8CAA8C;IAC9C,KAAK,EAAE,SAAS,CAAC;IACjB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,8CAA8C;IAC9C,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,mCAAmC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mCAAmC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,wBAAyB,SAAQ,4BAA4B;IAC5E;;;;;;;;OAQG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,wBAAwB,GAC9B,SAAS,CAkWX;yBApWe,mBAAmB"}
|