@octanejs/radix 0.1.32 → 0.1.34

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 (60) hide show
  1. package/dist/cjs/AccessibleIcon.cjs +56 -0
  2. package/dist/cjs/Accordion.cjs +272 -0
  3. package/dist/cjs/AlertDialog.cjs +144 -0
  4. package/dist/cjs/Arrow.cjs +43 -0
  5. package/dist/cjs/AspectRatio.cjs +56 -0
  6. package/dist/cjs/Avatar.cjs +150 -0
  7. package/dist/cjs/Checkbox.cjs +281 -0
  8. package/dist/cjs/Collapsible.cjs +176 -0
  9. package/dist/cjs/ContextMenu.cjs +315 -0
  10. package/dist/cjs/Dialog.cjs +291 -0
  11. package/dist/cjs/DismissableLayer.cjs +382 -0
  12. package/dist/cjs/DropdownMenu.cjs +296 -0
  13. package/dist/cjs/FocusScope.cjs +257 -0
  14. package/dist/cjs/Form.cjs +537 -0
  15. package/dist/cjs/HoverCard.cjs +309 -0
  16. package/dist/cjs/Label.cjs +42 -0
  17. package/dist/cjs/Menu.cjs +925 -0
  18. package/dist/cjs/Menubar.cjs +475 -0
  19. package/dist/cjs/NavigationMenu.cjs +942 -0
  20. package/dist/cjs/OneTimePasswordField.cjs +729 -0
  21. package/dist/cjs/PasswordToggleField.cjs +377 -0
  22. package/dist/cjs/Popover.cjs +340 -0
  23. package/dist/cjs/Popper.cjs +368 -0
  24. package/dist/cjs/Portal.cjs +40 -0
  25. package/dist/cjs/Presence.cjs +183 -0
  26. package/dist/cjs/Primitive.cjs +63 -0
  27. package/dist/cjs/Progress.cjs +111 -0
  28. package/dist/cjs/Radio.cjs +240 -0
  29. package/dist/cjs/RadioGroup.cjs +216 -0
  30. package/dist/cjs/RovingFocusGroup.cjs +253 -0
  31. package/dist/cjs/ScrollArea.cjs +828 -0
  32. package/dist/cjs/Select.cjs +1429 -0
  33. package/dist/cjs/Separator.cjs +51 -0
  34. package/dist/cjs/Slider.cjs +634 -0
  35. package/dist/cjs/Slot.cjs +97 -0
  36. package/dist/cjs/Switch.cjs +253 -0
  37. package/dist/cjs/Tabs.cjs +195 -0
  38. package/dist/cjs/Toast.cjs +733 -0
  39. package/dist/cjs/Toggle.cjs +54 -0
  40. package/dist/cjs/ToggleGroup.cjs +174 -0
  41. package/dist/cjs/Toolbar.cjs +165 -0
  42. package/dist/cjs/Tooltip.cjs +628 -0
  43. package/dist/cjs/VisuallyHidden.cjs +52 -0
  44. package/dist/cjs/collection.cjs +95 -0
  45. package/dist/cjs/compose-event-handlers.cjs +35 -0
  46. package/dist/cjs/compose-refs.cjs +68 -0
  47. package/dist/cjs/context.cjs +96 -0
  48. package/dist/cjs/direction.cjs +41 -0
  49. package/dist/cjs/focus-guards.cjs +76 -0
  50. package/dist/cjs/index.cjs +174 -0
  51. package/dist/cjs/internal.cjs +51 -0
  52. package/dist/cjs/scroll-lock.cjs +67 -0
  53. package/dist/cjs/use-callback-ref.cjs +47 -0
  54. package/dist/cjs/use-effect-event.cjs +52 -0
  55. package/dist/cjs/use-is-hydrated.cjs +43 -0
  56. package/dist/cjs/use-previous.cjs +47 -0
  57. package/dist/cjs/use-size.cjs +69 -0
  58. package/dist/cjs/useControllableState.cjs +80 -0
  59. package/dist/cjs/useId.cjs +36 -0
  60. package/package.json +14 -7
