@bazza-ui/react 0.0.0 → 0.1.0-canary.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/ListboxStore-BtcTXpzi.d.cts +351 -0
  2. package/dist/ListboxStore-DPqpLlAL.d.ts +351 -0
  3. package/dist/adapters/index.cjs +2 -0
  4. package/dist/adapters/index.cjs.map +1 -0
  5. package/dist/adapters/index.d.cts +363 -0
  6. package/dist/adapters/index.d.ts +363 -0
  7. package/dist/adapters/index.js +2 -0
  8. package/dist/adapters/index.js.map +1 -0
  9. package/dist/chunk-4C666HHU.js +2 -0
  10. package/dist/chunk-4C666HHU.js.map +1 -0
  11. package/dist/chunk-AVZ64JQ3.js +2 -0
  12. package/dist/chunk-AVZ64JQ3.js.map +1 -0
  13. package/dist/chunk-BGJJC6GX.cjs +2 -0
  14. package/dist/chunk-BGJJC6GX.cjs.map +1 -0
  15. package/dist/chunk-FWWOE2SW.cjs +2 -0
  16. package/dist/chunk-FWWOE2SW.cjs.map +1 -0
  17. package/dist/chunk-JSPKF52O.cjs +2 -0
  18. package/dist/chunk-JSPKF52O.cjs.map +1 -0
  19. package/dist/chunk-KWGD24VS.js +2 -0
  20. package/dist/chunk-KWGD24VS.js.map +1 -0
  21. package/dist/chunk-M4G6J7DP.cjs +2 -0
  22. package/dist/chunk-M4G6J7DP.cjs.map +1 -0
  23. package/dist/chunk-WKAPAKUL.js +2 -0
  24. package/dist/chunk-WKAPAKUL.js.map +1 -0
  25. package/dist/combobox/index.cjs +2 -0
  26. package/dist/combobox/index.cjs.map +1 -0
  27. package/dist/combobox/index.d.cts +1039 -0
  28. package/dist/combobox/index.d.ts +1039 -0
  29. package/dist/combobox/index.js +2 -0
  30. package/dist/combobox/index.js.map +1 -0
  31. package/dist/command-score-Dgo3ZS3Z.d.ts +36 -0
  32. package/dist/command-score-YjNr3ZWi.d.cts +36 -0
  33. package/dist/context-menu/index.cjs +2 -0
  34. package/dist/context-menu/index.cjs.map +1 -0
  35. package/dist/context-menu/index.d.cts +658 -0
  36. package/dist/context-menu/index.d.ts +658 -0
  37. package/dist/context-menu/index.js +2 -0
  38. package/dist/context-menu/index.js.map +1 -0
  39. package/dist/data-surface-B-eIGTBi.d.cts +678 -0
  40. package/dist/data-surface-D1OilMDu.d.ts +678 -0
  41. package/dist/dropdown-menu/index.cjs +2 -0
  42. package/dist/dropdown-menu/index.cjs.map +1 -0
  43. package/dist/dropdown-menu/index.d.cts +700 -0
  44. package/dist/dropdown-menu/index.d.ts +700 -0
  45. package/dist/dropdown-menu/index.js +2 -0
  46. package/dist/dropdown-menu/index.js.map +1 -0
  47. package/dist/events-BPr8sRGH.d.cts +166 -0
  48. package/dist/events-BPr8sRGH.d.ts +166 -0
  49. package/dist/input-BoIK003I.d.cts +41 -0
  50. package/dist/input-DF7D8YzW.d.ts +41 -0
  51. package/dist/internal/listbox/index.cjs +2 -0
  52. package/dist/internal/listbox/index.cjs.map +1 -0
  53. package/dist/internal/listbox/index.d.cts +269 -0
  54. package/dist/internal/listbox/index.d.ts +269 -0
  55. package/dist/internal/listbox/index.js +2 -0
  56. package/dist/internal/listbox/index.js.map +1 -0
  57. package/dist/internal/popup-menu/index.cjs +2 -0
  58. package/dist/internal/popup-menu/index.cjs.map +1 -0
  59. package/dist/internal/popup-menu/index.d.cts +846 -0
  60. package/dist/internal/popup-menu/index.d.ts +846 -0
  61. package/dist/internal/popup-menu/index.js +2 -0
  62. package/dist/internal/popup-menu/index.js.map +1 -0
  63. package/dist/item-equality-B6TbXlBT.d.cts +7 -0
  64. package/dist/item-equality-B6TbXlBT.d.ts +7 -0
  65. package/dist/loading-DphSt8MY.d.cts +27 -0
  66. package/dist/loading-TsgH6v92.d.ts +27 -0
  67. package/dist/select/index.cjs +2 -0
  68. package/dist/select/index.cjs.map +1 -0
  69. package/dist/select/index.d.cts +927 -0
  70. package/dist/select/index.d.ts +927 -0
  71. package/dist/select/index.js +2 -0
  72. package/dist/select/index.js.map +1 -0
  73. package/dist/separator-B4Ot84B0.d.ts +748 -0
  74. package/dist/separator-BmbUeeaT.d.cts +748 -0
  75. package/dist/types-9vS1uLIK.d.cts +1557 -0
  76. package/dist/types-lQCIvWW8.d.ts +1557 -0
  77. package/dist/use-listbox-item-BIi4eRPI.d.cts +182 -0
  78. package/dist/use-listbox-item-BIi4eRPI.d.ts +182 -0
  79. package/package.json +50 -12
  80. package/dist/index.d.ts +0 -2
  81. package/dist/index.js +0 -2
