@bazza-ui/react 0.0.0 → 0.1.0-canary.10
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/ListboxStore-BYBpGrOz.d.ts +453 -0
- package/dist/ListboxStore-nmorsoqX.d.cts +453 -0
- package/dist/chunk-4C666HHU.js +2 -0
- package/dist/chunk-4C666HHU.js.map +1 -0
- package/dist/chunk-5T5B5SPR.cjs +2 -0
- package/dist/chunk-5T5B5SPR.cjs.map +1 -0
- package/dist/chunk-A4Z5BY7H.js +2 -0
- package/dist/chunk-A4Z5BY7H.js.map +1 -0
- package/dist/chunk-BFOY762U.js +2 -0
- package/dist/chunk-BFOY762U.js.map +1 -0
- package/dist/chunk-IT372NHF.js +2 -0
- package/dist/chunk-IT372NHF.js.map +1 -0
- package/dist/chunk-JFEVUUPC.cjs +2 -0
- package/dist/chunk-JFEVUUPC.cjs.map +1 -0
- package/dist/chunk-KO3DXT3Y.js +2 -0
- package/dist/chunk-KO3DXT3Y.js.map +1 -0
- package/dist/chunk-LXXK4S4Q.js +2 -0
- package/dist/chunk-LXXK4S4Q.js.map +1 -0
- package/dist/chunk-M4G6J7DP.cjs +2 -0
- package/dist/chunk-M4G6J7DP.cjs.map +1 -0
- package/dist/chunk-SCDHQZFI.cjs +2 -0
- package/dist/chunk-SCDHQZFI.cjs.map +1 -0
- package/dist/chunk-W4ACKMIZ.cjs +2 -0
- package/dist/chunk-W4ACKMIZ.cjs.map +1 -0
- package/dist/chunk-XMZZ62VJ.cjs +2 -0
- package/dist/chunk-XMZZ62VJ.cjs.map +1 -0
- package/dist/combobox/index.cjs +2 -0
- package/dist/combobox/index.cjs.map +1 -0
- package/dist/combobox/index.d.cts +1066 -0
- package/dist/combobox/index.d.ts +1066 -0
- package/dist/combobox/index.js +2 -0
- package/dist/combobox/index.js.map +1 -0
- package/dist/command-menu/index.cjs +2 -0
- package/dist/command-menu/index.cjs.map +1 -0
- package/dist/command-menu/index.d.cts +154 -0
- package/dist/command-menu/index.d.ts +154 -0
- package/dist/command-menu/index.js +2 -0
- package/dist/command-menu/index.js.map +1 -0
- package/dist/command-score-CTJ9NV6n.d.cts +23 -0
- package/dist/command-score-CTJ9NV6n.d.ts +23 -0
- package/dist/context-menu/index.cjs +2 -0
- package/dist/context-menu/index.cjs.map +1 -0
- package/dist/context-menu/index.d.cts +672 -0
- package/dist/context-menu/index.d.ts +672 -0
- package/dist/context-menu/index.js +2 -0
- package/dist/context-menu/index.js.map +1 -0
- package/dist/dropdown-menu/index.cjs +2 -0
- package/dist/dropdown-menu/index.cjs.map +1 -0
- package/dist/dropdown-menu/index.d.cts +699 -0
- package/dist/dropdown-menu/index.d.ts +699 -0
- package/dist/dropdown-menu/index.js +2 -0
- package/dist/dropdown-menu/index.js.map +1 -0
- package/dist/events-DOGItflK.d.ts +1776 -0
- package/dist/events-DPsuhBln.d.cts +1776 -0
- package/dist/input-C95v6jB0.d.cts +46 -0
- package/dist/input-CYweYB_i.d.ts +46 -0
- package/dist/internal/listbox/index.cjs +2 -0
- package/dist/internal/listbox/index.cjs.map +1 -0
- package/dist/internal/listbox/index.d.cts +272 -0
- package/dist/internal/listbox/index.d.ts +272 -0
- package/dist/internal/listbox/index.js +2 -0
- package/dist/internal/listbox/index.js.map +1 -0
- package/dist/internal/popup-menu/index.cjs +2 -0
- package/dist/internal/popup-menu/index.cjs.map +1 -0
- package/dist/internal/popup-menu/index.d.cts +238 -0
- package/dist/internal/popup-menu/index.d.ts +238 -0
- package/dist/internal/popup-menu/index.js +2 -0
- package/dist/internal/popup-menu/index.js.map +1 -0
- package/dist/items-B6HeFO_8.d.cts +37 -0
- package/dist/items-B6HeFO_8.d.ts +37 -0
- package/dist/kbd/index.cjs +2 -0
- package/dist/kbd/index.cjs.map +1 -0
- package/dist/kbd/index.d.cts +61 -0
- package/dist/kbd/index.d.ts +61 -0
- package/dist/kbd/index.js +2 -0
- package/dist/kbd/index.js.map +1 -0
- package/dist/loaders/index.cjs +2 -0
- package/dist/loaders/index.cjs.map +1 -0
- package/dist/loaders/index.d.cts +363 -0
- package/dist/loaders/index.d.ts +363 -0
- package/dist/loaders/index.js +2 -0
- package/dist/loaders/index.js.map +1 -0
- package/dist/loading-C6WZGUc3.d.cts +29 -0
- package/dist/loading-CC4n55sR.d.ts +29 -0
- package/dist/resolve-BYm41YfG.d.ts +406 -0
- package/dist/resolve-Dk_fAKb2.d.cts +406 -0
- package/dist/scroll-arrow-B81wZTZ2.d.cts +544 -0
- package/dist/scroll-arrow-CNd0tgME.d.ts +544 -0
- package/dist/select/index.cjs +2 -0
- package/dist/select/index.cjs.map +1 -0
- package/dist/select/index.d.cts +985 -0
- package/dist/select/index.d.ts +985 -0
- package/dist/select/index.js +2 -0
- package/dist/select/index.js.map +1 -0
- package/dist/separator-BiySI623.d.cts +275 -0
- package/dist/separator-De8l8DKO.d.ts +275 -0
- package/dist/surface-context-ClmxshBW.d.ts +14 -0
- package/dist/surface-context-DF-L-30G.d.cts +14 -0
- package/dist/type-guards-BC2B6bVi.d.cts +350 -0
- package/dist/type-guards-ybcHBB3C.d.ts +350 -0
- package/dist/types-DT4FOOa2.d.cts +51 -0
- package/dist/types-DT4FOOa2.d.ts +51 -0
- package/dist/use-listbox-item-NzZuY34-.d.cts +212 -0
- package/dist/use-listbox-item-NzZuY34-.d.ts +212 -0
- package/dist/video-player/index.cjs +3 -0
- package/dist/video-player/index.cjs.map +1 -0
- package/dist/video-player/index.d.cts +1391 -0
- package/dist/video-player/index.d.ts +1391 -0
- package/dist/video-player/index.js +3 -0
- package/dist/video-player/index.js.map +1 -0
- package/package.json +66 -12
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -2
|
@@ -0,0 +1,1776 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { C as ComponentProps } from './types-DT4FOOa2.cjs';
|
|
3
|
+
|
|
4
|
+
declare const triggerPress: "trigger-press";
|
|
5
|
+
declare const triggerHover: "trigger-hover";
|
|
6
|
+
declare const triggerFocus: "trigger-focus";
|
|
7
|
+
declare const triggerContextMenu: "trigger-context-menu";
|
|
8
|
+
declare const escapeKey: "escape-key";
|
|
9
|
+
declare const outsidePress: "outside-press";
|
|
10
|
+
declare const focusOut: "focus-out";
|
|
11
|
+
declare const itemPress: "item-press";
|
|
12
|
+
declare const itemKeyboardSelect: "item-keyboard-select";
|
|
13
|
+
declare const closePress: "close-press";
|
|
14
|
+
declare const inputChange: "input-change";
|
|
15
|
+
declare const inputClear: "input-clear";
|
|
16
|
+
declare const clearPress: "clear-press";
|
|
17
|
+
declare const listNavigation: "list-navigation";
|
|
18
|
+
declare const submenuTrigger: "submenu-trigger";
|
|
19
|
+
declare const siblingOpen: "sibling-open";
|
|
20
|
+
declare const pointer: "pointer";
|
|
21
|
+
declare const keyboard: "keyboard";
|
|
22
|
+
declare const auto: "auto";
|
|
23
|
+
declare const imperativeAction: "imperative-action";
|
|
24
|
+
declare const none: "none";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Maps event reason strings to their corresponding native DOM event types.
|
|
28
|
+
* This provides type-safe access to the native event based on the reason.
|
|
29
|
+
*/
|
|
30
|
+
interface ReasonToEventMap {
|
|
31
|
+
[none]: Event;
|
|
32
|
+
[triggerPress]: MouseEvent | PointerEvent | TouchEvent | KeyboardEvent;
|
|
33
|
+
[triggerHover]: MouseEvent | PointerEvent;
|
|
34
|
+
[triggerFocus]: FocusEvent;
|
|
35
|
+
[triggerContextMenu]: MouseEvent;
|
|
36
|
+
[escapeKey]: KeyboardEvent;
|
|
37
|
+
[outsidePress]: MouseEvent | PointerEvent | TouchEvent;
|
|
38
|
+
[focusOut]: FocusEvent | KeyboardEvent;
|
|
39
|
+
[itemPress]: MouseEvent | PointerEvent | KeyboardEvent;
|
|
40
|
+
[itemKeyboardSelect]: KeyboardEvent;
|
|
41
|
+
[closePress]: MouseEvent | PointerEvent | KeyboardEvent;
|
|
42
|
+
[inputChange]: InputEvent | Event;
|
|
43
|
+
[inputClear]: InputEvent | FocusEvent | Event;
|
|
44
|
+
[clearPress]: MouseEvent | PointerEvent | KeyboardEvent;
|
|
45
|
+
[listNavigation]: KeyboardEvent;
|
|
46
|
+
[submenuTrigger]: MouseEvent | PointerEvent | KeyboardEvent;
|
|
47
|
+
[siblingOpen]: Event;
|
|
48
|
+
[pointer]: MouseEvent | PointerEvent;
|
|
49
|
+
[keyboard]: KeyboardEvent;
|
|
50
|
+
[imperativeAction]: Event;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Maps a reason string to the corresponding native event type.
|
|
54
|
+
* Falls back to `Event` for unknown reasons.
|
|
55
|
+
*/
|
|
56
|
+
type ReasonToEvent<Reason extends string> = Reason extends keyof ReasonToEventMap ? ReasonToEventMap[Reason] : Event;
|
|
57
|
+
/**
|
|
58
|
+
* Details object passed to change event handlers (onOpenChange, onValueChange, etc.)
|
|
59
|
+
*
|
|
60
|
+
* @template Reason - The union of allowed reason strings for this event
|
|
61
|
+
* @template CustomProperties - Additional component-specific properties
|
|
62
|
+
*/
|
|
63
|
+
interface ChangeEventDetails<Reason extends string, _CustomProperties extends object = Record<string, never>> {
|
|
64
|
+
/**
|
|
65
|
+
* The reason why this state change occurred.
|
|
66
|
+
* Use this to conditionally handle different scenarios.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```tsx
|
|
70
|
+
* onOpenChange={(open, details) => {
|
|
71
|
+
* if (details.reason === 'escape-key') {
|
|
72
|
+
* // Handle escape key differently
|
|
73
|
+
* }
|
|
74
|
+
* }}
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
reason: Reason;
|
|
78
|
+
/**
|
|
79
|
+
* The native DOM event that triggered this change.
|
|
80
|
+
* May be a synthetic event in some cases.
|
|
81
|
+
*/
|
|
82
|
+
event: ReasonToEvent<Reason>;
|
|
83
|
+
/**
|
|
84
|
+
* Cancels the state change.
|
|
85
|
+
* When called, the component's internal state will not update.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```tsx
|
|
89
|
+
* onOpenChange={(open, details) => {
|
|
90
|
+
* if (!open && details.reason === 'outside-press') {
|
|
91
|
+
* details.cancel() // Prevent closing on outside press
|
|
92
|
+
* }
|
|
93
|
+
* }}
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
cancel: () => void;
|
|
97
|
+
/**
|
|
98
|
+
* Allows the native event to propagate.
|
|
99
|
+
* By default, some events (like Escape key) stop propagation
|
|
100
|
+
* to prevent parent popups from closing simultaneously.
|
|
101
|
+
*/
|
|
102
|
+
allowPropagation: () => void;
|
|
103
|
+
/**
|
|
104
|
+
* Whether `cancel()` has been called.
|
|
105
|
+
*/
|
|
106
|
+
readonly isCanceled: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Whether `allowPropagation()` has been called.
|
|
109
|
+
*/
|
|
110
|
+
readonly isPropagationAllowed: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* The element that triggered this event, if applicable.
|
|
113
|
+
*/
|
|
114
|
+
trigger: Element | undefined;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Details object for generic events that don't support cancellation.
|
|
118
|
+
* Used for events like onHighlightChange where cancellation doesn't make sense.
|
|
119
|
+
*
|
|
120
|
+
* @template Reason - The union of allowed reason strings for this event
|
|
121
|
+
* @template CustomProperties - Additional component-specific properties
|
|
122
|
+
*/
|
|
123
|
+
interface GenericEventDetails<Reason extends string, _CustomProperties extends object = Record<string, never>> {
|
|
124
|
+
/**
|
|
125
|
+
* The reason why this event occurred.
|
|
126
|
+
*/
|
|
127
|
+
reason: Reason;
|
|
128
|
+
/**
|
|
129
|
+
* The native DOM event that triggered this event.
|
|
130
|
+
*/
|
|
131
|
+
event: ReasonToEvent<Reason>;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
interface PopupMenuCheckboxItemState extends Record<string, unknown> {
|
|
135
|
+
/**
|
|
136
|
+
* Whether the item is highlighted (via keyboard or pointer).
|
|
137
|
+
*/
|
|
138
|
+
highlighted: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Whether the item is disabled.
|
|
141
|
+
*/
|
|
142
|
+
disabled: boolean;
|
|
143
|
+
/**
|
|
144
|
+
* Whether the item is currently checked.
|
|
145
|
+
*/
|
|
146
|
+
checked: boolean;
|
|
147
|
+
first: boolean;
|
|
148
|
+
last: boolean;
|
|
149
|
+
firstInGroup: boolean;
|
|
150
|
+
lastInGroup: boolean;
|
|
151
|
+
}
|
|
152
|
+
interface PopupMenuCheckboxItemProps extends ComponentProps<'div', PopupMenuCheckboxItem.State> {
|
|
153
|
+
/**
|
|
154
|
+
* The controlled checked state.
|
|
155
|
+
*/
|
|
156
|
+
checked?: boolean;
|
|
157
|
+
/**
|
|
158
|
+
* The default checked state for uncontrolled mode.
|
|
159
|
+
* @default false
|
|
160
|
+
*/
|
|
161
|
+
defaultChecked?: boolean;
|
|
162
|
+
/**
|
|
163
|
+
* Callback fired when the checked state changes.
|
|
164
|
+
* The second parameter contains event details including the reason for the change.
|
|
165
|
+
*/
|
|
166
|
+
onCheckedChange?: (checked: boolean, eventDetails: CheckedChangeEventDetails) => void;
|
|
167
|
+
/**
|
|
168
|
+
* Unique value for this item used for filtering.
|
|
169
|
+
* If not provided, will be inferred from textContent.
|
|
170
|
+
*/
|
|
171
|
+
value?: string;
|
|
172
|
+
/**
|
|
173
|
+
* Additional keywords to match against when filtering.
|
|
174
|
+
* Useful for aliases or synonyms.
|
|
175
|
+
*/
|
|
176
|
+
keywords?: string[];
|
|
177
|
+
/**
|
|
178
|
+
* Whether this item is disabled.
|
|
179
|
+
* Disabled items are not selectable and are skipped during keyboard navigation.
|
|
180
|
+
* @default false
|
|
181
|
+
*/
|
|
182
|
+
disabled?: boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Callback when this item is selected (via click or Enter key).
|
|
185
|
+
*/
|
|
186
|
+
onSelect?: () => void;
|
|
187
|
+
/**
|
|
188
|
+
* Whether to force render this item regardless of filter results.
|
|
189
|
+
* @default false
|
|
190
|
+
*/
|
|
191
|
+
forceMount?: boolean;
|
|
192
|
+
/**
|
|
193
|
+
* Whether clicking this item should close the menu.
|
|
194
|
+
* @default false
|
|
195
|
+
*/
|
|
196
|
+
closeOnClick?: boolean;
|
|
197
|
+
/**
|
|
198
|
+
* Keyboard shortcut to trigger this item.
|
|
199
|
+
* When the menu is focused and the user presses this key, the item will be selected.
|
|
200
|
+
* Should be a single character (e.g., "1", "a", etc.).
|
|
201
|
+
*/
|
|
202
|
+
shortcut?: string;
|
|
203
|
+
/**
|
|
204
|
+
* Forces this row's relative order during score-based sorting.
|
|
205
|
+
* Lower values appear earlier.
|
|
206
|
+
* @default 0
|
|
207
|
+
*/
|
|
208
|
+
forceOrder?: number;
|
|
209
|
+
/**
|
|
210
|
+
* Overrides this row's computed fuzzy-match score.
|
|
211
|
+
*/
|
|
212
|
+
forceScore?: number;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* A selectable checkbox item within a popup menu.
|
|
216
|
+
* Manages its own checked state independently.
|
|
217
|
+
* Renders a `<div>` element with role="menuitemcheckbox".
|
|
218
|
+
*/
|
|
219
|
+
declare const PopupMenuCheckboxItem: React.ForwardRefExoticComponent<Omit<PopupMenuCheckboxItem.Props, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
220
|
+
declare namespace PopupMenuCheckboxItem {
|
|
221
|
+
type State = PopupMenuCheckboxItemState;
|
|
222
|
+
interface Props extends PopupMenuCheckboxItemProps {
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
interface PopupMenuItemState extends Record<string, unknown> {
|
|
227
|
+
/**
|
|
228
|
+
* Whether the item is highlighted (via keyboard or pointer).
|
|
229
|
+
*/
|
|
230
|
+
highlighted: boolean;
|
|
231
|
+
/**
|
|
232
|
+
* Whether the item is disabled.
|
|
233
|
+
*/
|
|
234
|
+
disabled: boolean;
|
|
235
|
+
first: boolean;
|
|
236
|
+
last: boolean;
|
|
237
|
+
firstInGroup: boolean;
|
|
238
|
+
lastInGroup: boolean;
|
|
239
|
+
}
|
|
240
|
+
interface PopupMenuItemProps extends ComponentProps<'div', PopupMenuItem.State> {
|
|
241
|
+
/**
|
|
242
|
+
* Unique value for this item used for filtering.
|
|
243
|
+
* If not provided, will be inferred from textContent.
|
|
244
|
+
*/
|
|
245
|
+
value?: string;
|
|
246
|
+
/**
|
|
247
|
+
* Additional keywords to match against when filtering.
|
|
248
|
+
* Useful for aliases or synonyms.
|
|
249
|
+
*/
|
|
250
|
+
keywords?: string[];
|
|
251
|
+
/**
|
|
252
|
+
* Whether this item is disabled.
|
|
253
|
+
* Disabled items are not selectable and are skipped during keyboard navigation.
|
|
254
|
+
*/
|
|
255
|
+
disabled?: boolean;
|
|
256
|
+
/**
|
|
257
|
+
* Whether this item can be activated via Enter or click.
|
|
258
|
+
* Non-activatable items are still highlightable via keyboard/pointer.
|
|
259
|
+
* @default true
|
|
260
|
+
*/
|
|
261
|
+
activatable?: boolean;
|
|
262
|
+
/**
|
|
263
|
+
* Callback when this item is selected (via click or Enter key).
|
|
264
|
+
*/
|
|
265
|
+
onSelect?: () => void;
|
|
266
|
+
/**
|
|
267
|
+
* Whether to force render this item regardless of filter results.
|
|
268
|
+
* @default false
|
|
269
|
+
*/
|
|
270
|
+
forceMount?: boolean;
|
|
271
|
+
/**
|
|
272
|
+
* Whether clicking this item should close the menu.
|
|
273
|
+
* @default true
|
|
274
|
+
*/
|
|
275
|
+
closeOnClick?: boolean;
|
|
276
|
+
/**
|
|
277
|
+
* Keyboard shortcut to trigger this item.
|
|
278
|
+
* When the menu is focused and the user presses this key, the item will be selected.
|
|
279
|
+
* Should be a single character (e.g., "1", "a", etc.).
|
|
280
|
+
*/
|
|
281
|
+
shortcut?: string;
|
|
282
|
+
/**
|
|
283
|
+
* Forces this row's relative order during score-based sorting.
|
|
284
|
+
* Lower values appear earlier.
|
|
285
|
+
* @default 0
|
|
286
|
+
*/
|
|
287
|
+
forceOrder?: number;
|
|
288
|
+
/**
|
|
289
|
+
* Overrides this row's computed fuzzy-match score.
|
|
290
|
+
*/
|
|
291
|
+
forceScore?: number;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* A selectable item in the popup menu.
|
|
295
|
+
* Renders a `<div>` element with role="option".
|
|
296
|
+
*/
|
|
297
|
+
declare const PopupMenuItem: React.ForwardRefExoticComponent<Omit<PopupMenuItem.Props, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
298
|
+
declare namespace PopupMenuItem {
|
|
299
|
+
type State = PopupMenuItemState;
|
|
300
|
+
interface Props extends PopupMenuItemProps {
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
interface PopupMenuRadioGroupState extends Record<string, unknown> {
|
|
305
|
+
/**
|
|
306
|
+
* Whether the radio group is disabled.
|
|
307
|
+
*/
|
|
308
|
+
disabled: boolean;
|
|
309
|
+
/**
|
|
310
|
+
* Present when this is the first visible group in the list.
|
|
311
|
+
*/
|
|
312
|
+
firstGroup: boolean;
|
|
313
|
+
/**
|
|
314
|
+
* Present when this is the last visible group in the list.
|
|
315
|
+
*/
|
|
316
|
+
lastGroup: boolean;
|
|
317
|
+
first: boolean;
|
|
318
|
+
last: boolean;
|
|
319
|
+
}
|
|
320
|
+
interface PopupMenuRadioGroupProps extends ComponentProps<'div', PopupMenuRadioGroup.State> {
|
|
321
|
+
/**
|
|
322
|
+
* The controlled selected value.
|
|
323
|
+
*/
|
|
324
|
+
value?: string;
|
|
325
|
+
/**
|
|
326
|
+
* The default value for uncontrolled mode.
|
|
327
|
+
*/
|
|
328
|
+
defaultValue?: string;
|
|
329
|
+
/**
|
|
330
|
+
* Callback fired when the selected value changes.
|
|
331
|
+
* The second parameter contains event details including the reason for the change.
|
|
332
|
+
*/
|
|
333
|
+
onValueChange?: (value: string, eventDetails: RadioValueChangeEventDetails) => void;
|
|
334
|
+
/**
|
|
335
|
+
* Whether all items in this group are disabled.
|
|
336
|
+
* @default false
|
|
337
|
+
*/
|
|
338
|
+
disabled?: boolean;
|
|
339
|
+
/**
|
|
340
|
+
* Whether to force render this group regardless of filter results.
|
|
341
|
+
* @default false
|
|
342
|
+
*/
|
|
343
|
+
forceMount?: boolean;
|
|
344
|
+
children: React.ReactNode;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Groups radio items together and manages the selected value.
|
|
348
|
+
* Only one item can be selected at a time within a radio group.
|
|
349
|
+
* Renders a `<div>` element with role="group".
|
|
350
|
+
*/
|
|
351
|
+
declare const PopupMenuRadioGroup: React.ForwardRefExoticComponent<Omit<PopupMenuRadioGroupProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
352
|
+
declare namespace PopupMenuRadioGroup {
|
|
353
|
+
type State = PopupMenuRadioGroupState;
|
|
354
|
+
interface Props extends PopupMenuRadioGroupProps {
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
interface PopupMenuRadioItemState extends Record<string, unknown> {
|
|
359
|
+
/**
|
|
360
|
+
* Whether the item is highlighted (via keyboard or pointer).
|
|
361
|
+
*/
|
|
362
|
+
highlighted: boolean;
|
|
363
|
+
/**
|
|
364
|
+
* Whether the item is disabled.
|
|
365
|
+
*/
|
|
366
|
+
disabled: boolean;
|
|
367
|
+
/**
|
|
368
|
+
* Whether the item is currently selected/checked.
|
|
369
|
+
*/
|
|
370
|
+
checked: boolean;
|
|
371
|
+
first: boolean;
|
|
372
|
+
last: boolean;
|
|
373
|
+
firstInGroup: boolean;
|
|
374
|
+
lastInGroup: boolean;
|
|
375
|
+
}
|
|
376
|
+
interface PopupMenuRadioItemProps extends ComponentProps<'div', PopupMenuRadioItem.State> {
|
|
377
|
+
/**
|
|
378
|
+
* The value to set when this item is selected.
|
|
379
|
+
* This is required and must be unique within the RadioGroup.
|
|
380
|
+
*/
|
|
381
|
+
value: string;
|
|
382
|
+
/**
|
|
383
|
+
* Additional keywords to match against when filtering.
|
|
384
|
+
* Useful for aliases or synonyms.
|
|
385
|
+
*/
|
|
386
|
+
keywords?: string[];
|
|
387
|
+
/**
|
|
388
|
+
* Whether this item is disabled.
|
|
389
|
+
* Disabled items are not selectable and are skipped during keyboard navigation.
|
|
390
|
+
* @default false
|
|
391
|
+
*/
|
|
392
|
+
disabled?: boolean;
|
|
393
|
+
/**
|
|
394
|
+
* Callback when this item is selected.
|
|
395
|
+
*/
|
|
396
|
+
onSelect?: () => void;
|
|
397
|
+
/**
|
|
398
|
+
* Whether to force render this item regardless of filter results.
|
|
399
|
+
* @default false
|
|
400
|
+
*/
|
|
401
|
+
forceMount?: boolean;
|
|
402
|
+
/**
|
|
403
|
+
* Whether clicking this item should close the menu.
|
|
404
|
+
* @default false
|
|
405
|
+
*/
|
|
406
|
+
closeOnClick?: boolean;
|
|
407
|
+
/**
|
|
408
|
+
* Keyboard shortcut to trigger this item.
|
|
409
|
+
* When the menu is focused and the user presses this key, the item will be selected.
|
|
410
|
+
* Should be a single character (e.g., "1", "a", etc.).
|
|
411
|
+
*/
|
|
412
|
+
shortcut?: string;
|
|
413
|
+
/**
|
|
414
|
+
* Forces this row's relative order during score-based sorting.
|
|
415
|
+
* Lower values appear earlier.
|
|
416
|
+
* @default 0
|
|
417
|
+
*/
|
|
418
|
+
forceOrder?: number;
|
|
419
|
+
/**
|
|
420
|
+
* Overrides this row's computed fuzzy-match score.
|
|
421
|
+
*/
|
|
422
|
+
forceScore?: number;
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* A selectable radio item within a RadioGroup.
|
|
426
|
+
* Only one RadioItem can be selected at a time within a RadioGroup.
|
|
427
|
+
* Renders a `<div>` element with role="menuitemradio".
|
|
428
|
+
*/
|
|
429
|
+
declare const PopupMenuRadioItem: React.ForwardRefExoticComponent<Omit<PopupMenuRadioItemProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
430
|
+
declare namespace PopupMenuRadioItem {
|
|
431
|
+
type State = PopupMenuRadioItemState;
|
|
432
|
+
interface Props extends PopupMenuRadioItemProps {
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
interface PopupMenuSubmenuTriggerState extends Record<string, unknown> {
|
|
437
|
+
/**
|
|
438
|
+
* Whether this is a submenu trigger (always true).
|
|
439
|
+
*/
|
|
440
|
+
submenuTrigger: boolean;
|
|
441
|
+
/**
|
|
442
|
+
* Whether the submenu popup is open.
|
|
443
|
+
*/
|
|
444
|
+
popupOpen: boolean;
|
|
445
|
+
/**
|
|
446
|
+
* Whether the submenu owns keyboard focus.
|
|
447
|
+
*/
|
|
448
|
+
popupFocused: boolean;
|
|
449
|
+
/**
|
|
450
|
+
* Whether the item is highlighted.
|
|
451
|
+
*/
|
|
452
|
+
highlighted: boolean;
|
|
453
|
+
/**
|
|
454
|
+
* Whether the item is disabled.
|
|
455
|
+
*/
|
|
456
|
+
disabled: boolean;
|
|
457
|
+
first: boolean;
|
|
458
|
+
last: boolean;
|
|
459
|
+
firstInGroup: boolean;
|
|
460
|
+
lastInGroup: boolean;
|
|
461
|
+
}
|
|
462
|
+
interface PopupMenuSubmenuTriggerProps extends ComponentProps<'div', PopupMenuSubmenuTrigger.State> {
|
|
463
|
+
/**
|
|
464
|
+
* Explicit unique identifier for this item in the store.
|
|
465
|
+
* When provided (e.g., from data-first API's computed composite ID),
|
|
466
|
+
* this takes priority over `value` for store registration.
|
|
467
|
+
*/
|
|
468
|
+
id?: string;
|
|
469
|
+
/**
|
|
470
|
+
* Unique value for this item used for filtering.
|
|
471
|
+
* If not provided, will be inferred from textContent.
|
|
472
|
+
*/
|
|
473
|
+
value?: string;
|
|
474
|
+
/**
|
|
475
|
+
* Additional keywords to match against when filtering.
|
|
476
|
+
* Useful for aliases or synonyms.
|
|
477
|
+
*/
|
|
478
|
+
keywords?: string[];
|
|
479
|
+
/**
|
|
480
|
+
* Whether this item is disabled.
|
|
481
|
+
* Disabled items are not selectable and are skipped during keyboard navigation.
|
|
482
|
+
*/
|
|
483
|
+
disabled?: boolean;
|
|
484
|
+
/**
|
|
485
|
+
* Whether to force render this item regardless of filter results.
|
|
486
|
+
* @default false
|
|
487
|
+
*/
|
|
488
|
+
forceMount?: boolean;
|
|
489
|
+
/**
|
|
490
|
+
* Whether the submenu opens when this trigger is highlighted.
|
|
491
|
+
* @default true
|
|
492
|
+
*/
|
|
493
|
+
openOnHighlight?: boolean;
|
|
494
|
+
/**
|
|
495
|
+
* Delay before opening the submenu (in milliseconds).
|
|
496
|
+
* Can be a number (applies to both pointer and keyboard) or an object
|
|
497
|
+
* with separate `pointer` and `keyboard` values.
|
|
498
|
+
* @default { pointer: 0, keyboard: 150 }
|
|
499
|
+
*/
|
|
500
|
+
delay?: number | {
|
|
501
|
+
pointer?: number;
|
|
502
|
+
keyboard?: number;
|
|
503
|
+
};
|
|
504
|
+
/**
|
|
505
|
+
* Delay before closing the submenu when pointer leaves (in milliseconds).
|
|
506
|
+
* @default 0
|
|
507
|
+
*/
|
|
508
|
+
closeDelay?: number;
|
|
509
|
+
/**
|
|
510
|
+
* Whether the submenu closes when the pointer leaves the trigger without aiming at the submenu popup.
|
|
511
|
+
* When `false`, the submenu stays open until closed by another path (sibling highlight, keyboard, outside click, etc.).
|
|
512
|
+
* @default true
|
|
513
|
+
*/
|
|
514
|
+
closeOnPointerLeave?: boolean;
|
|
515
|
+
/**
|
|
516
|
+
* Forces this row's relative order during score-based sorting.
|
|
517
|
+
* Lower values appear earlier.
|
|
518
|
+
* @default 0
|
|
519
|
+
*/
|
|
520
|
+
forceOrder?: number;
|
|
521
|
+
/**
|
|
522
|
+
* Overrides this row's computed fuzzy-match score.
|
|
523
|
+
*/
|
|
524
|
+
forceScore?: number;
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* A menu item that opens a submenu when hovered.
|
|
528
|
+
* Must be used within PopupMenu.Submenu.
|
|
529
|
+
* Renders a `<div>` element with role="menuitem" wrapped in Popover.Trigger.
|
|
530
|
+
*/
|
|
531
|
+
declare const PopupMenuSubmenuTrigger: React.ForwardRefExoticComponent<Omit<PopupMenuSubmenuTrigger.Props, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
532
|
+
declare namespace PopupMenuSubmenuTrigger {
|
|
533
|
+
type State = PopupMenuSubmenuTriggerState;
|
|
534
|
+
interface Props extends PopupMenuSubmenuTriggerProps {
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
interface PopupMenuSubpageTriggerState extends Record<string, unknown> {
|
|
539
|
+
/** Whether this is a subpage trigger (always true). */
|
|
540
|
+
subpageTrigger: boolean;
|
|
541
|
+
/** Whether the target page is active. */
|
|
542
|
+
popupOpen: boolean;
|
|
543
|
+
/** Whether the target page owns keyboard focus. */
|
|
544
|
+
popupFocused: boolean;
|
|
545
|
+
/** Whether the item is highlighted. */
|
|
546
|
+
highlighted: boolean;
|
|
547
|
+
/** Whether the item is disabled. */
|
|
548
|
+
disabled: boolean;
|
|
549
|
+
first: boolean;
|
|
550
|
+
last: boolean;
|
|
551
|
+
firstInGroup: boolean;
|
|
552
|
+
lastInGroup: boolean;
|
|
553
|
+
}
|
|
554
|
+
interface PopupMenuSubpageTriggerProps extends ComponentProps<'div', PopupMenuSubpageTrigger.State> {
|
|
555
|
+
/** Explicit unique identifier for this item in the store. */
|
|
556
|
+
id?: string;
|
|
557
|
+
/** Unique value for this item used for filtering. */
|
|
558
|
+
value?: string;
|
|
559
|
+
/** Additional keywords to match against when filtering. */
|
|
560
|
+
keywords?: string[];
|
|
561
|
+
/** Whether this item is disabled. */
|
|
562
|
+
disabled?: boolean;
|
|
563
|
+
/** Whether to force render this item regardless of filter results. */
|
|
564
|
+
forceMount?: boolean;
|
|
565
|
+
/**
|
|
566
|
+
* Forces this row's relative order during score-based sorting.
|
|
567
|
+
* Lower values appear earlier.
|
|
568
|
+
* @default 0
|
|
569
|
+
*/
|
|
570
|
+
forceOrder?: number;
|
|
571
|
+
/**
|
|
572
|
+
* Overrides this row's computed fuzzy-match score.
|
|
573
|
+
*/
|
|
574
|
+
forceScore?: number;
|
|
575
|
+
/** Target page ID to open when this trigger is selected. */
|
|
576
|
+
targetPageId: string;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* A menu item that pushes a new page in the same popup.
|
|
580
|
+
* Renders a `<div>` element with role="menuitem".
|
|
581
|
+
*/
|
|
582
|
+
declare const PopupMenuSubpageTrigger: React.ForwardRefExoticComponent<Omit<PopupMenuSubpageTrigger.Props, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
583
|
+
declare namespace PopupMenuSubpageTrigger {
|
|
584
|
+
type State = PopupMenuSubpageTriggerState;
|
|
585
|
+
interface Props extends PopupMenuSubpageTriggerProps {
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Library-agnostic result from an async loader.
|
|
591
|
+
* Compatible with TanStack Query, SWR, and custom loaders.
|
|
592
|
+
*/
|
|
593
|
+
type AsyncLoaderSource = 'tanstack-query' | 'swr' | 'vanilla' | 'custom';
|
|
594
|
+
/**
|
|
595
|
+
* Canonical async loader status.
|
|
596
|
+
* - 'idle': no request has been executed yet
|
|
597
|
+
* - 'pending': request in progress and no successful data yet
|
|
598
|
+
* - 'success': last resolved state has data
|
|
599
|
+
* - 'error': last resolved state errored
|
|
600
|
+
*/
|
|
601
|
+
type AsyncLoaderStatus = 'idle' | 'pending' | 'success' | 'error';
|
|
602
|
+
/**
|
|
603
|
+
* Canonical fetch status.
|
|
604
|
+
*/
|
|
605
|
+
type AsyncLoaderFetchStatus = 'idle' | 'fetching' | 'paused';
|
|
606
|
+
/**
|
|
607
|
+
* Loading phase for distinguishing first-load from background revalidation.
|
|
608
|
+
*/
|
|
609
|
+
type AsyncLoaderLoadingPhase = 'none' | 'initial' | 'background';
|
|
610
|
+
interface AsyncLoaderResult<TData, TRaw = unknown> {
|
|
611
|
+
/** The loaded data, undefined while loading or on error */
|
|
612
|
+
data: TData | undefined;
|
|
613
|
+
/** Raw result object returned by the underlying data library */
|
|
614
|
+
raw?: TRaw;
|
|
615
|
+
/** Source data library backing this result */
|
|
616
|
+
source?: AsyncLoaderSource;
|
|
617
|
+
/** Error if the load failed, null otherwise */
|
|
618
|
+
error: Error | null;
|
|
619
|
+
/** Canonical status state */
|
|
620
|
+
status: AsyncLoaderStatus;
|
|
621
|
+
/** Canonical fetch state */
|
|
622
|
+
fetchStatus: AsyncLoaderFetchStatus;
|
|
623
|
+
/** Distinguishes initial load vs background fetch */
|
|
624
|
+
loadingPhase: AsyncLoaderLoadingPhase;
|
|
625
|
+
/** True during the initial loading phase (TanStack-aligned semantics) */
|
|
626
|
+
isLoading: boolean;
|
|
627
|
+
/** Whether any fetch is currently in-flight */
|
|
628
|
+
isFetching: boolean;
|
|
629
|
+
/** Alias of `isLoading` for explicit phase naming */
|
|
630
|
+
isInitialLoading: boolean;
|
|
631
|
+
/** True when background re-fetch is in-flight */
|
|
632
|
+
isRefetching: boolean;
|
|
633
|
+
/** Whether query state is pending */
|
|
634
|
+
isPending: boolean;
|
|
635
|
+
/** Whether query state is successful */
|
|
636
|
+
isSuccess: boolean;
|
|
637
|
+
/** Whether the loader encountered an error */
|
|
638
|
+
isError: boolean;
|
|
639
|
+
/** Whether fetching is paused */
|
|
640
|
+
isPaused: boolean;
|
|
641
|
+
/** Whether data is currently available */
|
|
642
|
+
hasData: boolean;
|
|
643
|
+
/** Whether any fetch has completed at least once */
|
|
644
|
+
hasFetched: boolean;
|
|
645
|
+
/** Optional function to refetch the data */
|
|
646
|
+
refetch?: () => unknown;
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Props passed to loader components.
|
|
650
|
+
* The component should call hooks internally and pass the result to children.
|
|
651
|
+
*/
|
|
652
|
+
interface LoaderComponentProps {
|
|
653
|
+
/** Search query (for query loaders) */
|
|
654
|
+
query: string;
|
|
655
|
+
/** Whether the loader should execute its fetch/query hook */
|
|
656
|
+
enabled?: boolean;
|
|
657
|
+
/** Render function receiving loader state */
|
|
658
|
+
children: (state: AsyncLoaderResult<NodeDef[]>) => React.ReactNode;
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Controls query-loader behavior before users type an active query.
|
|
662
|
+
*/
|
|
663
|
+
interface InitialQueryBehavior {
|
|
664
|
+
/**
|
|
665
|
+
* Query value used before user input reaches minQueryLength.
|
|
666
|
+
* Defaults to '' (top/default results).
|
|
667
|
+
* @default ''
|
|
668
|
+
*/
|
|
669
|
+
value?: string;
|
|
670
|
+
/**
|
|
671
|
+
* When the initial query should load.
|
|
672
|
+
* - 'needed': when submenu is explicitly opened or needed for deep-search execution
|
|
673
|
+
* - 'parent-open': eagerly when direct parent opens
|
|
674
|
+
* @default 'needed'
|
|
675
|
+
*/
|
|
676
|
+
loadWhen?: 'needed' | 'parent-open';
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Static loader configuration.
|
|
680
|
+
* Loads data once, then filters client-side.
|
|
681
|
+
*/
|
|
682
|
+
interface StaticLoaderConfig {
|
|
683
|
+
type: 'static';
|
|
684
|
+
/**
|
|
685
|
+
* Component that calls hooks and provides loader state.
|
|
686
|
+
* This component pattern allows hooks to be called legally within React's rules.
|
|
687
|
+
*/
|
|
688
|
+
Loader: React.ComponentType<LoaderComponentProps>;
|
|
689
|
+
/**
|
|
690
|
+
* When to trigger the loader:
|
|
691
|
+
* - 'eager': Load when menu opens (good for deep search)
|
|
692
|
+
* - 'lazy': Load when submenu opens (default)
|
|
693
|
+
* @default 'lazy'
|
|
694
|
+
*/
|
|
695
|
+
loadStrategy?: 'eager' | 'lazy';
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* Query loader configuration.
|
|
699
|
+
* Refetches based on search query - server does the filtering.
|
|
700
|
+
*/
|
|
701
|
+
interface QueryLoaderConfig {
|
|
702
|
+
type: 'query';
|
|
703
|
+
/**
|
|
704
|
+
* Component that calls hooks and provides loader state.
|
|
705
|
+
* Receives the current search query as a prop.
|
|
706
|
+
*/
|
|
707
|
+
Loader: React.ComponentType<LoaderComponentProps>;
|
|
708
|
+
/**
|
|
709
|
+
* Minimum query length before fetching.
|
|
710
|
+
* @default 1
|
|
711
|
+
*/
|
|
712
|
+
minQueryLength?: number;
|
|
713
|
+
/**
|
|
714
|
+
* Defines behavior before user query reaches minQueryLength.
|
|
715
|
+
* - object: executes query loader with the configured initial value (default behavior)
|
|
716
|
+
* - false: disables initial fetch until query reaches minQueryLength
|
|
717
|
+
* @default { value: '', loadWhen: 'needed' }
|
|
718
|
+
*/
|
|
719
|
+
initialQueryBehavior?: InitialQueryBehavior | false;
|
|
720
|
+
/**
|
|
721
|
+
* @deprecated Use `initialQueryBehavior` instead.
|
|
722
|
+
*/
|
|
723
|
+
initialQuery?: string;
|
|
724
|
+
/**
|
|
725
|
+
* When to trigger the loader:
|
|
726
|
+
* - 'eager': Load when root menu opens (good for deep search)
|
|
727
|
+
* - 'lazy': Load when submenu opens (default)
|
|
728
|
+
* @default 'lazy'
|
|
729
|
+
*/
|
|
730
|
+
loadStrategy?: 'eager' | 'lazy';
|
|
731
|
+
/**
|
|
732
|
+
* What to show when query is below minQueryLength.
|
|
733
|
+
* - 'empty': Show nothing
|
|
734
|
+
* - 'placeholder': Show placeholderNodes
|
|
735
|
+
* @default 'empty'
|
|
736
|
+
*/
|
|
737
|
+
belowMinBehavior?: 'empty' | 'placeholder';
|
|
738
|
+
/**
|
|
739
|
+
* Placeholder nodes shown when query is below minQueryLength.
|
|
740
|
+
*/
|
|
741
|
+
placeholderNodes?: NodeDef[];
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Controls how submenu content participates in ancestor deep search results.
|
|
745
|
+
* - `true`: include submenu trigger and descendants
|
|
746
|
+
* - `'trigger-only'`: include submenu trigger only
|
|
747
|
+
* - `false`: exclude submenu trigger and descendants
|
|
748
|
+
*/
|
|
749
|
+
type IncludeInDeepSearch = true | 'trigger-only' | false;
|
|
750
|
+
/**
|
|
751
|
+
* Union of all async loader configurations.
|
|
752
|
+
*/
|
|
753
|
+
type AsyncLoaderConfig = StaticLoaderConfig | QueryLoaderConfig;
|
|
754
|
+
/**
|
|
755
|
+
* Static async nodes configuration for submenus.
|
|
756
|
+
*/
|
|
757
|
+
type StaticAsyncNodesConfig = StaticLoaderConfig;
|
|
758
|
+
/**
|
|
759
|
+
* Query async nodes configuration for submenus.
|
|
760
|
+
*/
|
|
761
|
+
type QueryAsyncNodesConfig = QueryLoaderConfig;
|
|
762
|
+
/**
|
|
763
|
+
* Async nodes configuration for submenus.
|
|
764
|
+
* Union of static and query loader configs.
|
|
765
|
+
*/
|
|
766
|
+
type AsyncNodesConfig = StaticAsyncNodesConfig | QueryAsyncNodesConfig;
|
|
767
|
+
/**
|
|
768
|
+
* Async state exposed to submenu render functions.
|
|
769
|
+
*/
|
|
770
|
+
interface AsyncRenderState {
|
|
771
|
+
/** Canonical status state */
|
|
772
|
+
status: AsyncLoaderStatus;
|
|
773
|
+
/** Canonical fetch state */
|
|
774
|
+
fetchStatus: AsyncLoaderFetchStatus;
|
|
775
|
+
/** Distinguishes initial load vs background fetch */
|
|
776
|
+
loadingPhase: AsyncLoaderLoadingPhase;
|
|
777
|
+
/** True during the initial loading phase */
|
|
778
|
+
isLoading: boolean;
|
|
779
|
+
/** Whether any fetch is currently in-flight */
|
|
780
|
+
isFetching: boolean;
|
|
781
|
+
/** Alias of `isLoading` for explicit phase naming */
|
|
782
|
+
isInitialLoading: boolean;
|
|
783
|
+
/** True when background re-fetch is in-flight */
|
|
784
|
+
isRefetching: boolean;
|
|
785
|
+
/** Whether the loader encountered an error */
|
|
786
|
+
isError: boolean;
|
|
787
|
+
/** The error if any */
|
|
788
|
+
error: Error | null;
|
|
789
|
+
/** For query loaders: whether query is below minQueryLength */
|
|
790
|
+
isBelowMinLength?: boolean;
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Aggregate async state exposed to DataList children.
|
|
794
|
+
*/
|
|
795
|
+
interface AsyncState {
|
|
796
|
+
/** Any loader is currently in initial loading phase */
|
|
797
|
+
isLoading: boolean;
|
|
798
|
+
/** Any loader is currently fetching */
|
|
799
|
+
isFetching: boolean;
|
|
800
|
+
/** Any loader is in first-load phase */
|
|
801
|
+
isInitialLoading: boolean;
|
|
802
|
+
/** Any loader is in background refetch phase */
|
|
803
|
+
isRefetching: boolean;
|
|
804
|
+
/** All registered loaders are in background refetch phase */
|
|
805
|
+
isAllRefetching: boolean;
|
|
806
|
+
/** Static loaders specifically are loading */
|
|
807
|
+
isStaticLoading: boolean;
|
|
808
|
+
/** Static loaders in first-load phase */
|
|
809
|
+
isStaticInitialLoading: boolean;
|
|
810
|
+
/** Static loaders in background refetch phase */
|
|
811
|
+
isStaticRefetching: boolean;
|
|
812
|
+
/** Query loaders specifically are loading */
|
|
813
|
+
isQueryLoading: boolean;
|
|
814
|
+
/** Query loaders in first-load phase */
|
|
815
|
+
isQueryInitialLoading: boolean;
|
|
816
|
+
/** Query loaders in background refetch phase */
|
|
817
|
+
isQueryRefetching: boolean;
|
|
818
|
+
/** Menus that failed (skipped from results) */
|
|
819
|
+
skippedMenus: Array<{
|
|
820
|
+
kind: 'root';
|
|
821
|
+
reason: 'error';
|
|
822
|
+
} | {
|
|
823
|
+
kind: 'branch';
|
|
824
|
+
id: string;
|
|
825
|
+
reason: 'error';
|
|
826
|
+
}>;
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Branch node info passed in breadcrumbs context.
|
|
830
|
+
* Contains the full submenu/subpage definition for maximum flexibility.
|
|
831
|
+
*/
|
|
832
|
+
interface BreadcrumbNode {
|
|
833
|
+
/** The branch node definition */
|
|
834
|
+
node: SubmenuDef | SubpageDef | TreeItemDef;
|
|
835
|
+
/** The branch Menu Node. `node`, `value`, and `id` mirror its def for compatibility. */
|
|
836
|
+
menuNode: PopupMenuNode<SubmenuDef | SubpageDef | TreeItemDef>;
|
|
837
|
+
/** The branch node's value */
|
|
838
|
+
value: string;
|
|
839
|
+
/** The branch node's explicit id (if provided) */
|
|
840
|
+
id?: string;
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Context passed to item, submenu, and subpage render functions.
|
|
844
|
+
* Provides information about the current rendering context (search, breadcrumbs, state).
|
|
845
|
+
*/
|
|
846
|
+
interface RowRenderContext {
|
|
847
|
+
/**
|
|
848
|
+
* Search context - the query in the menu where this row is being rendered.
|
|
849
|
+
* `null` if no active search (browsing mode).
|
|
850
|
+
*/
|
|
851
|
+
search: {
|
|
852
|
+
/** Current search query */
|
|
853
|
+
query: string;
|
|
854
|
+
/** Match score for this row (higher = better match). */
|
|
855
|
+
score: number;
|
|
856
|
+
} | null;
|
|
857
|
+
/**
|
|
858
|
+
* Full path of branch nodes from root to this row's parent.
|
|
859
|
+
* Contains the full submenu/subpage node definitions for maximum flexibility.
|
|
860
|
+
* Empty array [] for items directly in root menu.
|
|
861
|
+
*/
|
|
862
|
+
breadcrumbs: BreadcrumbNode[];
|
|
863
|
+
/**
|
|
864
|
+
* True if this row is being rendered outside its "home" menu
|
|
865
|
+
* (surfaced via deep search from an ancestor menu).
|
|
866
|
+
*/
|
|
867
|
+
isDeepSearchResult: boolean;
|
|
868
|
+
/** Whether this row is currently highlighted/focused */
|
|
869
|
+
highlighted: boolean;
|
|
870
|
+
/** Whether this row is disabled */
|
|
871
|
+
disabled: boolean;
|
|
872
|
+
/**
|
|
873
|
+
* The group this item belongs to, if any.
|
|
874
|
+
* `null` if the item is not inside a group.
|
|
875
|
+
*/
|
|
876
|
+
group: {
|
|
877
|
+
id: string;
|
|
878
|
+
label?: string;
|
|
879
|
+
} | null;
|
|
880
|
+
/** Tree rendering context, or null for non-tree and search rows. */
|
|
881
|
+
tree: {
|
|
882
|
+
depth: number;
|
|
883
|
+
hasChildren: boolean;
|
|
884
|
+
isLastChild: boolean;
|
|
885
|
+
ancestorsLast: boolean[];
|
|
886
|
+
header: boolean;
|
|
887
|
+
} | null;
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* Props to spread onto the Item component.
|
|
891
|
+
* Derived from PopupMenuItemProps.
|
|
892
|
+
*/
|
|
893
|
+
type ItemRenderProps = {
|
|
894
|
+
/**
|
|
895
|
+
* Canonical Resolved ID for the item, generated by the root policy: the
|
|
896
|
+
* encoded surface Definition Path by default, or the Definition Key in
|
|
897
|
+
* menu scope.
|
|
898
|
+
* Must be passed to the rendered component for navigation to work.
|
|
899
|
+
*/
|
|
900
|
+
id: string;
|
|
901
|
+
/**
|
|
902
|
+
* The original value from the node definition.
|
|
903
|
+
* Use this for display, search matching, or any logic that needs the raw value.
|
|
904
|
+
*/
|
|
905
|
+
value: string;
|
|
906
|
+
} & Required<Pick<PopupMenuItemProps, 'disabled'>> & Pick<PopupMenuItemProps, 'closeOnClick' | 'onSelect' | 'shortcut' | 'forceOrder' | 'forceScore'>;
|
|
907
|
+
/**
|
|
908
|
+
* Parameters passed to item render functions.
|
|
909
|
+
*/
|
|
910
|
+
interface ItemRenderParams {
|
|
911
|
+
/** The resolved menu node for this row — canonical identity (`node.id`), definition path, and tree links */
|
|
912
|
+
node: PopupMenuNode;
|
|
913
|
+
/** Props to spread onto the Item component */
|
|
914
|
+
props: ItemRenderProps;
|
|
915
|
+
/** Context for conditional rendering (includes props values for convenience) */
|
|
916
|
+
context: RowRenderContext & {
|
|
917
|
+
/** The node's value (ItemDef.value) */
|
|
918
|
+
value: string;
|
|
919
|
+
disabled: boolean;
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
/** Props to spread onto a TreeItem component. */
|
|
923
|
+
type TreeItemRenderProps = Omit<ItemRenderProps, 'shortcut'> & {
|
|
924
|
+
/** Whether this row can be selected. */
|
|
925
|
+
selectable: boolean;
|
|
926
|
+
};
|
|
927
|
+
/** Parameters passed to tree item render functions. */
|
|
928
|
+
interface TreeItemRenderParams {
|
|
929
|
+
/** The resolved menu node for this row — canonical identity (`node.id`), definition path, and tree links */
|
|
930
|
+
node: PopupMenuNode;
|
|
931
|
+
props: TreeItemRenderProps;
|
|
932
|
+
context: RowRenderContext & {
|
|
933
|
+
value: string;
|
|
934
|
+
disabled: boolean;
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
/**
|
|
938
|
+
* Props to spread onto the RadioItem component.
|
|
939
|
+
* Derived from PopupMenuRadioItemProps.
|
|
940
|
+
*/
|
|
941
|
+
type RadioItemRenderProps = {
|
|
942
|
+
/**
|
|
943
|
+
* Qualified unique ID for the radio item.
|
|
944
|
+
* Must be passed to the rendered component for navigation to work.
|
|
945
|
+
*/
|
|
946
|
+
id: string;
|
|
947
|
+
} & Required<Pick<PopupMenuRadioItemProps, 'value' | 'disabled'>> & Pick<PopupMenuRadioItemProps, 'closeOnClick' | 'onSelect' | 'shortcut' | 'forceOrder' | 'forceScore'>;
|
|
948
|
+
/**
|
|
949
|
+
* Parameters passed to radio item render functions.
|
|
950
|
+
*/
|
|
951
|
+
interface RadioItemRenderParams {
|
|
952
|
+
/** The resolved menu node for this row — canonical identity (`node.id`), definition path, and tree links */
|
|
953
|
+
node: PopupMenuNode;
|
|
954
|
+
/** Props to spread onto the RadioItem component */
|
|
955
|
+
props: RadioItemRenderProps;
|
|
956
|
+
/** Context for conditional rendering (includes props values for convenience) */
|
|
957
|
+
context: RowRenderContext & {
|
|
958
|
+
/** The node's value (RadioItemDef.value) */
|
|
959
|
+
value: string;
|
|
960
|
+
disabled: boolean;
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
/**
|
|
964
|
+
* Props to spread onto the SubmenuTrigger component.
|
|
965
|
+
* Derived from PopupMenuSubmenuTriggerProps.
|
|
966
|
+
*/
|
|
967
|
+
type SubmenuRenderProps = {
|
|
968
|
+
/**
|
|
969
|
+
* Qualified unique ID for the submenu trigger.
|
|
970
|
+
* Must be passed to the rendered component for navigation to work.
|
|
971
|
+
*/
|
|
972
|
+
id: string;
|
|
973
|
+
/**
|
|
974
|
+
* The original value from the node definition.
|
|
975
|
+
*/
|
|
976
|
+
value: string;
|
|
977
|
+
} & Required<Pick<PopupMenuSubmenuTriggerProps, 'disabled'>> & Pick<PopupMenuSubmenuTriggerProps, 'forceOrder' | 'forceScore'>;
|
|
978
|
+
/**
|
|
979
|
+
* Parameters passed to submenu render functions.
|
|
980
|
+
* Includes context plus the submenu's child nodes and render function.
|
|
981
|
+
*/
|
|
982
|
+
interface SubmenuRenderParams {
|
|
983
|
+
/** The resolved menu node for this row — canonical identity (`node.id`), definition path, and tree links */
|
|
984
|
+
node: PopupMenuNode;
|
|
985
|
+
/** Props to spread onto the SubmenuTrigger */
|
|
986
|
+
props: SubmenuRenderProps;
|
|
987
|
+
/** Context for conditional rendering (includes props values for convenience) */
|
|
988
|
+
context: RowRenderContext & {
|
|
989
|
+
/** The node's value (SubmenuDef.value) */
|
|
990
|
+
value: string;
|
|
991
|
+
disabled: boolean;
|
|
992
|
+
/** Async loading state (if asyncNodes configured) */
|
|
993
|
+
async?: AsyncRenderState;
|
|
994
|
+
};
|
|
995
|
+
/** The branch's resolved static child Menu Nodes, in def order. Loader results are grafted as children of `node` but are not included here — use `asyncContent` to load them. Authored fields are on `child.def`. */
|
|
996
|
+
nodes: PopupMenuNode[];
|
|
997
|
+
/**
|
|
998
|
+
* Async content configuration for this submenu.
|
|
999
|
+
* Pass this to the submenu's DataSurface to enable async loading
|
|
1000
|
+
* with the submenu's own search query (independent of parent search).
|
|
1001
|
+
*/
|
|
1002
|
+
asyncContent?: AsyncNodesConfig;
|
|
1003
|
+
/** Render one child Menu Node from `nodes`. */
|
|
1004
|
+
renderNode: (node: PopupMenuNode) => React.ReactNode;
|
|
1005
|
+
}
|
|
1006
|
+
/**
|
|
1007
|
+
* Props to spread onto the SubpageTrigger component.
|
|
1008
|
+
* Derived from PopupMenuSubpageTriggerProps.
|
|
1009
|
+
*/
|
|
1010
|
+
type SubpageTriggerRenderProps = {
|
|
1011
|
+
/**
|
|
1012
|
+
* Qualified unique ID for the subpage trigger.
|
|
1013
|
+
* Must be passed to the rendered component for navigation to work.
|
|
1014
|
+
*/
|
|
1015
|
+
id: string;
|
|
1016
|
+
/**
|
|
1017
|
+
* The original value from the node definition.
|
|
1018
|
+
*/
|
|
1019
|
+
value: string;
|
|
1020
|
+
/**
|
|
1021
|
+
* Computed page ID for the associated Subpage content.
|
|
1022
|
+
* Must be passed to `targetPageId` on SubpageTrigger.
|
|
1023
|
+
*/
|
|
1024
|
+
targetPageId: string;
|
|
1025
|
+
} & Required<Pick<PopupMenuSubpageTriggerProps, 'disabled'>>;
|
|
1026
|
+
/**
|
|
1027
|
+
* Parameters passed to subpage trigger render functions.
|
|
1028
|
+
*/
|
|
1029
|
+
interface SubpageTriggerRenderParams {
|
|
1030
|
+
/** The resolved menu node for this row — canonical identity (`node.id`), definition path, and tree links */
|
|
1031
|
+
node: PopupMenuNode;
|
|
1032
|
+
/** Props to spread onto the SubpageTrigger */
|
|
1033
|
+
props: SubpageTriggerRenderProps;
|
|
1034
|
+
/** Context for conditional rendering (includes props values for convenience) */
|
|
1035
|
+
context: RowRenderContext & {
|
|
1036
|
+
/** The node's value (SubpageDef.value) */
|
|
1037
|
+
value: string;
|
|
1038
|
+
disabled: boolean;
|
|
1039
|
+
/** Async loading state (if asyncNodes configured) */
|
|
1040
|
+
async?: AsyncRenderState;
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
/**
|
|
1044
|
+
* Parameters passed to subpage content render functions.
|
|
1045
|
+
* The returned JSX should include a `<PopupMenu.Subpage pageId={pageId}>` wrapper.
|
|
1046
|
+
*/
|
|
1047
|
+
interface SubpageContentRenderParams {
|
|
1048
|
+
/** The resolved menu node for this row — canonical identity (`node.id`), definition path, and tree links */
|
|
1049
|
+
node: PopupMenuNode;
|
|
1050
|
+
/** The subpage's Resolved ID (`node.id`); pass it to `<Subpage pageId>`. */
|
|
1051
|
+
pageId: string;
|
|
1052
|
+
/** Context for conditional rendering */
|
|
1053
|
+
context: RowRenderContext & {
|
|
1054
|
+
/** The node's value (SubpageDef.value) */
|
|
1055
|
+
value: string;
|
|
1056
|
+
disabled: boolean;
|
|
1057
|
+
/** Async loading state (if asyncNodes configured) */
|
|
1058
|
+
async?: AsyncRenderState;
|
|
1059
|
+
};
|
|
1060
|
+
/** The branch's resolved static child Menu Nodes, in def order. Loader results are grafted as children of `node` but are not included here — use `asyncContent` to load them. Authored fields are on `child.def`. */
|
|
1061
|
+
nodes: PopupMenuNode[];
|
|
1062
|
+
/**
|
|
1063
|
+
* Async content configuration for this subpage.
|
|
1064
|
+
* Pass this to the subpage's DataSurface to enable async loading
|
|
1065
|
+
* with the subpage's own search query (independent of parent search).
|
|
1066
|
+
*/
|
|
1067
|
+
asyncContent?: AsyncNodesConfig;
|
|
1068
|
+
/** Render one child Menu Node from `nodes`. */
|
|
1069
|
+
renderNode: (node: PopupMenuNode) => React.ReactNode;
|
|
1070
|
+
}
|
|
1071
|
+
/**
|
|
1072
|
+
* Context passed to group render functions.
|
|
1073
|
+
* Contains information about the group's state during search.
|
|
1074
|
+
*/
|
|
1075
|
+
interface GroupRenderContext {
|
|
1076
|
+
/**
|
|
1077
|
+
* Search context with the best match score among items in this group.
|
|
1078
|
+
* `null` if no active search (browsing mode).
|
|
1079
|
+
*/
|
|
1080
|
+
search: {
|
|
1081
|
+
/** Current search query */
|
|
1082
|
+
query: string;
|
|
1083
|
+
/** Best match score among items in this group (higher = better match). */
|
|
1084
|
+
bestScore: number;
|
|
1085
|
+
} | null;
|
|
1086
|
+
/** Number of matching items in this group */
|
|
1087
|
+
matchCount: number;
|
|
1088
|
+
/**
|
|
1089
|
+
* Breadcrumb nodes if this group is from a surfaced submenu.
|
|
1090
|
+
* Empty array [] for groups in the root menu.
|
|
1091
|
+
*/
|
|
1092
|
+
breadcrumbs: BreadcrumbNode[];
|
|
1093
|
+
/** Whether this group is from deep search (surfaced from a submenu) */
|
|
1094
|
+
isDeepSearchResult: boolean;
|
|
1095
|
+
}
|
|
1096
|
+
/**
|
|
1097
|
+
* Parameters passed to group render functions.
|
|
1098
|
+
*/
|
|
1099
|
+
interface GroupRenderParams {
|
|
1100
|
+
/** The resolved menu node for this row — canonical identity (`node.id`), definition path, and tree links */
|
|
1101
|
+
node: PopupMenuNode;
|
|
1102
|
+
/** Props (empty for groups, but consistent structure) */
|
|
1103
|
+
props: Record<string, never>;
|
|
1104
|
+
/** Context for conditional rendering (includes label for convenience) */
|
|
1105
|
+
context: GroupRenderContext & {
|
|
1106
|
+
/** The group's label */
|
|
1107
|
+
label?: string;
|
|
1108
|
+
};
|
|
1109
|
+
/** Pre-rendered matching children */
|
|
1110
|
+
children: React.ReactNode;
|
|
1111
|
+
}
|
|
1112
|
+
/**
|
|
1113
|
+
* Parameters passed to group label render functions.
|
|
1114
|
+
*/
|
|
1115
|
+
interface GroupLabelRenderParams {
|
|
1116
|
+
/** The resolved menu node for this group — canonical identity (`node.id`), definition path, and tree links */
|
|
1117
|
+
node: PopupMenuNode;
|
|
1118
|
+
/** Props to spread onto the label element (stable id for aria wiring) */
|
|
1119
|
+
props: {
|
|
1120
|
+
id: string;
|
|
1121
|
+
};
|
|
1122
|
+
/** Context for conditional rendering (includes label for convenience) */
|
|
1123
|
+
context: GroupRenderContext & {
|
|
1124
|
+
/** The group's label */
|
|
1125
|
+
label?: string;
|
|
1126
|
+
};
|
|
1127
|
+
}
|
|
1128
|
+
/**
|
|
1129
|
+
* Props to spread onto the CheckboxItem component.
|
|
1130
|
+
* Derived from PopupMenuCheckboxItemProps.
|
|
1131
|
+
*/
|
|
1132
|
+
type CheckboxItemRenderProps = {
|
|
1133
|
+
/**
|
|
1134
|
+
* Qualified unique ID for the checkbox item.
|
|
1135
|
+
* Must be passed to the rendered component for navigation to work.
|
|
1136
|
+
*/
|
|
1137
|
+
id: string;
|
|
1138
|
+
/**
|
|
1139
|
+
* The original value from the node definition.
|
|
1140
|
+
*/
|
|
1141
|
+
value: string;
|
|
1142
|
+
} & Required<Pick<PopupMenuCheckboxItemProps, 'disabled'>> & Pick<PopupMenuCheckboxItemProps, 'checked' | 'onCheckedChange' | 'closeOnClick' | 'forceOrder' | 'forceScore'>;
|
|
1143
|
+
/**
|
|
1144
|
+
* Parameters passed to checkbox item render functions.
|
|
1145
|
+
*/
|
|
1146
|
+
interface CheckboxItemRenderParams {
|
|
1147
|
+
/** The resolved menu node for this row — canonical identity (`node.id`), definition path, and tree links */
|
|
1148
|
+
node: PopupMenuNode;
|
|
1149
|
+
/** Props to spread onto the CheckboxItem component */
|
|
1150
|
+
props: CheckboxItemRenderProps;
|
|
1151
|
+
/** Context for conditional rendering (includes props values for convenience) */
|
|
1152
|
+
context: RowRenderContext & {
|
|
1153
|
+
/** The node's value (CheckboxItemDef.value) */
|
|
1154
|
+
value: string;
|
|
1155
|
+
checked?: boolean;
|
|
1156
|
+
disabled: boolean;
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
1159
|
+
/**
|
|
1160
|
+
* Props to spread onto the RadioGroup component.
|
|
1161
|
+
* Derived from PopupMenuRadioGroupProps.
|
|
1162
|
+
*/
|
|
1163
|
+
type RadioGroupRenderProps = Required<Pick<PopupMenuRadioGroupProps, 'disabled'>> & Pick<PopupMenuRadioGroupProps, 'value' | 'onValueChange'>;
|
|
1164
|
+
/**
|
|
1165
|
+
* Parameters passed to radio group render functions.
|
|
1166
|
+
*/
|
|
1167
|
+
interface RadioGroupRenderParams {
|
|
1168
|
+
/** The resolved menu node for this row — canonical identity (`node.id`), definition path, and tree links */
|
|
1169
|
+
node: PopupMenuNode;
|
|
1170
|
+
/** Props to spread onto the RadioGroup component */
|
|
1171
|
+
props: RadioGroupRenderProps;
|
|
1172
|
+
/** Context for conditional rendering */
|
|
1173
|
+
context: GroupRenderContext & {
|
|
1174
|
+
/** The radio group's label */
|
|
1175
|
+
label?: string;
|
|
1176
|
+
/** Current selected value */
|
|
1177
|
+
value?: string;
|
|
1178
|
+
/** Whether the radio group is disabled */
|
|
1179
|
+
disabled: boolean;
|
|
1180
|
+
};
|
|
1181
|
+
/** Pre-rendered radio items */
|
|
1182
|
+
children: React.ReactNode;
|
|
1183
|
+
}
|
|
1184
|
+
/**
|
|
1185
|
+
* Parameters passed to radio group label render functions.
|
|
1186
|
+
*/
|
|
1187
|
+
interface RadioGroupLabelRenderParams {
|
|
1188
|
+
/** The resolved menu node for this group — canonical identity (`node.id`), definition path, and tree links */
|
|
1189
|
+
node: PopupMenuNode;
|
|
1190
|
+
/** Props to spread onto the label element (stable id for aria wiring) */
|
|
1191
|
+
props: {
|
|
1192
|
+
id: string;
|
|
1193
|
+
};
|
|
1194
|
+
/** Context for conditional rendering (includes label for convenience) */
|
|
1195
|
+
context: GroupRenderContext & {
|
|
1196
|
+
/** The radio group's label */
|
|
1197
|
+
label?: string;
|
|
1198
|
+
/** Current selected value */
|
|
1199
|
+
value?: string;
|
|
1200
|
+
/** Whether the radio group is disabled */
|
|
1201
|
+
disabled: boolean;
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
/**
|
|
1205
|
+
* Base properties shared by all node types.
|
|
1206
|
+
*/
|
|
1207
|
+
interface BaseNodeDef {
|
|
1208
|
+
/**
|
|
1209
|
+
* Unique identifier for this node.
|
|
1210
|
+
* If provided, it contributes the Definition Key and encoded surface path;
|
|
1211
|
+
* Resolved ID generation otherwise follows the root policy or its
|
|
1212
|
+
* `getResolvedId` seam.
|
|
1213
|
+
*/
|
|
1214
|
+
id?: string;
|
|
1215
|
+
/** Whether this node is hidden */
|
|
1216
|
+
hidden?: boolean;
|
|
1217
|
+
}
|
|
1218
|
+
/**
|
|
1219
|
+
* Item node definition.
|
|
1220
|
+
* Represents a selectable menu item.
|
|
1221
|
+
* Props derived from PopupMenuItemProps.
|
|
1222
|
+
*/
|
|
1223
|
+
interface ItemDef extends BaseNodeDef, Required<Pick<PopupMenuItemProps, 'value'>>, Pick<PopupMenuItemProps, 'keywords' | 'disabled' | 'onSelect' | 'closeOnClick' | 'shortcut' | 'forceOrder' | 'forceScore'> {
|
|
1224
|
+
kind: 'item';
|
|
1225
|
+
/**
|
|
1226
|
+
* Render function for this item row.
|
|
1227
|
+
* Returns the JSX for the item.
|
|
1228
|
+
*/
|
|
1229
|
+
render: (params: ItemRenderParams) => React.ReactNode;
|
|
1230
|
+
}
|
|
1231
|
+
/** Tree item node definition. */
|
|
1232
|
+
interface TreeItemDef extends BaseNodeDef, Required<Pick<PopupMenuItemProps, 'value'>>, Pick<PopupMenuItemProps, 'keywords' | 'disabled' | 'onSelect' | 'closeOnClick' | 'forceOrder' | 'forceScore'> {
|
|
1233
|
+
kind: 'tree-item';
|
|
1234
|
+
/** Whether this row itself can be selected. */
|
|
1235
|
+
selectable?: boolean;
|
|
1236
|
+
/** Inline children rendered in the same list. */
|
|
1237
|
+
nodes?: NodeDef[];
|
|
1238
|
+
/** Whether descendants surface in deep search results. */
|
|
1239
|
+
deepSearch?: boolean;
|
|
1240
|
+
/** Render function for this row. */
|
|
1241
|
+
render: (params: TreeItemRenderParams) => React.ReactNode;
|
|
1242
|
+
}
|
|
1243
|
+
/**
|
|
1244
|
+
* Radio item node definition.
|
|
1245
|
+
* Represents a selectable radio menu item for use within RadioGroupDef.
|
|
1246
|
+
* Props derived from PopupMenuRadioItemProps.
|
|
1247
|
+
*/
|
|
1248
|
+
interface RadioItemDef extends BaseNodeDef, Required<Pick<PopupMenuRadioItemProps, 'value'>>, Pick<PopupMenuRadioItemProps, 'keywords' | 'disabled' | 'onSelect' | 'closeOnClick' | 'shortcut' | 'forceOrder' | 'forceScore'> {
|
|
1249
|
+
kind: 'radio-item';
|
|
1250
|
+
/**
|
|
1251
|
+
* Render function for this radio item row.
|
|
1252
|
+
* Returns the JSX for the radio item.
|
|
1253
|
+
*/
|
|
1254
|
+
render: (params: RadioItemRenderParams) => React.ReactNode;
|
|
1255
|
+
}
|
|
1256
|
+
/**
|
|
1257
|
+
* Checkbox item node definition.
|
|
1258
|
+
* Represents a toggleable checkbox menu item.
|
|
1259
|
+
* Props derived from PopupMenuCheckboxItemProps.
|
|
1260
|
+
*/
|
|
1261
|
+
interface CheckboxItemDef extends BaseNodeDef, Pick<PopupMenuCheckboxItemProps, 'keywords' | 'disabled' | 'checked' | 'onCheckedChange' | 'closeOnClick' | 'forceOrder' | 'forceScore'> {
|
|
1262
|
+
kind: 'checkbox-item';
|
|
1263
|
+
/**
|
|
1264
|
+
* Primary identifier and search text for this checkbox item.
|
|
1265
|
+
* Used for search matching and as the default identifier.
|
|
1266
|
+
*/
|
|
1267
|
+
value: string;
|
|
1268
|
+
/**
|
|
1269
|
+
* Render function for this checkbox item row.
|
|
1270
|
+
* Returns the JSX for the checkbox item.
|
|
1271
|
+
*/
|
|
1272
|
+
render: (params: CheckboxItemRenderParams) => React.ReactNode;
|
|
1273
|
+
}
|
|
1274
|
+
/**
|
|
1275
|
+
* Submenu node definition.
|
|
1276
|
+
* Represents a submenu trigger that opens a nested menu.
|
|
1277
|
+
* Props derived from PopupMenuSubmenuTriggerProps.
|
|
1278
|
+
*/
|
|
1279
|
+
interface SubmenuDef extends BaseNodeDef, Required<Pick<PopupMenuSubmenuTriggerProps, 'value'>>, Pick<PopupMenuSubmenuTriggerProps, 'keywords' | 'disabled' | 'forceOrder' | 'forceScore'> {
|
|
1280
|
+
kind: 'submenu';
|
|
1281
|
+
/** Static child nodes */
|
|
1282
|
+
nodes?: NodeDef[];
|
|
1283
|
+
/**
|
|
1284
|
+
* Async child nodes configuration.
|
|
1285
|
+
* When provided, the Loader component will be rendered to fetch async data.
|
|
1286
|
+
* Async nodes are merged with static nodes.
|
|
1287
|
+
*/
|
|
1288
|
+
asyncNodes?: AsyncNodesConfig;
|
|
1289
|
+
/**
|
|
1290
|
+
* Whether to include this submenu's descendants in deep search.
|
|
1291
|
+
* @default true
|
|
1292
|
+
*/
|
|
1293
|
+
deepSearch?: boolean;
|
|
1294
|
+
/**
|
|
1295
|
+
* Whether this submenu is included in ancestor deep search results.
|
|
1296
|
+
* - `true`: include submenu trigger and descendants
|
|
1297
|
+
* - `'trigger-only'`: include submenu trigger only
|
|
1298
|
+
* - `false`: exclude submenu trigger and descendants
|
|
1299
|
+
* @default true
|
|
1300
|
+
*/
|
|
1301
|
+
includeInDeepSearch?: IncludeInDeepSearch;
|
|
1302
|
+
/**
|
|
1303
|
+
* Render function for the entire submenu structure.
|
|
1304
|
+
* Should return the complete submenu: trigger, portal, positioner, popup, surface, list.
|
|
1305
|
+
*/
|
|
1306
|
+
render: (params: SubmenuRenderParams) => React.ReactNode;
|
|
1307
|
+
}
|
|
1308
|
+
/**
|
|
1309
|
+
* Subpage node definition.
|
|
1310
|
+
* Represents a trigger row that opens a page in the same popup.
|
|
1311
|
+
* Props derived from PopupMenuSubpageTriggerProps.
|
|
1312
|
+
*/
|
|
1313
|
+
interface SubpageDef extends BaseNodeDef, Required<Pick<PopupMenuSubpageTriggerProps, 'value'>>, Pick<PopupMenuSubpageTriggerProps, 'keywords' | 'disabled' | 'forceOrder' | 'forceScore'> {
|
|
1314
|
+
kind: 'subpage';
|
|
1315
|
+
/** Static child nodes */
|
|
1316
|
+
nodes?: NodeDef[];
|
|
1317
|
+
/**
|
|
1318
|
+
* Async child nodes configuration.
|
|
1319
|
+
* When provided, the Loader component will be rendered to fetch async data.
|
|
1320
|
+
* Async nodes are merged with static nodes.
|
|
1321
|
+
*/
|
|
1322
|
+
asyncNodes?: AsyncNodesConfig;
|
|
1323
|
+
/**
|
|
1324
|
+
* Whether to include this subpage's descendants in deep search.
|
|
1325
|
+
* @default true
|
|
1326
|
+
*/
|
|
1327
|
+
deepSearch?: boolean;
|
|
1328
|
+
/**
|
|
1329
|
+
* Whether this subpage is included in ancestor deep search results.
|
|
1330
|
+
* - `true`: include subpage trigger and descendants
|
|
1331
|
+
* - `'trigger-only'`: include subpage trigger only
|
|
1332
|
+
* - `false`: exclude subpage trigger and descendants
|
|
1333
|
+
* @default true
|
|
1334
|
+
*/
|
|
1335
|
+
includeInDeepSearch?: IncludeInDeepSearch;
|
|
1336
|
+
/**
|
|
1337
|
+
* Render function for the trigger row.
|
|
1338
|
+
* Should return a `SubpageTrigger`.
|
|
1339
|
+
*/
|
|
1340
|
+
renderTrigger: (params: SubpageTriggerRenderParams) => React.ReactNode;
|
|
1341
|
+
/**
|
|
1342
|
+
* Render function for the subpage content.
|
|
1343
|
+
* Should return a `Subpage` rendered alongside the root Surface in Popup.
|
|
1344
|
+
*/
|
|
1345
|
+
renderContent: (params: SubpageContentRenderParams) => React.ReactNode;
|
|
1346
|
+
}
|
|
1347
|
+
/**
|
|
1348
|
+
* Render params for separator nodes.
|
|
1349
|
+
*/
|
|
1350
|
+
interface SeparatorRenderParams {
|
|
1351
|
+
/** Props to spread on the separator element */
|
|
1352
|
+
props: {
|
|
1353
|
+
/** Unique identifier */
|
|
1354
|
+
id?: string;
|
|
1355
|
+
};
|
|
1356
|
+
}
|
|
1357
|
+
/**
|
|
1358
|
+
* Separator node definition.
|
|
1359
|
+
* Represents a visual separator between items.
|
|
1360
|
+
*/
|
|
1361
|
+
interface SeparatorDef {
|
|
1362
|
+
kind: 'separator';
|
|
1363
|
+
/** Unique identifier */
|
|
1364
|
+
id: string;
|
|
1365
|
+
/** Optional render function for custom separator rendering */
|
|
1366
|
+
render?: (params: SeparatorRenderParams) => React.ReactNode;
|
|
1367
|
+
}
|
|
1368
|
+
/**
|
|
1369
|
+
* Group node definition.
|
|
1370
|
+
* Represents a group of items with an optional label.
|
|
1371
|
+
*/
|
|
1372
|
+
interface GroupDef {
|
|
1373
|
+
kind: 'group';
|
|
1374
|
+
/** Unique identifier for this group */
|
|
1375
|
+
id: string;
|
|
1376
|
+
/** Optional group heading/label */
|
|
1377
|
+
label?: string;
|
|
1378
|
+
/** Child nodes in this group */
|
|
1379
|
+
nodes: NodeDef[];
|
|
1380
|
+
/** Optional render function for the group container */
|
|
1381
|
+
render?: (params: GroupRenderParams) => React.ReactNode;
|
|
1382
|
+
/**
|
|
1383
|
+
* Optional render function for the group's label row.
|
|
1384
|
+
* Used by the default group container when no `render` is provided, and by
|
|
1385
|
+
* virtualized lists (which ignore `render` and use only the label row).
|
|
1386
|
+
* Precedence: `render` > `renderLabel` > `label`.
|
|
1387
|
+
*/
|
|
1388
|
+
renderLabel?: (params: GroupLabelRenderParams) => React.ReactNode;
|
|
1389
|
+
}
|
|
1390
|
+
/**
|
|
1391
|
+
* Radio group node definition.
|
|
1392
|
+
* Represents a group of radio items where only one can be selected.
|
|
1393
|
+
* Props derived from PopupMenuRadioGroupProps.
|
|
1394
|
+
*/
|
|
1395
|
+
interface RadioGroupDef extends Pick<PopupMenuRadioGroupProps, 'value' | 'onValueChange' | 'disabled'> {
|
|
1396
|
+
kind: 'radio-group';
|
|
1397
|
+
/** Unique identifier for this radio group */
|
|
1398
|
+
id: string;
|
|
1399
|
+
/** Optional group heading/label */
|
|
1400
|
+
label?: string;
|
|
1401
|
+
/** Whether the radio group is hidden */
|
|
1402
|
+
hidden?: boolean;
|
|
1403
|
+
/** Child nodes in this radio group - must be RadioItemDef nodes */
|
|
1404
|
+
nodes: RadioItemDef[];
|
|
1405
|
+
/** Optional render function for the radio group container */
|
|
1406
|
+
render?: (params: RadioGroupRenderParams) => React.ReactNode;
|
|
1407
|
+
/**
|
|
1408
|
+
* Optional render function for the radio group's label row.
|
|
1409
|
+
* Used by the default radio group container when no `render` is provided, and by
|
|
1410
|
+
* virtualized lists (which ignore `render` and use only the label row).
|
|
1411
|
+
* Precedence: `render` > `renderLabel` > `label`.
|
|
1412
|
+
*/
|
|
1413
|
+
renderLabel?: (params: RadioGroupLabelRenderParams) => React.ReactNode;
|
|
1414
|
+
}
|
|
1415
|
+
/**
|
|
1416
|
+
* Helper function to create a radio group definition with proper typing.
|
|
1417
|
+
*/
|
|
1418
|
+
declare function defineRadioGroup(def: RadioGroupDef): RadioGroupDef;
|
|
1419
|
+
/**
|
|
1420
|
+
* Union of all node definition types.
|
|
1421
|
+
*/
|
|
1422
|
+
type NodeDef = ItemDef | TreeItemDef | RadioItemDef | CheckboxItemDef | SubmenuDef | SubpageDef | SeparatorDef | GroupDef | RadioGroupDef;
|
|
1423
|
+
/**
|
|
1424
|
+
* A node with its search score and breadcrumb path.
|
|
1425
|
+
* Used internally during filtering and scoring.
|
|
1426
|
+
*/
|
|
1427
|
+
interface ScoredNode {
|
|
1428
|
+
/** The row's Menu Node; its authored definition is `node.def`. */
|
|
1429
|
+
node: PopupMenuNode<RowNodeDef>;
|
|
1430
|
+
/** Search match score (higher = better match). */
|
|
1431
|
+
score: number;
|
|
1432
|
+
/**
|
|
1433
|
+
* Breadcrumb nodes leading to this node.
|
|
1434
|
+
* Contains the full submenu definitions for maximum flexibility.
|
|
1435
|
+
*/
|
|
1436
|
+
breadcrumbs: BreadcrumbNode[];
|
|
1437
|
+
/** The group this node belongs to, if any */
|
|
1438
|
+
group: {
|
|
1439
|
+
id: string;
|
|
1440
|
+
label?: string;
|
|
1441
|
+
groupDef: GroupDef;
|
|
1442
|
+
menuNode: PopupMenuNode<GroupDef>;
|
|
1443
|
+
} | null;
|
|
1444
|
+
/** The radio group this node belongs to, if any */
|
|
1445
|
+
radioGroup: {
|
|
1446
|
+
id: string;
|
|
1447
|
+
label?: string;
|
|
1448
|
+
radioGroupDef: RadioGroupDef;
|
|
1449
|
+
menuNode: PopupMenuNode<RadioGroupDef>;
|
|
1450
|
+
} | null;
|
|
1451
|
+
}
|
|
1452
|
+
type RowNodeDef = ItemDef | RadioItemDef | CheckboxItemDef | SubmenuDef | SubpageDef | TreeItemDef;
|
|
1453
|
+
/**
|
|
1454
|
+
* A row node ready for display with its render context.
|
|
1455
|
+
* Used for items, radio items, checkbox items, and submenu triggers.
|
|
1456
|
+
*/
|
|
1457
|
+
interface DisplayRowNode {
|
|
1458
|
+
kind: 'row';
|
|
1459
|
+
/** The resolved menu node; its authored definition is `node.def`. */
|
|
1460
|
+
node: PopupMenuNode<RowNodeDef>;
|
|
1461
|
+
/** Pre-computed render context for this node */
|
|
1462
|
+
context: RowRenderContext;
|
|
1463
|
+
/** Radio group this node belongs to, if rendering inside one */
|
|
1464
|
+
radioGroup?: {
|
|
1465
|
+
id: string;
|
|
1466
|
+
label?: string;
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
/**
|
|
1470
|
+
* A subpage content node ready for display with its render context.
|
|
1471
|
+
* Used by DataSubpages to render subpage content alongside the root Surface.
|
|
1472
|
+
*/
|
|
1473
|
+
interface DisplaySubpageNode {
|
|
1474
|
+
/** The resolved node for this subpage. The authored def is `node.def`. */
|
|
1475
|
+
node: PopupMenuNode<SubpageDef>;
|
|
1476
|
+
/** Pre-computed render context for this subpage trigger/content */
|
|
1477
|
+
context: RowRenderContext;
|
|
1478
|
+
/** Computed page ID for this subpage */
|
|
1479
|
+
pageId: string;
|
|
1480
|
+
}
|
|
1481
|
+
/**
|
|
1482
|
+
* A group node ready for display with its render context.
|
|
1483
|
+
* Contains the group definition and its matching items.
|
|
1484
|
+
*/
|
|
1485
|
+
interface DisplayGroupNode {
|
|
1486
|
+
kind: 'group';
|
|
1487
|
+
/** The resolved node; authored def at node.def. */
|
|
1488
|
+
node: PopupMenuNode<GroupDef>;
|
|
1489
|
+
/** Pre-computed render context for this group */
|
|
1490
|
+
context: GroupRenderContext;
|
|
1491
|
+
/** Display nodes for items within this group */
|
|
1492
|
+
items: DisplayRowNode[];
|
|
1493
|
+
/** Best match score among items in this group */
|
|
1494
|
+
bestScore: number;
|
|
1495
|
+
}
|
|
1496
|
+
/**
|
|
1497
|
+
* A radio group node ready for display with its render context.
|
|
1498
|
+
* Contains the radio group definition and its items.
|
|
1499
|
+
*/
|
|
1500
|
+
interface DisplayRadioGroupNode {
|
|
1501
|
+
kind: 'radio-group';
|
|
1502
|
+
/** The resolved node; authored def at node.def. */
|
|
1503
|
+
node: PopupMenuNode<RadioGroupDef>;
|
|
1504
|
+
/** Pre-computed render context for this radio group */
|
|
1505
|
+
context: GroupRenderContext;
|
|
1506
|
+
/** Display nodes for items within this radio group */
|
|
1507
|
+
items: DisplayRowNode[];
|
|
1508
|
+
/** Best match score among items in this radio group */
|
|
1509
|
+
bestScore: number;
|
|
1510
|
+
}
|
|
1511
|
+
/**
|
|
1512
|
+
* A separator node ready for display.
|
|
1513
|
+
*/
|
|
1514
|
+
interface DisplaySeparatorNode {
|
|
1515
|
+
kind: 'separator';
|
|
1516
|
+
/** The resolved node; authored def at node.def. */
|
|
1517
|
+
node: PopupMenuNode<SeparatorDef>;
|
|
1518
|
+
}
|
|
1519
|
+
/**
|
|
1520
|
+
* Union of all display node types.
|
|
1521
|
+
* Can be a row node (item/submenu/subpage), group node, radio group node, or separator.
|
|
1522
|
+
*/
|
|
1523
|
+
type DisplayNode = DisplayRowNode | DisplayGroupNode | DisplayRadioGroupNode | DisplaySeparatorNode;
|
|
1524
|
+
/**
|
|
1525
|
+
* Type guard for DisplayGroupNode.
|
|
1526
|
+
*/
|
|
1527
|
+
declare function isDisplayGroupNode(node: DisplayNode): node is DisplayGroupNode;
|
|
1528
|
+
/**
|
|
1529
|
+
* Type guard for DisplayRadioGroupNode.
|
|
1530
|
+
*/
|
|
1531
|
+
declare function isDisplayRadioGroupNode(node: DisplayNode): node is DisplayRadioGroupNode;
|
|
1532
|
+
/**
|
|
1533
|
+
* Type guard for DisplaySeparatorNode.
|
|
1534
|
+
*/
|
|
1535
|
+
declare function isDisplaySeparatorNode(node: DisplayNode): node is DisplaySeparatorNode;
|
|
1536
|
+
/**
|
|
1537
|
+
* Type guard for DisplayRowNode (items, checkbox items, submenus, subpages).
|
|
1538
|
+
*/
|
|
1539
|
+
declare function isDisplayRowNode(node: DisplayNode): node is DisplayRowNode;
|
|
1540
|
+
/**
|
|
1541
|
+
* Defines how groups behave during deep search.
|
|
1542
|
+
* - 'flatten': Groups become invisible, items shown in flat list by score.
|
|
1543
|
+
* - 'preserve': Groups are shown as containers with their matching items.
|
|
1544
|
+
* Note: Radio groups are ALWAYS preserved regardless of this setting.
|
|
1545
|
+
*/
|
|
1546
|
+
type GroupBehavior = 'flatten' | 'preserve';
|
|
1547
|
+
/**
|
|
1548
|
+
* Defines how radio groups behave during deep search.
|
|
1549
|
+
* - 'flatten': Radio group items are shown individually in the flat list (not recommended).
|
|
1550
|
+
* - 'preserve': Radio group is shown with only matching items visible.
|
|
1551
|
+
* - 'preserve-show-all': Radio group is shown with ALL items visible when any item matches.
|
|
1552
|
+
* This is useful when you want users to see all options in a radio group.
|
|
1553
|
+
*/
|
|
1554
|
+
type RadioGroupBehavior = 'flatten' | 'preserve' | 'preserve-show-all';
|
|
1555
|
+
/**
|
|
1556
|
+
* Defines how deep-search async results are revealed.
|
|
1557
|
+
* - 'stream': show available results immediately and append new async batches as they resolve.
|
|
1558
|
+
* - 'block': hide all deep-search rows until every participating async loader resolves.
|
|
1559
|
+
*/
|
|
1560
|
+
type AsyncResultBehavior = 'stream' | 'block';
|
|
1561
|
+
/**
|
|
1562
|
+
* Configuration for deep search behavior.
|
|
1563
|
+
*/
|
|
1564
|
+
interface DeepSearchConfig {
|
|
1565
|
+
/** Whether deep search is enabled */
|
|
1566
|
+
enabled?: boolean;
|
|
1567
|
+
/** Minimum query length before deep search activates */
|
|
1568
|
+
minLength?: number;
|
|
1569
|
+
/**
|
|
1570
|
+
* How groups behave during search results.
|
|
1571
|
+
* Only affects search mode - groups are always shown in browse mode.
|
|
1572
|
+
* Note: Radio groups have their own behavior controlled by radioGroupSearchBehavior.
|
|
1573
|
+
* @default 'preserve'
|
|
1574
|
+
*/
|
|
1575
|
+
groupSearchBehavior?: GroupBehavior;
|
|
1576
|
+
/**
|
|
1577
|
+
* How radio groups behave during search results.
|
|
1578
|
+
* - 'flatten': Radio items shown individually (not recommended).
|
|
1579
|
+
* - 'preserve': Only matching radio items are shown (default).
|
|
1580
|
+
* - 'preserve-show-all': All radio items are shown when any item matches.
|
|
1581
|
+
* @default 'preserve'
|
|
1582
|
+
*/
|
|
1583
|
+
radioGroupSearchBehavior?: RadioGroupBehavior;
|
|
1584
|
+
/**
|
|
1585
|
+
* Whether to sort groups by their best-matching item's score.
|
|
1586
|
+
* Only applies when groupSearchBehavior: 'preserve'.
|
|
1587
|
+
* @default true
|
|
1588
|
+
*/
|
|
1589
|
+
sortGroups?: boolean;
|
|
1590
|
+
/**
|
|
1591
|
+
* How async deep-search results are revealed.
|
|
1592
|
+
* - 'stream': emit available results immediately, append later async batches (default)
|
|
1593
|
+
* - 'block': show loading state only until all loaders resolve, then render once
|
|
1594
|
+
* @default 'stream'
|
|
1595
|
+
*/
|
|
1596
|
+
asyncResultBehavior?: AsyncResultBehavior;
|
|
1597
|
+
}
|
|
1598
|
+
/**
|
|
1599
|
+
* Props for the DataSurface component.
|
|
1600
|
+
*/
|
|
1601
|
+
interface DataSurfaceProps {
|
|
1602
|
+
/**
|
|
1603
|
+
* The menu content (node definitions with render functions). Resolved nodes
|
|
1604
|
+
* are accepted anywhere defs are; they are unwrapped to their defs, and
|
|
1605
|
+
* re-supplying the same nodes preserves identity.
|
|
1606
|
+
*/
|
|
1607
|
+
content?: NodeDef[] | PopupMenuNode[];
|
|
1608
|
+
/**
|
|
1609
|
+
* Async content configuration for root-level async loading.
|
|
1610
|
+
* When provided, the Loader component will be rendered to fetch async data.
|
|
1611
|
+
* Async content is merged with static content.
|
|
1612
|
+
*/
|
|
1613
|
+
asyncContent?: AsyncLoaderConfig;
|
|
1614
|
+
/** Deep search configuration */
|
|
1615
|
+
deepSearch?: DeepSearchConfig | boolean;
|
|
1616
|
+
/**
|
|
1617
|
+
* Default inclusion mode for descendant branch nodes in deep search results.
|
|
1618
|
+
* Submenus/subpages can override via `includeInDeepSearch`.
|
|
1619
|
+
* @default true
|
|
1620
|
+
*/
|
|
1621
|
+
includeInDeepSearch?: IncludeInDeepSearch;
|
|
1622
|
+
/** Filter function or false to disable filtering */
|
|
1623
|
+
filter?: ((value: string, search: string, keywords?: string[]) => number) | false;
|
|
1624
|
+
/**
|
|
1625
|
+
* Transforms search input before filtering and visibility logic.
|
|
1626
|
+
* @default trim whitespace (`search.trim()`)
|
|
1627
|
+
*/
|
|
1628
|
+
normalizeSearch?: (search: string) => string;
|
|
1629
|
+
/** Controlled search value */
|
|
1630
|
+
search?: string;
|
|
1631
|
+
/** Callback when search value changes */
|
|
1632
|
+
onSearchChange?: (search: string) => void;
|
|
1633
|
+
/** Default search value for uncontrolled usage */
|
|
1634
|
+
defaultSearch?: string;
|
|
1635
|
+
/** Whether navigation should loop */
|
|
1636
|
+
loop?: boolean;
|
|
1637
|
+
/** Auto-highlight behavior when menu opens */
|
|
1638
|
+
autoHighlightFirst?: boolean | string;
|
|
1639
|
+
/**
|
|
1640
|
+
* Whether to clear search on close.
|
|
1641
|
+
* - `true`: clear immediately when menu closes (default)
|
|
1642
|
+
* - `false`: preserve search when menu closes
|
|
1643
|
+
* - `'after-exit'`: clear after exit animation completes
|
|
1644
|
+
*/
|
|
1645
|
+
clearSearchOnClose?: boolean | 'after-exit';
|
|
1646
|
+
/**
|
|
1647
|
+
* Whether to reset the list scroll position when the search query changes.
|
|
1648
|
+
* @default true
|
|
1649
|
+
*/
|
|
1650
|
+
resetScrollOnSearch?: boolean;
|
|
1651
|
+
/** Children (Input, List, etc.) */
|
|
1652
|
+
children: React.ReactNode;
|
|
1653
|
+
}
|
|
1654
|
+
/**
|
|
1655
|
+
* State passed to the DataList render function.
|
|
1656
|
+
*/
|
|
1657
|
+
interface DataListChildrenState {
|
|
1658
|
+
/** Current search query (empty string if browsing) */
|
|
1659
|
+
search: string;
|
|
1660
|
+
/**
|
|
1661
|
+
* Display nodes (filtered and scored if searching).
|
|
1662
|
+
* Can include groups (DisplayGroupNode) or radio groups (DisplayRadioGroupNode)
|
|
1663
|
+
* when groupSearchBehavior: 'preserve'.
|
|
1664
|
+
*/
|
|
1665
|
+
nodes: DisplayNode[];
|
|
1666
|
+
/**
|
|
1667
|
+
* Function to render a node.
|
|
1668
|
+
* Handles items, submenus, groups, and radio groups, calling their render functions with context.
|
|
1669
|
+
*/
|
|
1670
|
+
renderNode: (displayNode: DisplayNode) => React.ReactNode;
|
|
1671
|
+
/** Number of visible items (counting items inside groups) */
|
|
1672
|
+
count: number;
|
|
1673
|
+
/** Whether deep search is active (query length >= minLength) */
|
|
1674
|
+
isDeepSearching: boolean;
|
|
1675
|
+
/** Aggregate async loading state across all menus */
|
|
1676
|
+
async: AsyncState;
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
type PopupMenuIdScope = 'menu' | 'surface';
|
|
1680
|
+
/**
|
|
1681
|
+
* A menu node: the library-created, resolved instance of a node def.
|
|
1682
|
+
* Exactly one per logical row per menu root, in every render context —
|
|
1683
|
+
* object identity is Resolved ID identity, and `id` is its serialization.
|
|
1684
|
+
* Created by resolution at the root or by grafting; instances are stable
|
|
1685
|
+
* across content re-supplies (reconciliation swaps `def` in place).
|
|
1686
|
+
* The type parameter narrows `def`/`kind` for callers that know the def kind
|
|
1687
|
+
* statically. Narrowing is a lookup-time snapshot: reconcile may replace `def`
|
|
1688
|
+
* in place with another def of the same resolved id, so a long-held narrowed
|
|
1689
|
+
* reference sees the current def, not necessarily the exact object/type it was
|
|
1690
|
+
* looked up with.
|
|
1691
|
+
*/
|
|
1692
|
+
interface PopupMenuNode<D extends NodeDef = NodeDef> {
|
|
1693
|
+
/** The originating def. Replaced in place when content is re-supplied. */
|
|
1694
|
+
def: D;
|
|
1695
|
+
/** Mirror of `def.kind`, stable for the node's lifetime. */
|
|
1696
|
+
kind: D['kind'];
|
|
1697
|
+
/**
|
|
1698
|
+
* This node's path component: explicit `def.id` verbatim when present,
|
|
1699
|
+
* otherwise the slugified `value` (kinds without a display value use
|
|
1700
|
+
* their required `id`).
|
|
1701
|
+
*/
|
|
1702
|
+
definitionKey: string;
|
|
1703
|
+
/**
|
|
1704
|
+
* Definition Path: Definition Keys from the menu root to this node,
|
|
1705
|
+
* including its own key, root-first. Only submenu and subpage ancestors
|
|
1706
|
+
* contribute keys (groups, radio-groups, and tree-items are path-transparent).
|
|
1707
|
+
*/
|
|
1708
|
+
definitionPath: string[];
|
|
1709
|
+
/** Resolved ID selected by the root's identity policy. */
|
|
1710
|
+
id: string;
|
|
1711
|
+
parent: PopupMenuNode | null;
|
|
1712
|
+
children: PopupMenuNode[];
|
|
1713
|
+
/** Def-tree depth counting every node kind; roots are 0. */
|
|
1714
|
+
depth: number;
|
|
1715
|
+
/** Sibling index in the def tree (position within `parent.children`). */
|
|
1716
|
+
index: number;
|
|
1717
|
+
}
|
|
1718
|
+
/**
|
|
1719
|
+
* A menu node before its resolved ID is assigned — the argument to `GetResolvedIdFn`.
|
|
1720
|
+
* Carries definitional facts only (`def`, `definitionKey`, `definitionPath`, resolved
|
|
1721
|
+
* `parent`, `depth`, def-tree sibling `index`). Contextual facts (search
|
|
1722
|
+
* state, deep-search flags, display position) are deliberately absent:
|
|
1723
|
+
* a context-dependent Resolved ID is inexpressible by construction.
|
|
1724
|
+
*/
|
|
1725
|
+
type UnresolvedMenuNode = Omit<PopupMenuNode, 'id'>;
|
|
1726
|
+
/**
|
|
1727
|
+
* Computes a node's Resolved ID from definitional facts. The ID must be unique
|
|
1728
|
+
* per menu root; it is the identity persistent state, registration, and
|
|
1729
|
+
* highlight key off.
|
|
1730
|
+
*
|
|
1731
|
+
* Contract: the id may read the node's own facts (including its own sibling
|
|
1732
|
+
* `index`) and may walk `parent` for lineage (as the default definition-path
|
|
1733
|
+
* rule does), but it must not depend on an *ancestor's* sibling `index` —
|
|
1734
|
+
* reconciliation invalidates ids by def identity and definition path, not by
|
|
1735
|
+
* ancestor reordering, so ancestor-index-dependent ids would go stale. The
|
|
1736
|
+
* seam must also not mutate its argument.
|
|
1737
|
+
*/
|
|
1738
|
+
type GetResolvedIdFn = (node: UnresolvedMenuNode) => string;
|
|
1739
|
+
|
|
1740
|
+
/**
|
|
1741
|
+
* Reasons why a popup menu's open state changed.
|
|
1742
|
+
*/
|
|
1743
|
+
type PopupMenuOpenChangeReason = typeof triggerPress | typeof triggerHover | typeof triggerFocus | typeof triggerContextMenu | typeof escapeKey | typeof outsidePress | typeof focusOut | typeof itemPress | typeof closePress | typeof listNavigation | typeof submenuTrigger | typeof siblingOpen | typeof imperativeAction | typeof none;
|
|
1744
|
+
/**
|
|
1745
|
+
* Event details for popup menu open state changes.
|
|
1746
|
+
*/
|
|
1747
|
+
type PopupMenuOpenChangeEventDetails = ChangeEventDetails<PopupMenuOpenChangeReason>;
|
|
1748
|
+
/**
|
|
1749
|
+
* Reasons why highlight changed.
|
|
1750
|
+
*/
|
|
1751
|
+
type HighlightChangeReason = typeof pointer | typeof keyboard | typeof auto | typeof none;
|
|
1752
|
+
/**
|
|
1753
|
+
* Event details for highlight changes.
|
|
1754
|
+
*/
|
|
1755
|
+
type HighlightChangeEventDetails = GenericEventDetails<HighlightChangeReason, {
|
|
1756
|
+
index: number;
|
|
1757
|
+
}>;
|
|
1758
|
+
type PopupMenuHighlightChangeHandler<EventDetails = HighlightChangeEventDetails> = (id: string | null, node: PopupMenuNode | null, index: number, eventDetails: EventDetails) => void;
|
|
1759
|
+
/**
|
|
1760
|
+
* Reasons why a checkbox item's checked state changed.
|
|
1761
|
+
*/
|
|
1762
|
+
type CheckedChangeReason = typeof itemPress | typeof itemKeyboardSelect;
|
|
1763
|
+
/**
|
|
1764
|
+
* Event details for checkbox item checked state changes.
|
|
1765
|
+
*/
|
|
1766
|
+
type CheckedChangeEventDetails = ChangeEventDetails<CheckedChangeReason>;
|
|
1767
|
+
/**
|
|
1768
|
+
* Reasons why a radio group's value changed.
|
|
1769
|
+
*/
|
|
1770
|
+
type RadioValueChangeReason = typeof itemPress | typeof itemKeyboardSelect;
|
|
1771
|
+
/**
|
|
1772
|
+
* Event details for radio group value changes.
|
|
1773
|
+
*/
|
|
1774
|
+
type RadioValueChangeEventDetails = ChangeEventDetails<RadioValueChangeReason>;
|
|
1775
|
+
|
|
1776
|
+
export { type CheckboxItemRenderProps as $, type PopupMenuItemProps as A, type PopupMenuItemState as B, type ChangeEventDetails as C, type PopupMenuRadioGroupProps as D, type PopupMenuRadioGroupState as E, type PopupMenuRadioItemProps as F, type GenericEventDetails as G, type PopupMenuRadioItemState as H, type PopupMenuSubmenuTriggerProps as I, type PopupMenuSubmenuTriggerState as J, type PopupMenuSubpageTriggerProps as K, type PopupMenuSubpageTriggerState as L, type AsyncLoaderConfig as M, type NodeDef as N, type AsyncLoaderFetchStatus as O, type PopupMenuHighlightChangeHandler as P, type AsyncLoaderLoadingPhase as Q, type AsyncLoaderResult as R, type AsyncLoaderSource as S, type AsyncLoaderStatus as T, type AsyncNodesConfig as U, type AsyncRenderState as V, type AsyncResultBehavior as W, type AsyncState as X, type BreadcrumbNode as Y, type CheckboxItemDef as Z, type CheckboxItemRenderParams as _, triggerHover as a, type DataListChildrenState as a0, type DeepSearchConfig as a1, type DisplayGroupNode as a2, type DisplayNode as a3, type DisplayRadioGroupNode as a4, type DisplayRowNode as a5, type DisplaySeparatorNode as a6, type DisplaySubpageNode as a7, type GroupBehavior as a8, type GroupDef as a9, type SubmenuRenderParams as aA, type SubmenuRenderProps as aB, type SubpageContentRenderParams as aC, type SubpageDef as aD, type SubpageTriggerRenderParams as aE, type SubpageTriggerRenderProps as aF, type TreeItemDef as aG, type TreeItemRenderParams as aH, type TreeItemRenderProps as aI, type UnresolvedMenuNode as aJ, defineRadioGroup as aK, isDisplayGroupNode as aL, isDisplayRadioGroupNode as aM, isDisplayRowNode as aN, isDisplaySeparatorNode as aO, inputChange as aP, inputClear as aQ, triggerContextMenu as aR, type HighlightChangeEventDetails as aS, type RadioValueChangeEventDetails as aT, type PopupMenuOpenChangeReason as aU, type DataSurfaceProps as aV, type PopupMenuOpenChangeEventDetails as aW, type GroupLabelRenderParams as aa, type GroupRenderContext as ab, type GroupRenderParams as ac, type IncludeInDeepSearch as ad, type InitialQueryBehavior as ae, type ItemDef as af, type ItemRenderParams as ag, type ItemRenderProps as ah, type LoaderComponentProps as ai, type QueryAsyncNodesConfig as aj, type QueryLoaderConfig as ak, type RadioGroupBehavior as al, type RadioGroupDef as am, type RadioGroupLabelRenderParams as an, type RadioGroupRenderParams as ao, type RadioGroupRenderProps as ap, type RadioItemDef as aq, type RadioItemRenderParams as ar, type RadioItemRenderProps as as, type RowRenderContext as at, type ScoredNode as au, type SeparatorDef as av, type SeparatorRenderParams as aw, type StaticAsyncNodesConfig as ax, type StaticLoaderConfig as ay, type SubmenuDef as az, triggerFocus as b, closePress as c, siblingOpen as d, escapeKey as e, focusOut as f, imperativeAction as g, type GetResolvedIdFn as h, itemPress as i, type PopupMenuIdScope as j, keyboard as k, listNavigation as l, PopupMenuCheckboxItem as m, none as n, outsidePress as o, pointer as p, PopupMenuItem as q, type PopupMenuNode as r, submenuTrigger as s, triggerPress as t, PopupMenuRadioGroup as u, PopupMenuRadioItem as v, PopupMenuSubmenuTrigger as w, PopupMenuSubpageTrigger as x, type PopupMenuCheckboxItemProps as y, type PopupMenuCheckboxItemState as z };
|