@@ -0,0 +1,942 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var NavigationMenu_exports = {};
20
+ __export(NavigationMenu_exports, {
21
+ Content: () => Content,
22
+ Indicator: () => Indicator,
23
+ Item: () => Item,
24
+ Link: () => Link,
25
+ List: () => List,
26
+ NavigationMenu: () => Root,
27
+ NavigationMenuContent: () => Content,
28
+ NavigationMenuIndicator: () => Indicator,
29
+ NavigationMenuItem: () => Item,
30
+ NavigationMenuLink: () => Link,
31
+ NavigationMenuList: () => List,
32
+ NavigationMenuSub: () => Sub,
33
+ NavigationMenuTrigger: () => Trigger,
34
+ NavigationMenuViewport: () => Viewport,
35
+ Root: () => Root,
36
+ Sub: () => Sub,
37
+ Trigger: () => Trigger,
38
+ Viewport: () => Viewport,
39
+ createNavigationMenuScope: () => createNavigationMenuScope
40
+ });
41
+ module.exports = __toCommonJS(NavigationMenu_exports);
42
+ var import_octane = require("octane");
43
+ var import_collection = require("./collection.cjs");
44
+ var import_compose_event_handlers = require("./compose-event-handlers.cjs");
45
+ var import_compose_refs = require("./compose-refs.cjs");
46
+ var import_context = require("./context.cjs");
47
+ var import_direction = require("./direction.cjs");
48
+ var import_DismissableLayer = require("./DismissableLayer.cjs");
49
+ var import_internal = require("./internal.cjs");
50
+ var import_use_effect_event = require("./use-effect-event.cjs");
51
+ var import_Presence = require("./Presence.cjs");
52
+ var import_Primitive = require("./Primitive.cjs");
53
+ var import_use_callback_ref = require("./use-callback-ref.cjs");
54
+ var import_use_previous = require("./use-previous.cjs");
55
+ var import_useControllableState = require("./useControllableState.cjs");
56
+ var import_useId = require("./useId.cjs");
57
+ var import_VisuallyHidden = require("./VisuallyHidden.cjs");
58
+ const NAVIGATION_MENU_NAME = "NavigationMenu";
59
+ const [Collection, useCollection, createCollectionScope] = (0, import_collection.createCollection)(NAVIGATION_MENU_NAME);
60
+ const [FocusGroupCollection, useFocusGroupCollection, createFocusGroupCollectionScope] = (0, import_collection.createCollection)(NAVIGATION_MENU_NAME + "FocusGroup");
61
+ const [createNavigationMenuContext, createNavigationMenuScope] = (0, import_context.createContextScope)(
62
+ NAVIGATION_MENU_NAME,
63
+ [createCollectionScope, createFocusGroupCollectionScope]
64
+ );
65
+ const [NavigationMenuProviderImpl, useNavigationMenuContext] = createNavigationMenuContext(NAVIGATION_MENU_NAME);
66
+ const [ViewportContentProvider, useViewportContentContext] = createNavigationMenuContext(NAVIGATION_MENU_NAME);
67
+ function Root(props) {
68
+ const slot = (0, import_internal.S)("NavigationMenu.Root");
69
+ const {
70
+ __scopeNavigationMenu,
71
+ value: valueProp,
72
+ onValueChange,
73
+ defaultValue,
74
+ delayDuration = 200,
75
+ skipDelayDuration = 300,
76
+ orientation = "horizontal",
77
+ dir,
78
+ ref: forwardedRef,
79
+ ...navigationMenuProps
80
+ } = props ?? {};
81
+ const [navigationMenu, setNavigationMenu] = (0, import_octane.useState)(
82
+ null,
83
+ (0, import_internal.subSlot)(slot, "nav")
84
+ );
85
+ const composedRef = (0, import_compose_refs.useComposedRefs)(forwardedRef, setNavigationMenu, (0, import_internal.subSlot)(slot, "refs"));
86
+ const direction = (0, import_direction.useDirection)(dir);
87
+ const openTimerRef = (0, import_octane.useRef)(0, (0, import_internal.subSlot)(slot, "openTimer"));
88
+ const closeTimerRef = (0, import_octane.useRef)(0, (0, import_internal.subSlot)(slot, "closeTimer"));
89
+ const skipDelayTimerRef = (0, import_octane.useRef)(0, (0, import_internal.subSlot)(slot, "skipTimer"));
90
+ const [isOpenDelayed, setIsOpenDelayed] = (0, import_octane.useState)(true, (0, import_internal.subSlot)(slot, "delayed"));
91
+ const [value, setValue] = (0, import_useControllableState.useControllableState)(
92
+ {
93
+ prop: valueProp,
94
+ onChange: (value2) => {
95
+ const isOpen = value2 !== "";
96
+ const hasSkipDelayDuration = skipDelayDuration > 0;
97
+ if (isOpen) {
98
+ window.clearTimeout(skipDelayTimerRef.current);
99
+ if (hasSkipDelayDuration) setIsOpenDelayed(false);
100
+ } else {
101
+ window.clearTimeout(skipDelayTimerRef.current);
102
+ skipDelayTimerRef.current = window.setTimeout(
103
+ () => setIsOpenDelayed(true),
104
+ skipDelayDuration
105
+ );
106
+ }
107
+ onValueChange?.(value2);
108
+ },
109
+ defaultProp: defaultValue ?? ""
110
+ },
111
+ (0, import_internal.subSlot)(slot, "value")
112
+ );
113
+ const startCloseTimer = (0, import_octane.useCallback)(
114
+ () => {
115
+ window.clearTimeout(closeTimerRef.current);
116
+ closeTimerRef.current = window.setTimeout(() => setValue(""), 150);
117
+ },
118
+ [setValue],
119
+ (0, import_internal.subSlot)(slot, "closeTimerCb")
120
+ );
121
+ const handleOpen = (0, import_octane.useCallback)(
122
+ (itemValue) => {
123
+ window.clearTimeout(closeTimerRef.current);
124
+ setValue(itemValue);
125
+ },
126
+ [setValue],
127
+ (0, import_internal.subSlot)(slot, "open")
128
+ );
129
+ const handleDelayedOpen = (0, import_octane.useCallback)(
130
+ (itemValue) => {
131
+ const isOpenItem = value === itemValue;
132
+ if (isOpenItem) {
133
+ window.clearTimeout(closeTimerRef.current);
134
+ } else {
135
+ openTimerRef.current = window.setTimeout(() => {
136
+ window.clearTimeout(closeTimerRef.current);
137
+ setValue(itemValue);
138
+ }, delayDuration);
139
+ }
140
+ },
141
+ [value, setValue, delayDuration],
142
+ (0, import_internal.subSlot)(slot, "delayedOpen")
143
+ );
144
+ (0, import_octane.useEffect)(
145
+ () => {
146
+ return () => {
147
+ window.clearTimeout(openTimerRef.current);
148
+ window.clearTimeout(closeTimerRef.current);
149
+ window.clearTimeout(skipDelayTimerRef.current);
150
+ };
151
+ },
152
+ [],
153
+ (0, import_internal.subSlot)(slot, "e:timers")
154
+ );
155
+ return (0, import_octane.createElement)(NavigationMenuProvider, {
156
+ scope: __scopeNavigationMenu,
157
+ isRootMenu: true,
158
+ value,
159
+ dir: direction,
160
+ orientation,
161
+ rootNavigationMenu: navigationMenu,
162
+ onTriggerEnter: (itemValue) => {
163
+ window.clearTimeout(openTimerRef.current);
164
+ if (isOpenDelayed) handleDelayedOpen(itemValue);
165
+ else handleOpen(itemValue);
166
+ },
167
+ onTriggerLeave: () => {
168
+ window.clearTimeout(openTimerRef.current);
169
+ startCloseTimer();
170
+ },
171
+ onContentEnter: () => window.clearTimeout(closeTimerRef.current),
172
+ onContentLeave: startCloseTimer,
173
+ onItemSelect: (itemValue) => {
174
+ setValue((prevValue) => prevValue === itemValue ? "" : itemValue);
175
+ },
176
+ onItemDismiss: () => setValue(""),
177
+ children: (0, import_octane.createElement)(import_Primitive.Primitive.nav, {
178
+ "aria-label": "Main",
179
+ "data-orientation": orientation,
180
+ dir: direction,
181
+ ...navigationMenuProps,
182
+ ref: composedRef
183
+ })
184
+ });
185
+ }
186
+ const SUB_NAME = "NavigationMenuSub";
187
+ function Sub(props) {
188
+ const slot = (0, import_internal.S)("NavigationMenu.Sub");
189
+ const {
190
+ __scopeNavigationMenu,
191
+ value: valueProp,
192
+ onValueChange,
193
+ defaultValue,
194
+ orientation = "horizontal",
195
+ ref: forwardedRef,
196
+ ...subProps
197
+ } = props ?? {};
198
+ const context = useNavigationMenuContext(SUB_NAME, __scopeNavigationMenu);
199
+ const [value, setValue] = (0, import_useControllableState.useControllableState)(
200
+ {
201
+ prop: valueProp,
202
+ onChange: onValueChange,
203
+ defaultProp: defaultValue ?? ""
204
+ },
205
+ (0, import_internal.subSlot)(slot, "value")
206
+ );
207
+ return (0, import_octane.createElement)(NavigationMenuProvider, {
208
+ scope: __scopeNavigationMenu,
209
+ isRootMenu: false,
210
+ value,
211
+ dir: context.dir,
212
+ orientation,
213
+ rootNavigationMenu: context.rootNavigationMenu,
214
+ onTriggerEnter: (itemValue) => setValue(itemValue),
215
+ onItemSelect: (itemValue) => setValue(itemValue),
216
+ onItemDismiss: () => setValue(""),
217
+ children: (0, import_octane.createElement)(import_Primitive.Primitive.div, {
218
+ "data-orientation": orientation,
219
+ ...subProps,
220
+ ref: forwardedRef
221
+ })
222
+ });
223
+ }
224
+ function NavigationMenuProvider(props) {
225
+ const slot = (0, import_internal.S)("NavigationMenu.Provider");
226
+ const {
227
+ scope,
228
+ isRootMenu,
229
+ rootNavigationMenu,
230
+ dir,
231
+ orientation,
232
+ children,
233
+ value,
234
+ onItemSelect,
235
+ onItemDismiss,
236
+ onTriggerEnter,
237
+ onTriggerLeave,
238
+ onContentEnter,
239
+ onContentLeave
240
+ } = props;
241
+ const [viewport, setViewport] = (0, import_octane.useState)(null, (0, import_internal.subSlot)(slot, "viewport"));
242
+ const [viewportContent, setViewportContent] = (0, import_octane.useState)(
243
+ /* @__PURE__ */ new Map(),
244
+ (0, import_internal.subSlot)(slot, "content")
245
+ );
246
+ const [indicatorTrack, setIndicatorTrack] = (0, import_octane.useState)(
247
+ null,
248
+ (0, import_internal.subSlot)(slot, "track")
249
+ );
250
+ return (0, import_octane.createElement)(NavigationMenuProviderImpl, {
251
+ scope,
252
+ isRootMenu,
253
+ rootNavigationMenu,
254
+ value,
255
+ previousValue: (0, import_use_previous.usePrevious)(value, (0, import_internal.subSlot)(slot, "prev")),
256
+ baseId: (0, import_useId.useId)((0, import_internal.subSlot)(slot, "id")),
257
+ dir,
258
+ orientation,
259
+ viewport,
260
+ onViewportChange: setViewport,
261
+ indicatorTrack,
262
+ onIndicatorTrackChange: setIndicatorTrack,
263
+ onTriggerEnter: (0, import_use_callback_ref.useCallbackRef)(onTriggerEnter, (0, import_internal.subSlot)(slot, "triggerEnter")),
264
+ onTriggerLeave: (0, import_use_callback_ref.useCallbackRef)(onTriggerLeave, (0, import_internal.subSlot)(slot, "triggerLeave")),
265
+ onContentEnter: (0, import_use_callback_ref.useCallbackRef)(onContentEnter, (0, import_internal.subSlot)(slot, "contentEnter")),
266
+ onContentLeave: (0, import_use_callback_ref.useCallbackRef)(onContentLeave, (0, import_internal.subSlot)(slot, "contentLeave")),
267
+ onItemSelect: (0, import_use_callback_ref.useCallbackRef)(onItemSelect, (0, import_internal.subSlot)(slot, "itemSelect")),
268
+ onItemDismiss: (0, import_use_callback_ref.useCallbackRef)(onItemDismiss, (0, import_internal.subSlot)(slot, "itemDismiss")),
269
+ onViewportContentChange: (0, import_octane.useCallback)(
270
+ (contentValue, contentData) => {
271
+ setViewportContent((prevContent) => {
272
+ prevContent.set(contentValue, contentData);
273
+ return new Map(prevContent);
274
+ });
275
+ },
276
+ [],
277
+ (0, import_internal.subSlot)(slot, "vcChange")
278
+ ),
279
+ onViewportContentRemove: (0, import_octane.useCallback)(
280
+ (contentValue) => {
281
+ setViewportContent((prevContent) => {
282
+ if (!prevContent.has(contentValue)) return prevContent;
283
+ prevContent.delete(contentValue);
284
+ return new Map(prevContent);
285
+ });
286
+ },
287
+ [],
288
+ (0, import_internal.subSlot)(slot, "vcRemove")
289
+ ),
290
+ children: (0, import_octane.createElement)(Collection.Provider, {
291
+ scope,
292
+ children: (0, import_octane.createElement)(ViewportContentProvider, {
293
+ scope,
294
+ items: viewportContent,
295
+ // Identity-stable user children ride octane's implicit same-element
296
+ // bailout (React beginWork parity): provider-state re-renders skip
297
+ // them while consumers of the CHANGED context refresh lazily.
298
+ children
299
+ })
300
+ })
301
+ });
302
+ }
303
+ const LIST_NAME = "NavigationMenuList";
304
+ function List(props) {
305
+ const { __scopeNavigationMenu, ref: forwardedRef, ...listProps } = props ?? {};
306
+ const context = useNavigationMenuContext(LIST_NAME, __scopeNavigationMenu);
307
+ const list = (0, import_octane.createElement)(import_Primitive.Primitive.ul, {
308
+ "data-orientation": context.orientation,
309
+ ...listProps,
310
+ ref: forwardedRef
311
+ });
312
+ return (0, import_octane.createElement)(import_Primitive.Primitive.div, {
313
+ style: { position: "relative" },
314
+ ref: context.onIndicatorTrackChange,
315
+ children: (0, import_octane.createElement)(Collection.Slot, {
316
+ scope: __scopeNavigationMenu,
317
+ children: context.isRootMenu ? (0, import_octane.createElement)(FocusGroup, { asChild: true, children: list }) : list
318
+ })
319
+ });
320
+ }
321
+ const ITEM_NAME = "NavigationMenuItem";
322
+ const [NavigationMenuItemContextProvider, useNavigationMenuItemContext] = createNavigationMenuContext(ITEM_NAME);
323
+ function Item(props) {
324
+ const slot = (0, import_internal.S)("NavigationMenu.Item");
325
+ const { __scopeNavigationMenu, value: valueProp, ref: forwardedRef, ...itemProps } = props ?? {};
326
+ const autoValue = (0, import_useId.useId)((0, import_internal.subSlot)(slot, "id"));
327
+ const value = valueProp || autoValue || "LEGACY_REACT_AUTO_VALUE";
328
+ const contentRef = (0, import_octane.useRef)(null, (0, import_internal.subSlot)(slot, "content"));
329
+ const triggerRef = (0, import_octane.useRef)(null, (0, import_internal.subSlot)(slot, "trigger"));
330
+ const focusProxyRef = (0, import_octane.useRef)(null, (0, import_internal.subSlot)(slot, "proxy"));
331
+ const restoreContentTabOrderRef = (0, import_octane.useRef)(() => {
332
+ }, (0, import_internal.subSlot)(slot, "restore"));
333
+ const wasEscapeCloseRef = (0, import_octane.useRef)(false, (0, import_internal.subSlot)(slot, "escape"));
334
+ const handleContentEntry = (0, import_octane.useCallback)(
335
+ (side = "start") => {
336
+ if (contentRef.current) {
337
+ restoreContentTabOrderRef.current();
338
+ const candidates = getTabbableCandidates(contentRef.current);
339
+ if (candidates.length) focusFirst(side === "start" ? candidates : candidates.reverse());
340
+ }
341
+ },
342
+ [],
343
+ (0, import_internal.subSlot)(slot, "entry")
344
+ );
345
+ const handleContentExit = (0, import_octane.useCallback)(
346
+ () => {
347
+ if (contentRef.current) {
348
+ const candidates = getTabbableCandidates(contentRef.current);
349
+ if (candidates.length) restoreContentTabOrderRef.current = removeFromTabOrder(candidates);
350
+ }
351
+ },
352
+ [],
353
+ (0, import_internal.subSlot)(slot, "exit")
354
+ );
355
+ return (0, import_octane.createElement)(NavigationMenuItemContextProvider, {
356
+ scope: __scopeNavigationMenu,
357
+ value,
358
+ triggerRef,
359
+ contentRef,
360
+ focusProxyRef,
361
+ wasEscapeCloseRef,
362
+ onEntryKeyDown: handleContentEntry,
363
+ onFocusProxyEnter: handleContentEntry,
364
+ onRootContentClose: handleContentExit,
365
+ onContentFocusOutside: handleContentExit,
366
+ children: (0, import_octane.createElement)(import_Primitive.Primitive.li, { ...itemProps, ref: forwardedRef })
367
+ });
368
+ }
369
+ const TRIGGER_NAME = "NavigationMenuTrigger";
370
+ function Trigger(props) {
371
+ const slot = (0, import_internal.S)("NavigationMenu.Trigger");
372
+ const { __scopeNavigationMenu, disabled, ref: forwardedRef, ...triggerProps } = props ?? {};
373
+ const context = useNavigationMenuContext(TRIGGER_NAME, props?.__scopeNavigationMenu);
374
+ const itemContext = useNavigationMenuItemContext(TRIGGER_NAME, props?.__scopeNavigationMenu);
375
+ const ref = (0, import_octane.useRef)(null, (0, import_internal.subSlot)(slot, "ref"));
376
+ const composedRefs = (0, import_compose_refs.useComposedRefs)(
377
+ ref,
378
+ itemContext.triggerRef,
379
+ forwardedRef,
380
+ (0, import_internal.subSlot)(slot, "refs")
381
+ );
382
+ const triggerId = makeTriggerId(context.baseId, itemContext.value);
383
+ const contentId = makeContentId(context.baseId, itemContext.value);
384
+ const hasPointerMoveOpenedRef = (0, import_octane.useRef)(false, (0, import_internal.subSlot)(slot, "moveOpened"));
385
+ const wasClickCloseRef = (0, import_octane.useRef)(false, (0, import_internal.subSlot)(slot, "clickClose"));
386
+ const open = itemContext.value === context.value;
387
+ return [
388
+ (0, import_octane.createElement)(Collection.ItemSlot, {
389
+ key: "trigger",
390
+ scope: __scopeNavigationMenu,
391
+ value: itemContext.value,
392
+ children: (0, import_octane.createElement)(FocusGroupItem, {
393
+ asChild: true,
394
+ children: (0, import_octane.createElement)(import_Primitive.Primitive.button, {
395
+ id: triggerId,
396
+ disabled,
397
+ "data-disabled": disabled ? "" : void 0,
398
+ "data-state": getOpenState(open),
399
+ "aria-expanded": open,
400
+ "aria-controls": open ? contentId : void 0,
401
+ ...triggerProps,
402
+ ref: composedRefs,
403
+ onPointerEnter: (0, import_compose_event_handlers.composeEventHandlers)(props?.onPointerEnter, () => {
404
+ wasClickCloseRef.current = false;
405
+ itemContext.wasEscapeCloseRef.current = false;
406
+ }),
407
+ onPointerMove: (0, import_compose_event_handlers.composeEventHandlers)(
408
+ props?.onPointerMove,
409
+ whenMouse(() => {
410
+ if (disabled || wasClickCloseRef.current || itemContext.wasEscapeCloseRef.current || hasPointerMoveOpenedRef.current)
411
+ return;
412
+ context.onTriggerEnter(itemContext.value);
413
+ hasPointerMoveOpenedRef.current = true;
414
+ })
415
+ ),
416
+ onPointerLeave: (0, import_compose_event_handlers.composeEventHandlers)(
417
+ props?.onPointerLeave,
418
+ whenMouse(() => {
419
+ if (disabled) return;
420
+ context.onTriggerLeave();
421
+ hasPointerMoveOpenedRef.current = false;
422
+ })
423
+ ),
424
+ onClick: (0, import_compose_event_handlers.composeEventHandlers)(props?.onClick, () => {
425
+ context.onItemSelect(itemContext.value);
426
+ wasClickCloseRef.current = open;
427
+ }),
428
+ onKeyDown: (0, import_compose_event_handlers.composeEventHandlers)(props?.onKeyDown, (event) => {
429
+ const verticalEntryKey = context.dir === "rtl" ? "ArrowLeft" : "ArrowRight";
430
+ const entryKey = { horizontal: "ArrowDown", vertical: verticalEntryKey }[context.orientation];
431
+ if (open && event.key === entryKey) {
432
+ itemContext.onEntryKeyDown();
433
+ event.preventDefault();
434
+ }
435
+ })
436
+ })
437
+ })
438
+ }),
439
+ // Proxy tab order between trigger and content
440
+ open ? (0, import_octane.createElement)(import_VisuallyHidden.VisuallyHidden, {
441
+ key: "proxy",
442
+ "aria-hidden": true,
443
+ tabIndex: 0,
444
+ ref: itemContext.focusProxyRef,
445
+ onFocus: (event) => {
446
+ const content = itemContext.contentRef.current;
447
+ const prevFocusedElement = event.relatedTarget;
448
+ const wasTriggerFocused = prevFocusedElement === ref.current;
449
+ const wasFocusFromContent = content?.contains(prevFocusedElement);
450
+ if (wasTriggerFocused || !wasFocusFromContent) {
451
+ itemContext.onFocusProxyEnter(wasTriggerFocused ? "start" : "end");
452
+ }
453
+ }
454
+ }) : null,
455
+ // Restructure a11y tree to make content accessible to screen reader when using the viewport
456
+ open && context.viewport ? (0, import_octane.createElement)("span", { key: "owns", "aria-owns": contentId }) : null
457
+ // The conditional slots are dropped (not `null`-padded): every element is keyed, so
458
+ // octane reconciles by key and doesn't warn about unkeyed array holes.
459
+ ].filter(Boolean);
460
+ }
461
+ const LINK_SELECT = "navigationMenu.linkSelect";
462
+ function Link(props) {
463
+ const { __scopeNavigationMenu, active, onSelect, ref: forwardedRef, ...linkProps } = props ?? {};
464
+ return (0, import_octane.createElement)(FocusGroupItem, {
465
+ asChild: true,
466
+ children: (0, import_octane.createElement)(import_Primitive.Primitive.a, {
467
+ "data-active": active ? "" : void 0,
468
+ "aria-current": active ? "page" : void 0,
469
+ ...linkProps,
470
+ ref: forwardedRef,
471
+ onClick: (0, import_compose_event_handlers.composeEventHandlers)(
472
+ props?.onClick,
473
+ (event) => {
474
+ const target = event.target;
475
+ const linkSelectEvent = new CustomEvent(LINK_SELECT, {
476
+ bubbles: true,
477
+ cancelable: true
478
+ });
479
+ target.addEventListener(LINK_SELECT, (event2) => onSelect?.(event2), { once: true });
480
+ (0, import_Primitive.dispatchDiscreteCustomEvent)(target, linkSelectEvent);
481
+ if (!linkSelectEvent.defaultPrevented && !event.metaKey) {
482
+ const rootContentDismissEvent = new CustomEvent(ROOT_CONTENT_DISMISS, {
483
+ bubbles: true,
484
+ cancelable: true
485
+ });
486
+ (0, import_Primitive.dispatchDiscreteCustomEvent)(target, rootContentDismissEvent);
487
+ }
488
+ },
489
+ { checkForDefaultPrevented: false }
490
+ )
491
+ })
492
+ });
493
+ }
494
+ const INDICATOR_NAME = "NavigationMenuIndicator";
495
+ function Indicator(props) {
496
+ const { forceMount, ...indicatorProps } = props ?? {};
497
+ const context = useNavigationMenuContext(INDICATOR_NAME, props?.__scopeNavigationMenu);
498
+ const isVisible = Boolean(context.value);
499
+ return context.indicatorTrack ? (0, import_octane.createPortal)(
500
+ (0, import_octane.createElement)(import_Presence.Presence, {
501
+ present: forceMount || isVisible,
502
+ children: (0, import_octane.createElement)(NavigationMenuIndicatorImpl, { ...indicatorProps })
503
+ }),
504
+ context.indicatorTrack
505
+ ) : null;
506
+ }
507
+ function NavigationMenuIndicatorImpl(props) {
508
+ const slot = (0, import_internal.S)("NavigationMenu.IndicatorImpl");
509
+ const { __scopeNavigationMenu, ref: forwardedRef, ...indicatorProps } = props ?? {};
510
+ const context = useNavigationMenuContext(INDICATOR_NAME, __scopeNavigationMenu);
511
+ const getItems = useCollection(__scopeNavigationMenu, (0, import_internal.subSlot)(slot, "items"));
512
+ const [activeTrigger, setActiveTrigger] = (0, import_octane.useState)(
513
+ null,
514
+ (0, import_internal.subSlot)(slot, "active")
515
+ );
516
+ const [position, setPosition] = (0, import_octane.useState)(
517
+ null,
518
+ (0, import_internal.subSlot)(slot, "position")
519
+ );
520
+ const isHorizontal = context.orientation === "horizontal";
521
+ const isVisible = Boolean(context.value);
522
+ (0, import_octane.useEffect)(
523
+ () => {
524
+ const items = getItems();
525
+ const triggerNode = items.find((item) => item.value === context.value)?.ref.current;
526
+ if (triggerNode) setActiveTrigger(triggerNode);
527
+ },
528
+ [getItems, context.value],
529
+ (0, import_internal.subSlot)(slot, "e:active")
530
+ );
531
+ const handlePositionChange = () => {
532
+ if (activeTrigger) {
533
+ setPosition({
534
+ size: isHorizontal ? activeTrigger.offsetWidth : activeTrigger.offsetHeight,
535
+ offset: isHorizontal ? activeTrigger.offsetLeft : activeTrigger.offsetTop
536
+ });
537
+ }
538
+ };
539
+ useResizeObserver(activeTrigger, handlePositionChange, (0, import_internal.subSlot)(slot, "ro:trigger"));
540
+ useResizeObserver(context.indicatorTrack, handlePositionChange, (0, import_internal.subSlot)(slot, "ro:track"));
541
+ return position ? (0, import_octane.createElement)(import_Primitive.Primitive.div, {
542
+ "aria-hidden": true,
543
+ "data-state": isVisible ? "visible" : "hidden",
544
+ "data-orientation": context.orientation,
545
+ ...indicatorProps,
546
+ ref: forwardedRef,
547
+ style: {
548
+ position: "absolute",
549
+ ...isHorizontal ? {
550
+ left: 0,
551
+ width: position.size + "px",
552
+ transform: `translateX(${position.offset}px)`
553
+ } : {
554
+ top: 0,
555
+ height: position.size + "px",
556
+ transform: `translateY(${position.offset}px)`
557
+ },
558
+ ...indicatorProps.style
559
+ }
560
+ }) : null;
561
+ }
562
+ const CONTENT_NAME = "NavigationMenuContent";
563
+ function Content(props) {
564
+ const slot = (0, import_internal.S)("NavigationMenu.Content");
565
+ const { forceMount, ref: forwardedRef, ...contentProps } = props ?? {};
566
+ const context = useNavigationMenuContext(CONTENT_NAME, props?.__scopeNavigationMenu);
567
+ const itemContext = useNavigationMenuItemContext(CONTENT_NAME, props?.__scopeNavigationMenu);
568
+ const composedRefs = (0, import_compose_refs.useComposedRefs)(itemContext.contentRef, forwardedRef, (0, import_internal.subSlot)(slot, "refs"));
569
+ const open = itemContext.value === context.value;
570
+ const commonProps = {
571
+ value: itemContext.value,
572
+ triggerRef: itemContext.triggerRef,
573
+ focusProxyRef: itemContext.focusProxyRef,
574
+ wasEscapeCloseRef: itemContext.wasEscapeCloseRef,
575
+ onContentFocusOutside: itemContext.onContentFocusOutside,
576
+ onRootContentClose: itemContext.onRootContentClose,
577
+ ...contentProps
578
+ };
579
+ const inViewport = Boolean(context.viewport);
580
+ const { onViewportContentChange, onViewportContentRemove } = context;
581
+ const contentData = { forceMount, ...commonProps, ref: composedRefs };
582
+ (0, import_octane.useLayoutEffect)(
583
+ () => {
584
+ return () => onViewportContentRemove(contentData.value);
585
+ },
586
+ [inViewport, contentData.value, onViewportContentRemove],
587
+ (0, import_internal.subSlot)(slot, "e:vcRemove")
588
+ );
589
+ (0, import_octane.useLayoutEffect)(
590
+ () => {
591
+ if (inViewport) onViewportContentChange(contentData.value, contentData);
592
+ },
593
+ [inViewport, contentData, onViewportContentChange],
594
+ (0, import_internal.subSlot)(slot, "e:vcChange")
595
+ );
596
+ if (!inViewport) {
597
+ return (0, import_octane.createElement)(import_Presence.Presence, {
598
+ present: forceMount || open,
599
+ children: (0, import_octane.createElement)(NavigationMenuContentImpl, {
600
+ "data-state": getOpenState(open),
601
+ ...commonProps,
602
+ ref: composedRefs,
603
+ onPointerEnter: (0, import_compose_event_handlers.composeEventHandlers)(props?.onPointerEnter, context.onContentEnter),
604
+ onPointerLeave: (0, import_compose_event_handlers.composeEventHandlers)(
605
+ props?.onPointerLeave,
606
+ whenMouse(context.onContentLeave)
607
+ ),
608
+ style: {
609
+ // Prevent interaction when animating out
610
+ pointerEvents: !open && context.isRootMenu ? "none" : void 0,
611
+ ...commonProps.style
612
+ }
613
+ })
614
+ });
615
+ }
616
+ return null;
617
+ }
618
+ const ROOT_CONTENT_DISMISS = "navigationMenu.rootContentDismiss";
619
+ function NavigationMenuContentImpl(props) {
620
+ const slot = (0, import_internal.S)("NavigationMenu.ContentImpl");
621
+ const {
622
+ __scopeNavigationMenu,
623
+ value,
624
+ triggerRef,
625
+ focusProxyRef,
626
+ wasEscapeCloseRef,
627
+ onRootContentClose,
628
+ onContentFocusOutside,
629
+ ref: forwardedRef,
630
+ ...contentProps
631
+ } = props ?? {};
632
+ const context = useNavigationMenuContext(CONTENT_NAME, __scopeNavigationMenu);
633
+ const ref = (0, import_octane.useRef)(null, (0, import_internal.subSlot)(slot, "ref"));
634
+ const composedRefs = (0, import_compose_refs.useComposedRefs)(ref, forwardedRef, (0, import_internal.subSlot)(slot, "refs"));
635
+ const triggerId = makeTriggerId(context.baseId, value);
636
+ const contentId = makeContentId(context.baseId, value);
637
+ const getItems = useCollection(__scopeNavigationMenu, (0, import_internal.subSlot)(slot, "items"));
638
+ const prevMotionAttributeRef = (0, import_octane.useRef)(null, (0, import_internal.subSlot)(slot, "prevMotion"));
639
+ const { onItemDismiss } = context;
640
+ (0, import_octane.useEffect)(
641
+ () => {
642
+ const content = ref.current;
643
+ if (context.isRootMenu && content) {
644
+ const handleClose = () => {
645
+ onItemDismiss();
646
+ onRootContentClose();
647
+ if (content.contains(document.activeElement)) triggerRef.current?.focus();
648
+ };
649
+ content.addEventListener(ROOT_CONTENT_DISMISS, handleClose);
650
+ return () => content.removeEventListener(ROOT_CONTENT_DISMISS, handleClose);
651
+ }
652
+ },
653
+ [context.isRootMenu, value, triggerRef, onItemDismiss, onRootContentClose],
654
+ (0, import_internal.subSlot)(slot, "e:dismiss")
655
+ );
656
+ const motionAttribute = (0, import_octane.useMemo)(
657
+ () => {
658
+ const items = getItems();
659
+ const values = items.map((item) => item.value);
660
+ if (context.dir === "rtl") values.reverse();
661
+ const index = values.indexOf(context.value);
662
+ const prevIndex = values.indexOf(context.previousValue);
663
+ const isSelected = value === context.value;
664
+ const wasSelected = prevIndex === values.indexOf(value);
665
+ if (!isSelected && !wasSelected) return prevMotionAttributeRef.current;
666
+ const attribute = (() => {
667
+ if (index !== prevIndex) {
668
+ if (isSelected && prevIndex !== -1) return index > prevIndex ? "from-end" : "from-start";
669
+ if (wasSelected && index !== -1) return index > prevIndex ? "to-start" : "to-end";
670
+ }
671
+ return null;
672
+ })();
673
+ prevMotionAttributeRef.current = attribute;
674
+ return attribute;
675
+ },
676
+ [context.previousValue, context.value, context.dir, getItems, value],
677
+ (0, import_internal.subSlot)(slot, "m:motion")
678
+ );
679
+ return (0, import_octane.createElement)(FocusGroup, {
680
+ asChild: true,
681
+ children: (0, import_octane.createElement)(import_DismissableLayer.DismissableLayer, {
682
+ id: contentId,
683
+ "aria-labelledby": triggerId,
684
+ "data-motion": motionAttribute,
685
+ "data-orientation": context.orientation,
686
+ ...contentProps,
687
+ ref: composedRefs,
688
+ disableOutsidePointerEvents: false,
689
+ onDismiss: () => {
690
+ const rootContentDismissEvent = new Event(ROOT_CONTENT_DISMISS, {
691
+ bubbles: true,
692
+ cancelable: true
693
+ });
694
+ ref.current?.dispatchEvent(rootContentDismissEvent);
695
+ },
696
+ onFocusOutside: (0, import_compose_event_handlers.composeEventHandlers)(props?.onFocusOutside, (event) => {
697
+ onContentFocusOutside();
698
+ const target = event.target;
699
+ if (context.rootNavigationMenu?.contains(target)) event.preventDefault();
700
+ }),
701
+ onPointerDownOutside: (0, import_compose_event_handlers.composeEventHandlers)(props?.onPointerDownOutside, (event) => {
702
+ const target = event.target;
703
+ const isTrigger = getItems().some((item) => item.ref.current?.contains(target));
704
+ const isRootViewport = context.isRootMenu && context.viewport?.contains(target);
705
+ if (isTrigger || isRootViewport || !context.isRootMenu) event.preventDefault();
706
+ }),
707
+ onKeyDown: (0, import_compose_event_handlers.composeEventHandlers)(props?.onKeyDown, (event) => {
708
+ const isMetaKey = event.altKey || event.ctrlKey || event.metaKey;
709
+ const isTabKey = event.key === "Tab" && !isMetaKey;
710
+ if (isTabKey) {
711
+ const candidates = getTabbableCandidates(event.currentTarget);
712
+ const focusedElement = document.activeElement;
713
+ const index = candidates.findIndex((candidate) => candidate === focusedElement);
714
+ const isMovingBackwards = event.shiftKey;
715
+ const nextCandidates = isMovingBackwards ? candidates.slice(0, index).reverse() : candidates.slice(index + 1, candidates.length);
716
+ if (focusFirst(nextCandidates)) {
717
+ event.preventDefault();
718
+ } else {
719
+ focusProxyRef.current?.focus();
720
+ }
721
+ }
722
+ }),
723
+ onEscapeKeyDown: (0, import_compose_event_handlers.composeEventHandlers)(props?.onEscapeKeyDown, (_event) => {
724
+ wasEscapeCloseRef.current = true;
725
+ })
726
+ })
727
+ });
728
+ }
729
+ const VIEWPORT_NAME = "NavigationMenuViewport";
730
+ function Viewport(props) {
731
+ const { forceMount, ...viewportProps } = props ?? {};
732
+ const context = useNavigationMenuContext(VIEWPORT_NAME, props?.__scopeNavigationMenu);
733
+ const open = Boolean(context.value);
734
+ return (0, import_octane.createElement)(import_Presence.Presence, {
735
+ present: forceMount || open,
736
+ children: (0, import_octane.createElement)(NavigationMenuViewportImpl, { ...viewportProps })
737
+ });
738
+ }
739
+ function NavigationMenuViewportImpl(props) {
740
+ const slot = (0, import_internal.S)("NavigationMenu.ViewportImpl");
741
+ const { __scopeNavigationMenu, children, ref: forwardedRef, ...viewportImplProps } = props ?? {};
742
+ const context = useNavigationMenuContext(VIEWPORT_NAME, __scopeNavigationMenu);
743
+ const composedRefs = (0, import_compose_refs.useComposedRefs)(
744
+ forwardedRef,
745
+ context.onViewportChange,
746
+ (0, import_internal.subSlot)(slot, "refs")
747
+ );
748
+ const viewportContentContext = useViewportContentContext(
749
+ CONTENT_NAME,
750
+ props?.__scopeNavigationMenu
751
+ );
752
+ const [size, setSize] = (0, import_octane.useState)(
753
+ null,
754
+ (0, import_internal.subSlot)(slot, "size")
755
+ );
756
+ const [content, setContent] = (0, import_octane.useState)(null, (0, import_internal.subSlot)(slot, "content"));
757
+ const viewportWidth = size ? size?.width + "px" : void 0;
758
+ const viewportHeight = size ? size?.height + "px" : void 0;
759
+ const open = Boolean(context.value);
760
+ const activeContentValue = open ? context.value : context.previousValue;
761
+ const handleSizeChange = () => {
762
+ if (content) setSize({ width: content.offsetWidth, height: content.offsetHeight });
763
+ };
764
+ useResizeObserver(content, handleSizeChange, (0, import_internal.subSlot)(slot, "ro:content"));
765
+ return (0, import_octane.createElement)(import_Primitive.Primitive.div, {
766
+ "data-state": getOpenState(open),
767
+ "data-orientation": context.orientation,
768
+ ...viewportImplProps,
769
+ ref: composedRefs,
770
+ style: {
771
+ // Prevent interaction when animating out
772
+ pointerEvents: !open && context.isRootMenu ? "none" : void 0,
773
+ "--radix-navigation-menu-viewport-width": viewportWidth,
774
+ "--radix-navigation-menu-viewport-height": viewportHeight,
775
+ ...viewportImplProps.style
776
+ },
777
+ onPointerEnter: (0, import_compose_event_handlers.composeEventHandlers)(props?.onPointerEnter, context.onContentEnter),
778
+ onPointerLeave: (0, import_compose_event_handlers.composeEventHandlers)(props?.onPointerLeave, whenMouse(context.onContentLeave)),
779
+ children: Array.from(viewportContentContext.items).map(
780
+ ([value, { ref, forceMount, ...props2 }]) => {
781
+ const isActive = activeContentValue === value;
782
+ return (0, import_octane.createElement)(import_Presence.Presence, {
783
+ key: value,
784
+ present: forceMount || isActive,
785
+ children: (0, import_octane.createElement)(NavigationMenuViewportItem, {
786
+ ...props2,
787
+ contentRef: ref,
788
+ isActive,
789
+ onActiveContentChange: setContent
790
+ })
791
+ });
792
+ }
793
+ )
794
+ });
795
+ }
796
+ function NavigationMenuViewportItem(props) {
797
+ const slot = (0, import_internal.S)("NavigationMenu.ViewportItem");
798
+ const { contentRef, isActive, onActiveContentChange, ...itemProps } = props ?? {};
799
+ const handleContentChange = (0, import_octane.useCallback)(
800
+ (node) => {
801
+ if (isActive && node) {
802
+ onActiveContentChange(node);
803
+ }
804
+ },
805
+ [isActive, onActiveContentChange],
806
+ (0, import_internal.subSlot)(slot, "change")
807
+ );
808
+ const composedRefs = (0, import_compose_refs.useComposedRefs)(contentRef, handleContentChange, (0, import_internal.subSlot)(slot, "refs"));
809
+ return (0, import_octane.createElement)(NavigationMenuContentImpl, { ...itemProps, ref: composedRefs });
810
+ }
811
+ const FOCUS_GROUP_NAME = "FocusGroup";
812
+ function FocusGroup(props) {
813
+ const { __scopeNavigationMenu, ...groupProps } = props ?? {};
814
+ const context = useNavigationMenuContext(FOCUS_GROUP_NAME, __scopeNavigationMenu);
815
+ return (0, import_octane.createElement)(FocusGroupCollection.Provider, {
816
+ scope: __scopeNavigationMenu,
817
+ children: (0, import_octane.createElement)(FocusGroupCollection.Slot, {
818
+ scope: __scopeNavigationMenu,
819
+ children: (0, import_octane.createElement)(import_Primitive.Primitive.div, { dir: context.dir, ...groupProps })
820
+ })
821
+ });
822
+ }
823
+ const ARROW_KEYS = ["ArrowRight", "ArrowLeft", "ArrowUp", "ArrowDown"];
824
+ const FOCUS_GROUP_ITEM_NAME = "FocusGroupItem";
825
+ function FocusGroupItem(props) {
826
+ const slot = (0, import_internal.S)("NavigationMenu.FocusGroupItem");
827
+ const { __scopeNavigationMenu, ...groupProps } = props ?? {};
828
+ const getItems = useFocusGroupCollection(__scopeNavigationMenu, (0, import_internal.subSlot)(slot, "items"));
829
+ const context = useNavigationMenuContext(FOCUS_GROUP_ITEM_NAME, __scopeNavigationMenu);
830
+ return (0, import_octane.createElement)(FocusGroupCollection.ItemSlot, {
831
+ scope: __scopeNavigationMenu,
832
+ children: (0, import_octane.createElement)(import_Primitive.Primitive.button, {
833
+ ...groupProps,
834
+ onKeyDown: (0, import_compose_event_handlers.composeEventHandlers)(props?.onKeyDown, (event) => {
835
+ const isFocusNavigationKey = ["Home", "End", ...ARROW_KEYS].includes(event.key);
836
+ if (isFocusNavigationKey) {
837
+ let candidateNodes = getItems().map((item) => item.ref.current);
838
+ const prevItemKey = context.dir === "rtl" ? "ArrowRight" : "ArrowLeft";
839
+ const prevKeys = [prevItemKey, "ArrowUp", "End"];
840
+ if (prevKeys.includes(event.key)) candidateNodes.reverse();
841
+ if (ARROW_KEYS.includes(event.key)) {
842
+ const currentIndex = candidateNodes.indexOf(event.currentTarget);
843
+ candidateNodes = candidateNodes.slice(currentIndex + 1);
844
+ }
845
+ setTimeout(() => focusFirst(candidateNodes));
846
+ event.preventDefault();
847
+ }
848
+ })
849
+ })
850
+ });
851
+ }
852
+ function getTabbableCandidates(container) {
853
+ const nodes = [];
854
+ const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
855
+ acceptNode: (node) => {
856
+ const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
857
+ if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP;
858
+ return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
859
+ }
860
+ });
861
+ while (walker.nextNode()) nodes.push(walker.currentNode);
862
+ return nodes;
863
+ }
864
+ function focusFirst(candidates) {
865
+ const previouslyFocusedElement = document.activeElement;
866
+ return candidates.some((candidate) => {
867
+ if (candidate === previouslyFocusedElement) return true;
868
+ candidate.focus();
869
+ return document.activeElement !== previouslyFocusedElement;
870
+ });
871
+ }
872
+ function removeFromTabOrder(candidates) {
873
+ candidates.forEach((candidate) => {
874
+ candidate.dataset.tabindex = candidate.getAttribute("tabindex") || "";
875
+ candidate.setAttribute("tabindex", "-1");
876
+ });
877
+ return () => {
878
+ candidates.forEach((candidate) => {
879
+ const prevTabIndex = candidate.dataset.tabindex;
880
+ candidate.setAttribute("tabindex", prevTabIndex);
881
+ });
882
+ };
883
+ }
884
+ function useResizeObserver(element, onResize, slot) {
885
+ const handleResize = (0, import_use_effect_event.useEffectEvent)(onResize, (0, import_internal.subSlot)(slot, "cb"));
886
+ (0, import_octane.useLayoutEffect)(
887
+ () => {
888
+ let rAF = 0;
889
+ if (element) {
890
+ if (typeof ResizeObserver === "undefined") {
891
+ const timer = window.setTimeout(handleResize, 0);
892
+ return () => window.clearTimeout(timer);
893
+ }
894
+ const resizeObserver = new ResizeObserver(() => {
895
+ cancelAnimationFrame(rAF);
896
+ rAF = window.requestAnimationFrame(handleResize);
897
+ });
898
+ resizeObserver.observe(element);
899
+ return () => {
900
+ window.cancelAnimationFrame(rAF);
901
+ resizeObserver.unobserve(element);
902
+ };
903
+ }
904
+ },
905
+ [element, handleResize],
906
+ (0, import_internal.subSlot)(slot, "e")
907
+ );
908
+ }
909
+ function getOpenState(open) {
910
+ return open ? "open" : "closed";
911
+ }
912
+ function makeTriggerId(baseId, value) {
913
+ return `${baseId}-trigger-${value}`;
914
+ }
915
+ function makeContentId(baseId, value) {
916
+ return `${baseId}-content-${value}`;
917
+ }
918
+ function whenMouse(handler) {
919
+ return (event) => event.pointerType === "mouse" ? handler(event) : void 0;
920
+ }
921
+ // Annotate the CommonJS export names for ESM import in node:
922
+ 0 && (module.exports = {
923
+ Content,
924
+ Indicator,
925
+ Item,
926
+ Link,
927
+ List,
928
+ NavigationMenu,
929
+ NavigationMenuContent,
930
+ NavigationMenuIndicator,
931
+ NavigationMenuItem,
932
+ NavigationMenuLink,
933
+ NavigationMenuList,
934
+ NavigationMenuSub,
935
+ NavigationMenuTrigger,
936
+ NavigationMenuViewport,
937
+ Root,
938
+ Sub,
939
+ Trigger,
940
+ Viewport,
941
+ createNavigationMenuScope
942
+ });