@@ -0,0 +1,351 @@
1
+ import { ReactStore } from '@base-ui/utils/store';
2
+ import { v as PopupMenuOpenChangeEventDetails, H as HighlightChangeEventDetails, P as PopupMenuOpenChangeReason } from './events-BPr8sRGH.js';
3
+
4
+ type FilterFn = (value: string, search: string, keywords?: string[]) => number;
5
+ type SearchNormalizer = (search: string) => string;
6
+ interface ItemRegistration {
7
+ value: string;
8
+ keywords?: string[];
9
+ groupId?: string;
10
+ disabled?: boolean;
11
+ /** Lower values are sorted earlier in score-based lists. */
12
+ forceOrder?: number;
13
+ /** Overrides computed fuzzy score in score-based lists. */
14
+ forceScore?: number;
15
+ /** Whether this item is a submenu trigger */
16
+ isSubmenuTrigger?: boolean;
17
+ /** Single character keyboard shortcut to trigger this item */
18
+ shortcut?: string;
19
+ /** Whether selecting this item should close the menu (default: true) */
20
+ closeOnClick?: boolean;
21
+ }
22
+ /**
23
+ * Pre-registered item for virtualization.
24
+ * This allows the store to know about all items even when they're not mounted.
25
+ * The `value` field serves as both the unique identifier and the filtering value.
26
+ */
27
+ interface VirtualItem {
28
+ /** Value used as unique identifier and for filtering/matching */
29
+ value: string;
30
+ /** Additional keywords for filtering */
31
+ keywords?: string[];
32
+ /** Whether the item is disabled */
33
+ disabled?: boolean;
34
+ }
35
+ type HighlightSource = 'keyboard' | 'pointer' | 'auto' | null;
36
+ /**
37
+ * Describes why the consumer updated ordered items when filter={false}.
38
+ * - `replace`: list was re-ordered/replaced (default)
39
+ * - `append`: new items were appended to the end while preserving existing order
40
+ */
41
+ type OrderedItemsUpdateReason = 'replace' | 'append';
42
+ interface SetOrderedItemsOptions {
43
+ /** Why ordered items were updated. @default 'replace' */
44
+ reason?: OrderedItemsUpdateReason;
45
+ }
46
+ /**
47
+ * Refs for DOM elements used for scroll behavior.
48
+ * These are stored outside of reactive state to avoid unnecessary re-renders.
49
+ */
50
+ interface DOMRefs {
51
+ /** Ref to the list/scroll container element */
52
+ listRef: React.RefObject<HTMLElement | null>;
53
+ /** Map of item ID to ref for the item's DOM element */
54
+ itemRefs: Map<string, React.RefObject<HTMLElement | null>>;
55
+ }
56
+ interface ListboxState {
57
+ /** Whether the listbox is open */
58
+ open: boolean;
59
+ /** Current search query */
60
+ search: string;
61
+ /** Normalized search query used for filtering and visibility checks */
62
+ normalizedSearch: string;
63
+ /** Currently highlighted item ID */
64
+ highlightedId: string | null;
65
+ /** Source of the current highlight (keyboard or pointer) */
66
+ highlightSource: HighlightSource;
67
+ /** Whether an Input is present in the Surface */
68
+ hasInput: boolean;
69
+ /** Whether the input is currently active (rendered) when hideUntilActive mode is used */
70
+ inputActive: boolean;
71
+ /** Pending search character typed before input was active */
72
+ pendingSearch: string;
73
+ /** Filtered results: item ID to score */
74
+ filteredItems: Map<string, number>;
75
+ /** Groups that have at least one visible item */
76
+ visibleGroups: Set<string>;
77
+ /** Count of visible items */
78
+ filteredCount: number;
79
+ /** Counter to trigger re-filtering when items change */
80
+ filterTrigger: number;
81
+ /** Whether virtualization mode is enabled */
82
+ virtualized: boolean;
83
+ /** Count of virtual items (from items prop) */
84
+ virtualItemsCount: number;
85
+ }
86
+ interface ListboxContext {
87
+ /** Filter function or false to disable filtering */
88
+ filter: FilterFn | false;
89
+ /** Function used to normalize search before filtering. */
90
+ normalizeSearch: SearchNormalizer;
91
+ /** Whether to loop navigation */
92
+ loop: boolean;
93
+ /**
94
+ * Controls auto-highlighting behavior when the menu opens.
95
+ * - `true`: highlight the first item (default)
96
+ * - `false`: don't auto-highlight any item
97
+ * - `string`: highlight the item with this specific value
98
+ */
99
+ autoHighlightFirst: boolean | string;
100
+ /**
101
+ * Whether to clear search on close.
102
+ * - `true`: clear immediately when menu closes (default)
103
+ * - `false`: preserve search when menu closes
104
+ * - `'after-exit'`: clear after exit animation completes (requires Surface to call clearSearch)
105
+ */
106
+ clearSearchOnClose: boolean | 'after-exit';
107
+ /** Whether hideUntilActive mode is enabled */
108
+ hideUntilActive: boolean;
109
+ /** ID for the list element (for aria-activedescendant) */
110
+ listId: string;
111
+ /** ID for the input element */
112
+ inputId: string;
113
+ /** Map of item ID to registration data */
114
+ readonly items: Map<string, ItemRegistration>;
115
+ /** Map of group ID to set of item IDs */
116
+ readonly groups: Map<string, Set<string>>;
117
+ /** Map of item ID to onSelect callback */
118
+ readonly itemSelects: Map<string, () => void>;
119
+ /** Map of submenu trigger ID to open callback */
120
+ readonly submenuOpens: Map<string, () => void>;
121
+ /** Map of submenu trigger ID to close callback */
122
+ readonly submenuCloses: Map<string, () => void>;
123
+ /** Map of shortcut key to item ID */
124
+ readonly shortcuts: Map<string, string>;
125
+ /**
126
+ * Callback when open state changes.
127
+ * The second parameter contains event details including the reason for the change.
128
+ */
129
+ onOpenChange: (open: boolean, eventDetails: PopupMenuOpenChangeEventDetails) => void;
130
+ /** Callback when search state changes */
131
+ onSearchChange: ((search: string) => void) | undefined;
132
+ /**
133
+ * Pre-registered items for virtualization.
134
+ * When provided, navigation uses this array order instead of DOM registration order.
135
+ */
136
+ virtualItems: VirtualItem[];
137
+ /**
138
+ * Consumer-provided ordered list of item values when filter={false}.
139
+ * Used to determine correct navigation/highlight order when consumer handles filtering externally.
140
+ * Must always be provided when filter={false}.
141
+ */
142
+ orderedItems: string[];
143
+ /**
144
+ * Callback when highlighted item changes.
145
+ * Useful for synchronizing with virtualizers (scrollToIndex) and other UI state.
146
+ * The third parameter contains event details including the reason for the change.
147
+ */
148
+ onHighlightChange: ((id: string | null, index: number, eventDetails: HighlightChangeEventDetails) => void) | undefined;
149
+ /**
150
+ * DOM refs for scroll behavior.
151
+ * Stored in context (not state) to avoid re-renders.
152
+ */
153
+ refs: DOMRefs;
154
+ /**
155
+ * Callback when menu close animation completes.
156
+ * Used for resetting row width measurements.
157
+ */
158
+ onCloseComplete?: () => void;
159
+ /**
160
+ * Callback when popup close transition completes.
161
+ * Used by popup-layer features that should reset only after exit animations.
162
+ */
163
+ onPopupCloseComplete?: () => void;
164
+ /**
165
+ * Last known pointer position for detecting actual pointer movement.
166
+ * Used to prevent "phantom" highlights when content shifts under a stationary pointer.
167
+ */
168
+ lastPointerPosition: {
169
+ x: number;
170
+ y: number;
171
+ } | null;
172
+ }
173
+ declare const selectors: {
174
+ open: (state: ListboxState) => boolean;
175
+ search: (state: ListboxState) => string;
176
+ normalizedSearch: (state: ListboxState) => string;
177
+ highlightedId: (state: ListboxState) => string | null;
178
+ highlightSource: (state: ListboxState) => HighlightSource;
179
+ hasInput: (state: ListboxState) => boolean;
180
+ inputActive: (state: ListboxState) => boolean;
181
+ pendingSearch: (state: ListboxState) => string;
182
+ filteredCount: (state: ListboxState) => number;
183
+ filteredItems: (state: ListboxState) => Map<string, number>;
184
+ visibleGroups: (state: ListboxState) => Set<string>;
185
+ virtualized: (state: ListboxState) => boolean;
186
+ isHighlighted: (state: ListboxState, itemId: string) => boolean;
187
+ isGroupVisible: (state: ListboxState, groupId: string) => boolean;
188
+ getItemScore: (state: ListboxState, itemId: string) => number;
189
+ hasSearchWithNoResults: (state: ListboxState) => boolean;
190
+ };
191
+ /**
192
+ * Core store for listbox-like components.
193
+ * Handles item registration, filtering, navigation, and highlight state.
194
+ *
195
+ * Used by: DropdownMenu, ContextMenu, Select, CommandMenu
196
+ */
197
+ declare class ListboxStore extends ReactStore<ListboxState, ListboxContext, typeof selectors> {
198
+ constructor(initialState?: Partial<ListboxState>, context?: Partial<ListboxContext>);
199
+ /**
200
+ * Set the open state with event details.
201
+ *
202
+ * @param open - The new open state
203
+ * @param reason - The reason for the state change (default: 'none')
204
+ * @param event - The native DOM event that triggered the change (optional)
205
+ */
206
+ setOpen(open: boolean, reason?: PopupMenuOpenChangeReason, event?: Event): void;
207
+ setSearch(search: string): void;
208
+ setSearchNormalizer(normalizeSearch: SearchNormalizer): void;
209
+ setHighlightedId(id: string | null, cause?: HighlightSource): void;
210
+ /**
211
+ * Notify listeners about highlight changes.
212
+ * Called whenever highlightedId changes, regardless of virtualization or DOM state.
213
+ * Useful for virtualization scroll sync, analytics, or any other tracking needs.
214
+ *
215
+ * @param id - The newly highlighted item ID (or null if cleared)
216
+ * @param cause - What caused the highlight change
217
+ */
218
+ private notifyHighlightChange;
219
+ /**
220
+ * Scroll the highlighted item into view.
221
+ * Uses native scrollIntoView if the element is in the DOM.
222
+ * For virtualized lists, the onHighlightChange callback (called from setHighlightedId)
223
+ * should handle scrolling via the virtualizer.
224
+ *
225
+ * @param id - The item ID to scroll into view
226
+ */
227
+ private scrollItemIntoView;
228
+ setHasInput(hasInput: boolean): void;
229
+ setInputActive(active: boolean): void;
230
+ setPendingSearch(search: string): void;
231
+ setHideUntilActive(enabled: boolean): void;
232
+ setVirtualized(virtualized: boolean): void;
233
+ setVirtualItems(items: VirtualItem[]): void;
234
+ /**
235
+ * Set the consumer-provided ordered items.
236
+ * Used when filter={false} and consumer controls item order/visibility.
237
+ * Must always be provided when filter={false}.
238
+ *
239
+ * @param items - Array of item IDs in display order
240
+ */
241
+ setOrderedItems(items: string[], options?: SetOrderedItemsOptions): void;
242
+ /**
243
+ * Try to auto-highlight when an item registers.
244
+ * This handles the case where orderedItems was set before items mounted.
245
+ * Only highlights if:
246
+ * - filter={false} (using orderedItems)
247
+ * - Menu is open
248
+ * - No item is currently highlighted
249
+ * - autoHighlightFirst is enabled
250
+ * - The registering item is the first in orderedItems
251
+ */
252
+ private maybeAutoHighlightOnRegister;
253
+ setOnHighlightChange(callback: ((id: string | null, index: number, eventDetails: HighlightChangeEventDetails) => void) | undefined): void;
254
+ /**
255
+ * Set the list element ref for scroll container detection.
256
+ */
257
+ setListRef(ref: React.RefObject<HTMLElement | null>): void;
258
+ /**
259
+ * Register an item's DOM ref for scrollIntoView behavior.
260
+ * Returns a cleanup function.
261
+ */
262
+ registerItemRef(id: string, ref: React.RefObject<HTMLElement | null>): () => void;
263
+ /**
264
+ * Check if pointer has moved and should allow highlight.
265
+ * This prevents "phantom" highlights when content shifts under a stationary pointer
266
+ * (e.g., when search results change or menu items reorder).
267
+ *
268
+ * @param x - Current pointer X position
269
+ * @param y - Current pointer Y position
270
+ * @returns true if pointer has actually moved and highlight should be allowed
271
+ */
272
+ shouldAllowPointerHighlight(x: number, y: number): boolean;
273
+ /**
274
+ * Reset pointer position tracking.
275
+ * Call this when the menu opens or content changes significantly.
276
+ */
277
+ resetPointerPosition(): void;
278
+ /**
279
+ * Pre-register virtual items so they appear in filteredItems.
280
+ * This allows filtering to work for items that aren't mounted yet.
281
+ */
282
+ private preRegisterVirtualItems;
283
+ registerItem(id: string, registration: ItemRegistration): () => void;
284
+ registerGroup(id: string): () => void;
285
+ registerItemSelect(id: string, onSelect: (() => void) | undefined): () => void;
286
+ registerSubmenuOpen(id: string, onOpen: (() => void) | undefined): () => void;
287
+ registerSubmenuClose(id: string, onClose: (() => void) | undefined): () => void;
288
+ /**
289
+ * Close all submenus except the one with the given ID.
290
+ * Used when hovering over a new submenu trigger to close sibling submenus.
291
+ */
292
+ closeSiblingSubmenus(exceptId: string | null): void;
293
+ highlightNext(): void;
294
+ highlightPrev(): void;
295
+ selectHighlighted(): void;
296
+ /**
297
+ * Select an item by its keyboard shortcut.
298
+ * Returns true if an item was found and selected, false otherwise.
299
+ */
300
+ selectByShortcut(key: string): boolean;
301
+ openSubmenuForHighlighted(): void;
302
+ isHighlightedSubmenuTrigger(): boolean;
303
+ /**
304
+ * Get the item registration for the highlighted item.
305
+ * Returns undefined if no item is highlighted.
306
+ */
307
+ getHighlightedItem(): ItemRegistration | undefined;
308
+ clearSearch(): void;
309
+ highlightFirstItem(): void;
310
+ /**
311
+ * Apply auto-highlight based on the current context.autoHighlightFirst value.
312
+ * Called by Surface after updating the context to ensure correct value is used.
313
+ */
314
+ applyAutoHighlight(): void;
315
+ /**
316
+ * Highlight a specific item by its value.
317
+ * If the item is not visible or doesn't exist, falls back to highlighting the first item.
318
+ * Scrolls the highlighted item into view.
319
+ */
320
+ highlightItemByValue(value: string): void;
321
+ /**
322
+ * Returns whether filtering is disabled (consumer handles filtering externally).
323
+ */
324
+ isFilterDisabled(): boolean;
325
+ getVisibleItemIds(): string[];
326
+ /**
327
+ * Get the index of an item in the visible items list.
328
+ * Returns -1 if the item is not found or not visible.
329
+ */
330
+ getVisibleItemIndex(id: string): number;
331
+ /**
332
+ * Get the index of an item in the virtualItems array.
333
+ * This is used for virtualizer scrollToIndex which needs the raw array index,
334
+ * not the filtered/visible index.
335
+ * Returns -1 if not found or not in virtualized mode.
336
+ */
337
+ getVirtualItemIndex(value: string): number;
338
+ /**
339
+ * Validates and updates the highlighted item.
340
+ * This is the single source of truth for highlight management.
341
+ *
342
+ * @param options.forceFirst - Force highlight first item even if current is valid
343
+ * @param options.filteredItems - Use this map instead of state (for mid-update calls)
344
+ * @param options.newSearch - The search query for filteredItems (to detect search cleared)
345
+ */
346
+ private validateHighlight;
347
+ private recomputeFilteredItems;
348
+ static useStore(externalStore: ListboxStore | undefined, initialState?: Partial<ListboxState>, context?: Partial<ListboxContext>): ListboxStore;
349
+ }
350
+
351
+ export { type DOMRefs as D, type FilterFn as F, type HighlightSource as H, type ItemRegistration as I, type ListboxContext as L, type SearchNormalizer as S, type VirtualItem as V, type ListboxState as a, ListboxStore as b };
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }require('../chunk-M4G6J7DP.cjs');var _jsxruntime = require('react/jsx-runtime');function D(e){return e==null?null:e instanceof Error?e:new Error(String(e))}function g(e){let o=D(e.error),a=e.data!==void 0,n=e.isPaused?"paused":e.isValidating?"fetching":"idle",r=n==="fetching",t=_nullishCoalesce(e.isLoading, () => ((r&&!a&&o==null))),c=r&&!t,s=o?"error":a?"success":t||r?"pending":"idle",i=t?"initial":c?"background":"none";return{data:e.data,raw:e,source:"swr",error:o,status:s,fetchStatus:n,loadingPhase:i,isLoading:t,isFetching:r,isInitialLoading:t,isRefetching:c,isPending:s==="pending",isSuccess:s==="success",isError:s==="error",isPaused:n==="paused",hasData:a,hasFetched:a||o!=null||t||c,refetch:()=>e.mutate()}}function A(e){let{useSWR:o,loadStrategy:a}=e;return{type:"static",Loader:({children:r})=>{let t=o();return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:r(g(t))})},loadStrategy:a}}function T(e){let{useSWR:o,minQueryLength:a=1,initialQueryBehavior:n,initialQuery:r,loadStrategy:t,belowMinBehavior:c="empty",placeholderNodes:s}=e,i=n!==void 0?n:r!==void 0?{value:r,loadWhen:"needed"}:{value:"",loadWhen:"needed"};return{type:"query",Loader:({query:l,enabled:h,children:f})=>{let y=_nullishCoalesce(h, () => ((l.length>=a||i!==!1))),p=o(l,{enabled:y});return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:f(g(p))})},minQueryLength:a,initialQueryBehavior:i,initialQuery:r,loadStrategy:t,belowMinBehavior:c,placeholderNodes:s}}function E(e){return function({query:a,children:n}){let r=e(a);return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:n(g(r))})}}function v(e){return e==null?null:e instanceof Error?e:new Error(String(e))}function L(e){let o=e.data!==void 0,a=e.fetchStatus?e.fetchStatus:e.isPaused?"paused":e.isFetching||e.isLoading?"fetching":"idle",n=a==="fetching",r=e.status?e.status:e.isError?"error":e.isSuccess||o?"success":e.isPending||e.isLoading||n?"pending":"idle",t=_nullishCoalesce(e.isPending, () => (r==="pending")),c=_nullishCoalesce(e.isSuccess, () => (r==="success")),s=_nullishCoalesce(e.isError, () => (r==="error")),i=_nullishCoalesce(e.isLoading, () => ((t&&n))),u=_nullishCoalesce(e.isRefetching, () => ((n&&!i))),l=_nullishCoalesce(e.isPaused, () => (a==="paused")),h=_nullishCoalesce(e.isFetched, () => ((c||s||i||u))),f=i?"initial":u?"background":"none";return{data:e.data,raw:e,source:"tanstack-query",error:v(e.error),status:r,fetchStatus:a,loadingPhase:f,isLoading:i,isFetching:n,isInitialLoading:i,isRefetching:u,isPending:t,isSuccess:c,isError:s,isPaused:l,hasData:o,hasFetched:h,refetch:e.refetch}}function W(e){let{useQuery:o,loadStrategy:a}=e;return{type:"static",Loader:({children:r})=>{let t=o();return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:r(L(t))})},loadStrategy:a}}function B(e){let{useQuery:o,minQueryLength:a=1,initialQueryBehavior:n,initialQuery:r,loadStrategy:t,belowMinBehavior:c="empty",placeholderNodes:s}=e,i=n!==void 0?n:r!==void 0?{value:r,loadWhen:"needed"}:{value:"",loadWhen:"needed"};return{type:"query",Loader:({query:l,enabled:h,children:f})=>{let y=_nullishCoalesce(h, () => ((l.length>=a||i!==!1))),p=o(l,{enabled:y});return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:f(L(p))})},minQueryLength:a,initialQueryBehavior:i,initialQuery:r,loadStrategy:t,belowMinBehavior:c,placeholderNodes:s}}function N(e){return function({query:a,children:n}){let r=e(a);return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:n(L(r))})}}var _react = require('react'); var d = _interopRequireWildcard(_react);function m(e){return e==null?null:e instanceof Error?e:new Error(String(e))}function k(e){return e.error?"error":e.data!==void 0?"success":e.isFetching?"pending":"idle"}function C(e,o){let a=k(e),n=e.isFetching?"fetching":"idle",r=e.isFetching&&!e.hasFetched,t=e.isFetching&&e.hasFetched,c=r?"initial":t?"background":"none";return{data:e.data,source:"vanilla",error:e.error,status:a,fetchStatus:n,loadingPhase:c,isLoading:r,isFetching:e.isFetching,isInitialLoading:r,isRefetching:t,isPending:a==="pending",isSuccess:a==="success",isError:a==="error",isPaused:!1,hasData:e.data!==void 0,hasFetched:e.hasFetched,refetch:o}}function w(e,o){let{enabled:a=!0}=_nullishCoalesce(o, () => ({})),[n,r]=d.useState(()=>({data:void 0,error:null,isFetching:a,hasFetched:!1})),t=d.useRef(e);t.current=e;let c=d.useCallback(()=>{r(s=>({...s,isFetching:!0,error:null})),t.current().then(s=>{r({data:s,error:null,isFetching:!1,hasFetched:!0})}).catch(s=>{r(i=>({...i,error:m(s),isFetching:!1,hasFetched:!0}))})},[]);return d.useEffect(()=>{if(a){c();return}r(s=>({...s,isFetching:!1}))},[a,c]),d.useMemo(()=>C(n,c),[n,c])}function I(e,o,a){let{enabled:n=!0}=_nullishCoalesce(a, () => ({})),[r,t]=d.useState(()=>({data:void 0,error:null,isFetching:n,hasFetched:!1})),c=d.useRef(e);c.current=e,d.useEffect(()=>{if(!n){t({data:void 0,error:null,isFetching:!1,hasFetched:!1});return}let i=new AbortController;return t({data:void 0,error:null,isFetching:!0,hasFetched:!1}),c.current(o,{signal:i.signal}).then(u=>{i.signal.aborted||t({data:u,error:null,isFetching:!1,hasFetched:!0})}).catch(u=>{i.signal.aborted||t({data:void 0,error:m(u),isFetching:!1,hasFetched:!0})}),()=>{i.abort()}},[n,o]);let s=d.useCallback(()=>{t(i=>({...i,isFetching:!0,error:null})),c.current(o).then(i=>{t({data:i,error:null,isFetching:!1,hasFetched:!0})}).catch(i=>{t(u=>({...u,error:m(i),isFetching:!1,hasFetched:!0}))})},[o]);return d.useMemo(()=>C(r,s),[r,s])}function V(e){let{fetcher:o,loadStrategy:a}=e;return{type:"static",Loader:({children:r})=>{let t=w(o);return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:r(t)})},loadStrategy:a}}function x(e){let{fetcher:o,minQueryLength:a=1,initialQueryBehavior:n,initialQuery:r,loadStrategy:t,belowMinBehavior:c="empty",placeholderNodes:s}=e,i=n!==void 0?n:r!==void 0?{value:r,loadWhen:"needed"}:{value:"",loadWhen:"needed"};return{type:"query",Loader:({query:l,enabled:h,children:f})=>{let y=_nullishCoalesce(h, () => ((l.length>=a||i!==!1))),p=I(o,l,{enabled:y});return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:f(p)})},minQueryLength:a,initialQueryBehavior:i,initialQuery:r,loadStrategy:t,belowMinBehavior:c,placeholderNodes:s}}exports.createLoaderComponent = N; exports.createQueryLoader = B; exports.createSWRLoaderComponent = E; exports.createSWRQueryLoader = T; exports.createSWRStaticLoader = A; exports.createStaticLoader = W; exports.createVanillaQueryLoader = x; exports.createVanillaStaticLoader = V; exports.toAsyncLoaderResult = L; exports.toAsyncLoaderResultFromSWR = g;
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/ui/ui/packages/react/dist/adapters/index.cjs","../../src/adapters/swr.tsx","../../src/adapters/tanstack-query.tsx","../../src/adapters/vanilla.tsx"],"names":["toError","error","toAsyncLoaderResultFromSWR","result","normalizedError","hasData","fetchStatus","isFetching","isInitialLoading","isRefetching","status","loadingPhase","createSWRStaticLoader","props","useSWR","loadStrategy","children","jsx","Fragment","createSWRQueryLoader","minQueryLength","initialQueryBehavior","initialQuery","belowMinBehavior","placeholderNodes","resolvedInitialQueryBehavior","query","enabled","isEnabled","createSWRLoaderComponent","useSWRFn","toAsyncLoaderResult","isPending","isSuccess","isError","isPaused","hasFetched","createStaticLoader","useQuery","createQueryLoader","createLoaderComponent","useQueryFn","normalizeError","getVanillaStatus","state","toVanillaAsyncLoaderResult","refetch","useAsyncState","fetcher","options","setState","fetcherRef","data","s","useAsyncQueryState","controller","createVanillaStaticLoader","createVanillaQueryLoader"],"mappings":"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","file":"/home/runner/work/ui/ui/packages/react/dist/adapters/index.cjs","sourcesContent":[null,"'use client'\n\nimport type * as React from 'react'\nimport type {\n AsyncLoaderFetchStatus,\n AsyncLoaderLoadingPhase,\n AsyncLoaderResult,\n AsyncLoaderStatus,\n InitialQueryBehavior,\n LoaderComponentProps,\n NodeDef,\n QueryDependentLoaderConfig,\n StaticLoaderConfig,\n} from '../internal/popup-menu/deep-search/types.js'\n\n// ============================================================================\n// SWR Adapter\n// ============================================================================\n\n/**\n * SWR result shape (subset of SWRResponse).\n * This allows the adapter to work without requiring `swr` as a dependency.\n */\nexport interface SWRResult<TData, TError = Error> {\n data: TData | undefined\n error: TError | undefined\n isLoading?: boolean\n isValidating: boolean\n isPaused?: boolean\n mutate: (...args: unknown[]) => unknown\n}\n\nfunction toError(error: unknown): Error | null {\n if (error == null) {\n return null\n }\n\n if (error instanceof Error) {\n return error\n }\n\n return new Error(String(error))\n}\n\n/**\n * Converts an SWR result to an AsyncLoaderResult.\n */\nexport function toAsyncLoaderResultFromSWR<TData, TError = Error>(\n result: SWRResult<TData, TError>,\n): AsyncLoaderResult<TData, SWRResult<TData, TError>> {\n const normalizedError = toError(result.error)\n const hasData = result.data !== undefined\n\n const fetchStatus: AsyncLoaderFetchStatus = result.isPaused\n ? 'paused'\n : result.isValidating\n ? 'fetching'\n : 'idle'\n\n const isFetching = fetchStatus === 'fetching'\n const isInitialLoading =\n result.isLoading ?? (isFetching && !hasData && normalizedError == null)\n const isRefetching = isFetching && !isInitialLoading\n\n const status: AsyncLoaderStatus = normalizedError\n ? 'error'\n : hasData\n ? 'success'\n : isInitialLoading || isFetching\n ? 'pending'\n : 'idle'\n\n const loadingPhase: AsyncLoaderLoadingPhase = isInitialLoading\n ? 'initial'\n : isRefetching\n ? 'background'\n : 'none'\n\n return {\n data: result.data,\n raw: result,\n source: 'swr',\n error: normalizedError,\n status,\n fetchStatus,\n loadingPhase,\n isLoading: isInitialLoading,\n isFetching,\n isInitialLoading,\n isRefetching,\n isPending: status === 'pending',\n isSuccess: status === 'success',\n isError: status === 'error',\n isPaused: fetchStatus === 'paused',\n hasData,\n hasFetched:\n hasData || normalizedError != null || isInitialLoading || isRefetching,\n refetch: () => result.mutate(),\n }\n}\n\n/**\n * Props for creating a static SWR loader component.\n */\nexport interface CreateSWRStaticLoaderProps {\n /** Hook that returns an SWR result. */\n useSWR: () => SWRResult<NodeDef[]>\n\n /**\n * When to trigger the loader:\n * - 'eager': Load when root menu opens\n * - 'lazy': Load when submenu opens (default)\n */\n loadStrategy?: 'eager' | 'lazy'\n}\n\n/**\n * Creates a static loader configuration backed by SWR.\n */\nexport function createSWRStaticLoader(\n props: CreateSWRStaticLoaderProps,\n): StaticLoaderConfig {\n const { useSWR, loadStrategy } = props\n\n const Loader: React.FC<LoaderComponentProps> = ({ children }) => {\n const result = useSWR()\n return <>{children(toAsyncLoaderResultFromSWR(result))}</>\n }\n\n return {\n type: 'static',\n Loader,\n loadStrategy,\n }\n}\n\n/**\n * Props for creating a query-dependent SWR loader component.\n */\nexport interface CreateSWRQueryLoaderProps {\n /**\n * Hook that returns an SWR result based on the search query.\n * `options.enabled` can be used to derive a `null` key and disable fetching.\n */\n useSWR: (\n query: string,\n options?: { enabled: boolean },\n ) => SWRResult<NodeDef[]>\n /**\n * Minimum query length before fetching.\n * @default 1\n */\n minQueryLength?: number\n /**\n * Initial query behavior before user input reaches minQueryLength.\n * Defaults to fetching with an empty query.\n */\n initialQueryBehavior?: InitialQueryBehavior | false\n /**\n * @deprecated Use `initialQueryBehavior` instead.\n */\n initialQuery?: string\n /**\n * When to trigger the loader:\n * - 'eager': Load when root menu opens (good for deep search)\n * - 'lazy': Load when submenu opens (default)\n * @default 'lazy'\n */\n loadStrategy?: 'eager' | 'lazy'\n /**\n * What to show when query is below minQueryLength.\n * @default 'empty'\n */\n belowMinBehavior?: 'empty' | 'placeholder'\n /**\n * Placeholder nodes shown when query is below minQueryLength.\n */\n placeholderNodes?: NodeDef[]\n}\n\n/**\n * Creates a query-dependent loader configuration backed by SWR.\n */\nexport function createSWRQueryLoader(\n props: CreateSWRQueryLoaderProps,\n): QueryDependentLoaderConfig {\n const {\n useSWR,\n minQueryLength = 1,\n initialQueryBehavior,\n initialQuery,\n loadStrategy,\n belowMinBehavior = 'empty',\n placeholderNodes,\n } = props\n\n const resolvedInitialQueryBehavior: InitialQueryBehavior | false =\n initialQueryBehavior !== undefined\n ? initialQueryBehavior\n : initialQuery !== undefined\n ? { value: initialQuery, loadWhen: 'needed' }\n : { value: '', loadWhen: 'needed' }\n\n const Loader: React.FC<LoaderComponentProps> = ({\n query,\n enabled,\n children,\n }) => {\n const isEnabled =\n enabled ??\n (query.length >= minQueryLength || resolvedInitialQueryBehavior !== false)\n const result = useSWR(query, { enabled: isEnabled })\n return <>{children(toAsyncLoaderResultFromSWR(result))}</>\n }\n\n return {\n type: 'query',\n Loader,\n minQueryLength,\n initialQueryBehavior: resolvedInitialQueryBehavior,\n initialQuery,\n loadStrategy,\n belowMinBehavior,\n placeholderNodes,\n }\n}\n\n/**\n * Creates a loader component that wraps an SWR hook.\n */\nexport function createSWRLoaderComponent(\n useSWRFn: (query: string) => SWRResult<NodeDef[]>,\n): React.FC<LoaderComponentProps> {\n return function SWRLoader({ query, children }) {\n const result = useSWRFn(query)\n return <>{children(toAsyncLoaderResultFromSWR(result))}</>\n }\n}\n","'use client'\n\nimport type * as React from 'react'\nimport type {\n AsyncLoaderFetchStatus,\n AsyncLoaderLoadingPhase,\n AsyncLoaderResult,\n AsyncLoaderStatus,\n InitialQueryBehavior,\n LoaderComponentProps,\n NodeDef,\n QueryDependentLoaderConfig,\n StaticLoaderConfig,\n} from '../internal/popup-menu/deep-search/types.js'\n\n// ============================================================================\n// TanStack Query Adapter\n// ============================================================================\n\n/**\n * TanStack Query result shape (subset of UseQueryResult).\n * This allows the adapter to work without requiring @tanstack/react-query as a dependency.\n */\nexport interface TanStackQueryResult<TData, TError = Error> {\n /** TanStack status (`pending` | `error` | `success`) */\n status?: 'pending' | 'error' | 'success'\n\n /** TanStack fetch status (`fetching` | `paused` | `idle`) */\n fetchStatus?: 'fetching' | 'paused' | 'idle'\n\n data: TData | undefined\n error: TError | null | undefined\n\n /** v5: true when first fetch is in-flight */\n isLoading?: boolean\n\n /** v5: true when status is pending */\n isPending?: boolean\n\n /** true when status is success */\n isSuccess?: boolean\n\n /** true when status is error */\n isError?: boolean\n\n /** true while any fetch is in-flight */\n isFetching?: boolean\n\n /** true while background refetch is in-flight */\n isRefetching?: boolean\n\n /** true when fetch is paused */\n isPaused?: boolean\n\n /** true once query has fetched at least once */\n isFetched?: boolean\n\n refetch: () => unknown\n}\n\nfunction toError(error: unknown): Error | null {\n if (error == null) {\n return null\n }\n\n if (error instanceof Error) {\n return error\n }\n\n return new Error(String(error))\n}\n\n/**\n * Converts a TanStack Query result to an AsyncLoaderResult.\n * Use this to wrap your useQuery hook result.\n *\n * @example\n * ```tsx\n * function MyLoader({ query, children }) {\n * const result = useQuery({\n * queryKey: ['items', query],\n * queryFn: () => fetchItems(query),\n * })\n * return children(toAsyncLoaderResult(result))\n * }\n * ```\n */\nexport function toAsyncLoaderResult<TData, TError = Error>(\n result: TanStackQueryResult<TData, TError>,\n): AsyncLoaderResult<TData, TanStackQueryResult<TData, TError>> {\n const hasData = result.data !== undefined\n\n const fetchStatus: AsyncLoaderFetchStatus = result.fetchStatus\n ? result.fetchStatus\n : result.isPaused\n ? 'paused'\n : result.isFetching || result.isLoading\n ? 'fetching'\n : 'idle'\n\n const isFetching = fetchStatus === 'fetching'\n\n const status: AsyncLoaderStatus = result.status\n ? result.status\n : result.isError\n ? 'error'\n : result.isSuccess || hasData\n ? 'success'\n : result.isPending || result.isLoading || isFetching\n ? 'pending'\n : 'idle'\n\n const isPending = result.isPending ?? status === 'pending'\n const isSuccess = result.isSuccess ?? status === 'success'\n const isError = result.isError ?? status === 'error'\n const isInitialLoading = result.isLoading ?? (isPending && isFetching)\n const isRefetching = result.isRefetching ?? (isFetching && !isInitialLoading)\n const isPaused = result.isPaused ?? fetchStatus === 'paused'\n const hasFetched =\n result.isFetched ??\n (isSuccess || isError || isInitialLoading || isRefetching)\n\n const loadingPhase: AsyncLoaderLoadingPhase = isInitialLoading\n ? 'initial'\n : isRefetching\n ? 'background'\n : 'none'\n\n return {\n data: result.data,\n raw: result,\n source: 'tanstack-query',\n error: toError(result.error),\n status,\n fetchStatus,\n loadingPhase,\n isLoading: isInitialLoading,\n isFetching,\n isInitialLoading,\n isRefetching,\n isPending,\n isSuccess,\n isError,\n isPaused,\n hasData,\n hasFetched,\n refetch: result.refetch,\n }\n}\n\n/**\n * Props for creating a static loader component.\n */\nexport interface CreateStaticLoaderProps {\n /**\n * Hook that returns a TanStack Query result.\n * This hook will be called inside the loader component.\n */\n useQuery: () => TanStackQueryResult<NodeDef[]>\n\n /**\n * When to trigger the loader:\n * - 'eager': Load when root menu opens\n * - 'lazy': Load when submenu opens (default)\n */\n loadStrategy?: 'eager' | 'lazy'\n}\n\n/**\n * Creates a static loader configuration for use with async menus.\n * The hook is called inside a component, so it follows React's rules of hooks.\n *\n * @example\n * ```tsx\n * const recentFilesLoader = createStaticLoader({\n * useQuery: () => useQuery({\n * queryKey: ['recent-files'],\n * queryFn: fetchRecentFiles,\n * staleTime: 5 * 60 * 1000,\n * }),\n * })\n *\n * // Use in submenu\n * {\n * kind: 'submenu',\n * value: 'Recent Files',\n * asyncNodes: {\n * ...recentFilesLoader,\n * loadStrategy: 'eager',\n * },\n * render: ...\n * }\n * ```\n */\nexport function createStaticLoader(\n props: CreateStaticLoaderProps,\n): StaticLoaderConfig {\n const { useQuery, loadStrategy } = props\n\n const Loader: React.FC<LoaderComponentProps> = ({ children }) => {\n const result = useQuery()\n return <>{children(toAsyncLoaderResult(result))}</>\n }\n\n return {\n type: 'static',\n Loader,\n loadStrategy,\n }\n}\n\n/**\n * Props for creating a query-dependent loader component.\n */\nexport interface CreateQueryLoaderProps {\n /**\n * Hook that returns a TanStack Query result based on the search query.\n * This hook will be called inside the loader component with the current query.\n */\n useQuery: (\n query: string,\n options?: { enabled: boolean },\n ) => TanStackQueryResult<NodeDef[]>\n /**\n * Minimum query length before fetching.\n * @default 1\n */\n minQueryLength?: number\n /**\n * Initial query behavior before user input reaches minQueryLength.\n * Defaults to fetching with an empty query.\n */\n initialQueryBehavior?: InitialQueryBehavior | false\n /**\n * @deprecated Use `initialQueryBehavior` instead.\n */\n initialQuery?: string\n /**\n * When to trigger the loader:\n * - 'eager': Load when root menu opens (good for deep search)\n * - 'lazy': Load when submenu opens (default)\n * @default 'lazy'\n */\n loadStrategy?: 'eager' | 'lazy'\n /**\n * What to show when query is below minQueryLength.\n * @default 'empty'\n */\n belowMinBehavior?: 'empty' | 'placeholder'\n /**\n * Placeholder nodes shown when query is below minQueryLength.\n */\n placeholderNodes?: NodeDef[]\n}\n\n/**\n * Creates a query-dependent loader configuration for use with async menus.\n * The loader will re-fetch when the search query changes.\n *\n * @example\n * ```tsx\n * const searchLoader = createQueryLoader({\n * useQuery: (query, options) => useQuery({\n * queryKey: ['search', query],\n * queryFn: () => searchItems(query),\n * enabled: options?.enabled,\n * }),\n * minQueryLength: 2,\n * })\n *\n * // Use in submenu\n * {\n * kind: 'submenu',\n * value: 'Search',\n * includeInDeepSearch: true,\n * asyncNodes: searchLoader,\n * render: ...\n * }\n * ```\n */\nexport function createQueryLoader(\n props: CreateQueryLoaderProps,\n): QueryDependentLoaderConfig {\n const {\n useQuery,\n minQueryLength = 1,\n initialQueryBehavior,\n initialQuery,\n loadStrategy,\n belowMinBehavior = 'empty',\n placeholderNodes,\n } = props\n\n const resolvedInitialQueryBehavior: InitialQueryBehavior | false =\n initialQueryBehavior !== undefined\n ? initialQueryBehavior\n : initialQuery !== undefined\n ? { value: initialQuery, loadWhen: 'needed' }\n : { value: '', loadWhen: 'needed' }\n\n const Loader: React.FC<LoaderComponentProps> = ({\n query,\n enabled,\n children,\n }) => {\n const isEnabled =\n enabled ??\n (query.length >= minQueryLength || resolvedInitialQueryBehavior !== false)\n const result = useQuery(query, { enabled: isEnabled })\n return <>{children(toAsyncLoaderResult(result))}</>\n }\n\n return {\n type: 'query',\n Loader,\n minQueryLength,\n initialQueryBehavior: resolvedInitialQueryBehavior,\n initialQuery,\n loadStrategy,\n belowMinBehavior,\n placeholderNodes,\n }\n}\n\n/**\n * Creates a loader component that wraps a TanStack Query hook.\n * This is a lower-level utility for custom loader implementations.\n *\n * @example\n * ```tsx\n * const MyLoader = createLoaderComponent((query) =>\n * useQuery({\n * queryKey: ['items', query],\n * queryFn: () => fetchItems(query),\n * })\n * )\n * ```\n */\nexport function createLoaderComponent(\n useQueryFn: (query: string) => TanStackQueryResult<NodeDef[]>,\n): React.FC<LoaderComponentProps> {\n return function TanStackLoader({ query, children }) {\n const result = useQueryFn(query)\n return <>{children(toAsyncLoaderResult(result))}</>\n }\n}\n","'use client'\n\nimport * as React from 'react'\nimport type {\n AsyncLoaderFetchStatus,\n AsyncLoaderLoadingPhase,\n AsyncLoaderResult,\n AsyncLoaderStatus,\n InitialQueryBehavior,\n LoaderComponentProps,\n NodeDef,\n QueryDependentLoaderConfig,\n StaticLoaderConfig,\n} from '../internal/popup-menu/deep-search/types.js'\n\n// ============================================================================\n// Vanilla Async Adapter (no external dependencies)\n// ============================================================================\n\ninterface VanillaAsyncInternalState<TData> {\n data: TData | undefined\n error: Error | null\n isFetching: boolean\n hasFetched: boolean\n}\n\nfunction normalizeError(error: unknown): Error | null {\n if (error == null) {\n return null\n }\n\n if (error instanceof Error) {\n return error\n }\n\n return new Error(String(error))\n}\n\nfunction getVanillaStatus<TData>(\n state: VanillaAsyncInternalState<TData>,\n): AsyncLoaderStatus {\n if (state.error) {\n return 'error'\n }\n\n if (state.data !== undefined) {\n return 'success'\n }\n\n if (state.isFetching) {\n return 'pending'\n }\n\n return 'idle'\n}\n\nfunction toVanillaAsyncLoaderResult<TData>(\n state: VanillaAsyncInternalState<TData>,\n refetch: () => unknown,\n): AsyncLoaderResult<TData> {\n const status = getVanillaStatus(state)\n const fetchStatus: AsyncLoaderFetchStatus = state.isFetching\n ? 'fetching'\n : 'idle'\n\n const isInitialLoading = state.isFetching && !state.hasFetched\n const isRefetching = state.isFetching && state.hasFetched\n\n const loadingPhase: AsyncLoaderLoadingPhase = isInitialLoading\n ? 'initial'\n : isRefetching\n ? 'background'\n : 'none'\n\n return {\n data: state.data,\n source: 'vanilla',\n error: state.error,\n status,\n fetchStatus,\n loadingPhase,\n isLoading: isInitialLoading,\n isFetching: state.isFetching,\n isInitialLoading,\n isRefetching,\n isPending: status === 'pending',\n isSuccess: status === 'success',\n isError: status === 'error',\n isPaused: false,\n hasData: state.data !== undefined,\n hasFetched: state.hasFetched,\n refetch,\n }\n}\n\n/**\n * Internal hook for managing async state with plain promises.\n * Use this when you don't have TanStack Query or SWR.\n */\nfunction useAsyncState<T>(\n fetcher: () => Promise<T>,\n options?: { enabled?: boolean },\n): AsyncLoaderResult<T> {\n const { enabled = true } = options ?? {}\n const [state, setState] = React.useState<VanillaAsyncInternalState<T>>(\n () => ({\n data: undefined,\n error: null,\n isFetching: enabled,\n hasFetched: false,\n }),\n )\n\n const fetcherRef = React.useRef(fetcher)\n fetcherRef.current = fetcher\n\n const refetch = React.useCallback(() => {\n setState((s) => ({ ...s, isFetching: true, error: null }))\n fetcherRef\n .current()\n .then((data) => {\n setState({\n data,\n error: null,\n isFetching: false,\n hasFetched: true,\n })\n })\n .catch((error) => {\n setState((s) => ({\n ...s,\n error: normalizeError(error),\n isFetching: false,\n hasFetched: true,\n }))\n })\n }, [])\n\n React.useEffect(() => {\n if (enabled) {\n refetch()\n return\n }\n\n setState((s) => ({\n ...s,\n isFetching: false,\n }))\n }, [enabled, refetch])\n\n return React.useMemo(\n () => toVanillaAsyncLoaderResult(state, refetch),\n [state, refetch],\n )\n}\n\n/**\n * Internal hook for managing query-dependent async state with plain promises.\n * Unlike `useAsyncState`, this hook re-fetches whenever the query changes.\n * Aborts in-flight requests when a new query is issued or the component unmounts.\n */\nfunction useAsyncQueryState(\n fetcher: (\n query: string,\n options?: { signal?: AbortSignal },\n ) => Promise<NodeDef[]>,\n query: string,\n options?: { enabled?: boolean },\n): AsyncLoaderResult<NodeDef[]> {\n const { enabled = true } = options ?? {}\n const [state, setState] = React.useState<\n VanillaAsyncInternalState<NodeDef[]>\n >(() => ({\n data: undefined,\n error: null,\n isFetching: enabled,\n hasFetched: false,\n }))\n\n const fetcherRef = React.useRef(fetcher)\n fetcherRef.current = fetcher\n\n React.useEffect(() => {\n if (!enabled) {\n setState({\n data: undefined,\n error: null,\n isFetching: false,\n hasFetched: false,\n })\n return\n }\n\n const controller = new AbortController()\n\n setState({\n data: undefined,\n error: null,\n isFetching: true,\n hasFetched: false,\n })\n\n fetcherRef\n .current(query, { signal: controller.signal })\n .then((data) => {\n if (!controller.signal.aborted) {\n setState({\n data,\n error: null,\n isFetching: false,\n hasFetched: true,\n })\n }\n })\n .catch((error) => {\n if (!controller.signal.aborted) {\n setState({\n data: undefined,\n error: normalizeError(error),\n isFetching: false,\n hasFetched: true,\n })\n }\n })\n\n return () => {\n controller.abort()\n }\n }, [enabled, query])\n\n const refetch = React.useCallback(() => {\n // Trigger re-run by toggling a state-based effect isn't ideal here,\n // so we do a manual fetch that respects the current query/enabled state.\n setState((s) => ({\n ...s,\n isFetching: true,\n error: null,\n }))\n fetcherRef\n .current(query)\n .then((data) => {\n setState({\n data,\n error: null,\n isFetching: false,\n hasFetched: true,\n })\n })\n .catch((error) => {\n setState((s) => ({\n ...s,\n error: normalizeError(error),\n isFetching: false,\n hasFetched: true,\n }))\n })\n }, [query])\n\n return React.useMemo(\n () => toVanillaAsyncLoaderResult(state, refetch),\n [state, refetch],\n )\n}\n\n/**\n * Props for creating a static loader with vanilla fetch.\n */\nexport interface CreateVanillaStaticLoaderProps {\n /**\n * Async function that fetches the menu items.\n */\n fetcher: () => Promise<NodeDef[]>\n\n /**\n * When to trigger the loader:\n * - 'eager': Load when root menu opens\n * - 'lazy': Load when submenu opens (default)\n */\n loadStrategy?: 'eager' | 'lazy'\n}\n\n/**\n * Creates a static loader configuration using plain fetch/promises.\n * No external data library required.\n *\n * @example\n * ```tsx\n * const recentFilesLoader = createVanillaStaticLoader({\n * fetcher: async () => {\n * const res = await fetch('/api/recent-files')\n * const data = await res.json()\n * return data.map(file => ({\n * kind: 'item',\n * value: file.name,\n * render: ...\n * }))\n * },\n * })\n * ```\n */\nexport function createVanillaStaticLoader(\n props: CreateVanillaStaticLoaderProps,\n): StaticLoaderConfig {\n const { fetcher, loadStrategy } = props\n\n const Loader: React.FC<LoaderComponentProps> = ({ children }) => {\n const result = useAsyncState(fetcher)\n return <>{children(result)}</>\n }\n\n return {\n type: 'static',\n Loader,\n loadStrategy,\n }\n}\n\n/**\n * Props for creating a query-dependent loader with vanilla fetch.\n */\nexport interface CreateVanillaQueryLoaderProps {\n /**\n * Async function that fetches menu items based on the search query.\n * Receives an optional `signal` that is aborted when a newer query is issued,\n * allowing you to cancel in-flight requests (e.g. pass it to `fetch()`).\n */\n fetcher: (\n query: string,\n options?: { signal?: AbortSignal },\n ) => Promise<NodeDef[]>\n /**\n * Minimum query length before fetching.\n * @default 1\n */\n minQueryLength?: number\n /**\n * Initial query behavior before user input reaches minQueryLength.\n * Defaults to fetching with an empty query.\n */\n initialQueryBehavior?: InitialQueryBehavior | false\n /**\n * @deprecated Use `initialQueryBehavior` instead.\n */\n initialQuery?: string\n /**\n * When to trigger the loader:\n * - 'eager': Load when root menu opens (good for deep search)\n * - 'lazy': Load when submenu opens (default)\n * @default 'lazy'\n */\n loadStrategy?: 'eager' | 'lazy'\n /**\n * What to show when query is below minQueryLength.\n * @default 'empty'\n */\n belowMinBehavior?: 'empty' | 'placeholder'\n /**\n * Placeholder nodes shown when query is below minQueryLength.\n */\n placeholderNodes?: NodeDef[]\n}\n\n/**\n * Creates a query-dependent loader configuration using plain fetch/promises.\n * No external data library required.\n *\n * @example\n * ```tsx\n * const searchLoader = createVanillaQueryLoader({\n * fetcher: async (query, options) => {\n * const res = await fetch(`/api/search?q=${encodeURIComponent(query)}`, {\n * signal: options?.signal, // aborts when a newer query is issued\n * })\n * const data = await res.json()\n * return data.map(item => ({\n * kind: 'item',\n * value: item.name,\n * render: ...\n * }))\n * },\n * minQueryLength: 2,\n * })\n * ```\n */\nexport function createVanillaQueryLoader(\n props: CreateVanillaQueryLoaderProps,\n): QueryDependentLoaderConfig {\n const {\n fetcher,\n minQueryLength = 1,\n initialQueryBehavior,\n initialQuery,\n loadStrategy,\n belowMinBehavior = 'empty',\n placeholderNodes,\n } = props\n\n const resolvedInitialQueryBehavior: InitialQueryBehavior | false =\n initialQueryBehavior !== undefined\n ? initialQueryBehavior\n : initialQuery !== undefined\n ? { value: initialQuery, loadWhen: 'needed' }\n : { value: '', loadWhen: 'needed' }\n\n const Loader: React.FC<LoaderComponentProps> = ({\n query,\n enabled,\n children,\n }) => {\n const isEnabled =\n enabled ??\n (query.length >= minQueryLength || resolvedInitialQueryBehavior !== false)\n const result = useAsyncQueryState(fetcher, query, { enabled: isEnabled })\n return <>{children(result)}</>\n }\n\n return {\n type: 'query',\n Loader,\n minQueryLength,\n initialQueryBehavior: resolvedInitialQueryBehavior,\n initialQuery,\n loadStrategy,\n belowMinBehavior,\n placeholderNodes,\n }\n}\n"]}