@radix-ui/react-navigation-menu 1.1.5-rc.9 → 1.2.0-rc.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.
package/dist/index.mjs CHANGED
@@ -1,879 +1,804 @@
1
- import $yHMN2$babelruntimehelpersesmextends from "@babel/runtime/helpers/esm/extends";
2
- import {forwardRef as $yHMN2$forwardRef, useState as $yHMN2$useState, useRef as $yHMN2$useRef, useCallback as $yHMN2$useCallback, useEffect as $yHMN2$useEffect, createElement as $yHMN2$createElement, Fragment as $yHMN2$Fragment, useMemo as $yHMN2$useMemo} from "react";
3
- import $yHMN2$reactdom from "react-dom";
4
- import {createContextScope as $yHMN2$createContextScope} from "@radix-ui/react-context";
5
- import {composeEventHandlers as $yHMN2$composeEventHandlers} from "@radix-ui/primitive";
6
- import {Primitive as $yHMN2$Primitive, dispatchDiscreteCustomEvent as $yHMN2$dispatchDiscreteCustomEvent} from "@radix-ui/react-primitive";
7
- import {useControllableState as $yHMN2$useControllableState} from "@radix-ui/react-use-controllable-state";
8
- import {useComposedRefs as $yHMN2$useComposedRefs, composeRefs as $yHMN2$composeRefs} from "@radix-ui/react-compose-refs";
9
- import {useDirection as $yHMN2$useDirection} from "@radix-ui/react-direction";
10
- import {Presence as $yHMN2$Presence} from "@radix-ui/react-presence";
11
- import {useId as $yHMN2$useId} from "@radix-ui/react-id";
12
- import {createCollection as $yHMN2$createCollection} from "@radix-ui/react-collection";
13
- import {DismissableLayer as $yHMN2$DismissableLayer} from "@radix-ui/react-dismissable-layer";
14
- import {usePrevious as $yHMN2$usePrevious} from "@radix-ui/react-use-previous";
15
- import {useLayoutEffect as $yHMN2$useLayoutEffect} from "@radix-ui/react-use-layout-effect";
16
- import {useCallbackRef as $yHMN2$useCallbackRef} from "@radix-ui/react-use-callback-ref";
17
- import {Root as $yHMN2$Root} from "@radix-ui/react-visually-hidden";
1
+ "use client";
18
2
 
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
- /* -------------------------------------------------------------------------------------------------
37
- * NavigationMenu
38
- * -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$var$NAVIGATION_MENU_NAME = 'NavigationMenu';
39
- const [$322c88a641701f3b$var$Collection, $322c88a641701f3b$var$useCollection, $322c88a641701f3b$var$createCollectionScope] = $yHMN2$createCollection($322c88a641701f3b$var$NAVIGATION_MENU_NAME);
40
- const [$322c88a641701f3b$var$FocusGroupCollection, $322c88a641701f3b$var$useFocusGroupCollection, $322c88a641701f3b$var$createFocusGroupCollectionScope] = $yHMN2$createCollection($322c88a641701f3b$var$NAVIGATION_MENU_NAME);
41
- const [$322c88a641701f3b$var$createNavigationMenuContext, $322c88a641701f3b$export$fb8ea5af8c9fcdf0] = $yHMN2$createContextScope($322c88a641701f3b$var$NAVIGATION_MENU_NAME, [
42
- $322c88a641701f3b$var$createCollectionScope,
43
- $322c88a641701f3b$var$createFocusGroupCollectionScope
44
- ]);
45
- const [$322c88a641701f3b$var$NavigationMenuProviderImpl, $322c88a641701f3b$var$useNavigationMenuContext] = $322c88a641701f3b$var$createNavigationMenuContext($322c88a641701f3b$var$NAVIGATION_MENU_NAME);
46
- const [$322c88a641701f3b$var$ViewportContentProvider, $322c88a641701f3b$var$useViewportContentContext] = $322c88a641701f3b$var$createNavigationMenuContext($322c88a641701f3b$var$NAVIGATION_MENU_NAME);
47
- const $322c88a641701f3b$export$5b2278cf1e8bcae2 = /*#__PURE__*/ $yHMN2$forwardRef((props, forwardedRef)=>{
48
- const { __scopeNavigationMenu: __scopeNavigationMenu , value: valueProp , onValueChange: onValueChange , defaultValue: defaultValue , delayDuration: delayDuration = 200 , skipDelayDuration: skipDelayDuration = 300 , orientation: orientation = 'horizontal' , dir: dir , ...NavigationMenuProps } = props;
49
- const [navigationMenu, setNavigationMenu] = $yHMN2$useState(null);
50
- const composedRef = $yHMN2$useComposedRefs(forwardedRef, (node)=>setNavigationMenu(node)
51
- );
52
- const direction = $yHMN2$useDirection(dir);
53
- const openTimerRef = $yHMN2$useRef(0);
54
- const closeTimerRef = $yHMN2$useRef(0);
55
- const skipDelayTimerRef = $yHMN2$useRef(0);
56
- const [isOpenDelayed, setIsOpenDelayed] = $yHMN2$useState(true);
57
- const [value1 = '', setValue] = $yHMN2$useControllableState({
58
- prop: valueProp,
59
- onChange: (value)=>{
60
- const isOpen = value !== '';
61
- const hasSkipDelayDuration = skipDelayDuration > 0;
62
- if (isOpen) {
63
- window.clearTimeout(skipDelayTimerRef.current);
64
- if (hasSkipDelayDuration) setIsOpenDelayed(false);
65
- } else {
66
- window.clearTimeout(skipDelayTimerRef.current);
67
- skipDelayTimerRef.current = window.setTimeout(()=>setIsOpenDelayed(true)
68
- , skipDelayDuration);
69
- }
70
- onValueChange === null || onValueChange === void 0 || onValueChange(value);
71
- },
72
- defaultProp: defaultValue
3
+ // packages/react/navigation-menu/src/NavigationMenu.tsx
4
+ import * as React from "react";
5
+ import ReactDOM from "react-dom";
6
+ import { createContextScope } from "@radix-ui/react-context";
7
+ import { composeEventHandlers } from "@radix-ui/primitive";
8
+ import { Primitive, dispatchDiscreteCustomEvent } from "@radix-ui/react-primitive";
9
+ import { useControllableState } from "@radix-ui/react-use-controllable-state";
10
+ import { composeRefs, useComposedRefs } from "@radix-ui/react-compose-refs";
11
+ import { useDirection } from "@radix-ui/react-direction";
12
+ import { Presence } from "@radix-ui/react-presence";
13
+ import { useId } from "@radix-ui/react-id";
14
+ import { createCollection } from "@radix-ui/react-collection";
15
+ import { DismissableLayer } from "@radix-ui/react-dismissable-layer";
16
+ import { usePrevious } from "@radix-ui/react-use-previous";
17
+ import { useLayoutEffect } from "@radix-ui/react-use-layout-effect";
18
+ import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
19
+ import * as VisuallyHiddenPrimitive from "@radix-ui/react-visually-hidden";
20
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
21
+ var NAVIGATION_MENU_NAME = "NavigationMenu";
22
+ var [Collection, useCollection, createCollectionScope] = createCollection(NAVIGATION_MENU_NAME);
23
+ var [FocusGroupCollection, useFocusGroupCollection, createFocusGroupCollectionScope] = createCollection(NAVIGATION_MENU_NAME);
24
+ var [createNavigationMenuContext, createNavigationMenuScope] = createContextScope(
25
+ NAVIGATION_MENU_NAME,
26
+ [createCollectionScope, createFocusGroupCollectionScope]
27
+ );
28
+ var [NavigationMenuProviderImpl, useNavigationMenuContext] = createNavigationMenuContext(NAVIGATION_MENU_NAME);
29
+ var [ViewportContentProvider, useViewportContentContext] = createNavigationMenuContext(NAVIGATION_MENU_NAME);
30
+ var NavigationMenu = React.forwardRef(
31
+ (props, forwardedRef) => {
32
+ const {
33
+ __scopeNavigationMenu,
34
+ value: valueProp,
35
+ onValueChange,
36
+ defaultValue,
37
+ delayDuration = 200,
38
+ skipDelayDuration = 300,
39
+ orientation = "horizontal",
40
+ dir,
41
+ ...NavigationMenuProps
42
+ } = props;
43
+ const [navigationMenu, setNavigationMenu] = React.useState(null);
44
+ const composedRef = useComposedRefs(forwardedRef, (node) => setNavigationMenu(node));
45
+ const direction = useDirection(dir);
46
+ const openTimerRef = React.useRef(0);
47
+ const closeTimerRef = React.useRef(0);
48
+ const skipDelayTimerRef = React.useRef(0);
49
+ const [isOpenDelayed, setIsOpenDelayed] = React.useState(true);
50
+ const [value = "", setValue] = useControllableState({
51
+ prop: valueProp,
52
+ onChange: (value2) => {
53
+ const isOpen = value2 !== "";
54
+ const hasSkipDelayDuration = skipDelayDuration > 0;
55
+ if (isOpen) {
56
+ window.clearTimeout(skipDelayTimerRef.current);
57
+ if (hasSkipDelayDuration) setIsOpenDelayed(false);
58
+ } else {
59
+ window.clearTimeout(skipDelayTimerRef.current);
60
+ skipDelayTimerRef.current = window.setTimeout(
61
+ () => setIsOpenDelayed(true),
62
+ skipDelayDuration
63
+ );
64
+ }
65
+ onValueChange?.(value2);
66
+ },
67
+ defaultProp: defaultValue
73
68
  });
74
- const startCloseTimer = $yHMN2$useCallback(()=>{
75
- window.clearTimeout(closeTimerRef.current);
76
- closeTimerRef.current = window.setTimeout(()=>setValue('')
77
- , 150);
78
- }, [
79
- setValue
80
- ]);
81
- const handleOpen = $yHMN2$useCallback((itemValue)=>{
69
+ const startCloseTimer = React.useCallback(() => {
70
+ window.clearTimeout(closeTimerRef.current);
71
+ closeTimerRef.current = window.setTimeout(() => setValue(""), 150);
72
+ }, [setValue]);
73
+ const handleOpen = React.useCallback(
74
+ (itemValue) => {
82
75
  window.clearTimeout(closeTimerRef.current);
83
76
  setValue(itemValue);
84
- }, [
85
- setValue
86
- ]);
87
- const handleDelayedOpen = $yHMN2$useCallback((itemValue)=>{
88
- const isOpenItem = value1 === itemValue;
89
- if (isOpenItem) // If the item is already open (e.g. we're transitioning from the content to the trigger)
90
- // then we want to clear the close timer immediately.
91
- window.clearTimeout(closeTimerRef.current);
92
- else openTimerRef.current = window.setTimeout(()=>{
77
+ },
78
+ [setValue]
79
+ );
80
+ const handleDelayedOpen = React.useCallback(
81
+ (itemValue) => {
82
+ const isOpenItem = value === itemValue;
83
+ if (isOpenItem) {
84
+ window.clearTimeout(closeTimerRef.current);
85
+ } else {
86
+ openTimerRef.current = window.setTimeout(() => {
93
87
  window.clearTimeout(closeTimerRef.current);
94
88
  setValue(itemValue);
95
- }, delayDuration);
96
- }, [
97
- value1,
98
- setValue,
99
- delayDuration
100
- ]);
101
- $yHMN2$useEffect(()=>{
102
- return ()=>{
103
- window.clearTimeout(openTimerRef.current);
104
- window.clearTimeout(closeTimerRef.current);
105
- window.clearTimeout(skipDelayTimerRef.current);
106
- };
89
+ }, delayDuration);
90
+ }
91
+ },
92
+ [value, setValue, delayDuration]
93
+ );
94
+ React.useEffect(() => {
95
+ return () => {
96
+ window.clearTimeout(openTimerRef.current);
97
+ window.clearTimeout(closeTimerRef.current);
98
+ window.clearTimeout(skipDelayTimerRef.current);
99
+ };
107
100
  }, []);
108
- return /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$NavigationMenuProvider, {
101
+ return /* @__PURE__ */ jsx(
102
+ NavigationMenuProvider,
103
+ {
109
104
  scope: __scopeNavigationMenu,
110
105
  isRootMenu: true,
111
- value: value1,
106
+ value,
112
107
  dir: direction,
113
- orientation: orientation,
108
+ orientation,
114
109
  rootNavigationMenu: navigationMenu,
115
- onTriggerEnter: (itemValue)=>{
116
- window.clearTimeout(openTimerRef.current);
117
- if (isOpenDelayed) handleDelayedOpen(itemValue);
118
- else handleOpen(itemValue);
110
+ onTriggerEnter: (itemValue) => {
111
+ window.clearTimeout(openTimerRef.current);
112
+ if (isOpenDelayed) handleDelayedOpen(itemValue);
113
+ else handleOpen(itemValue);
119
114
  },
120
- onTriggerLeave: ()=>{
121
- window.clearTimeout(openTimerRef.current);
122
- startCloseTimer();
115
+ onTriggerLeave: () => {
116
+ window.clearTimeout(openTimerRef.current);
117
+ startCloseTimer();
123
118
  },
124
- onContentEnter: ()=>window.clearTimeout(closeTimerRef.current)
125
- ,
119
+ onContentEnter: () => window.clearTimeout(closeTimerRef.current),
126
120
  onContentLeave: startCloseTimer,
127
- onItemSelect: (itemValue)=>{
128
- setValue((prevValue)=>prevValue === itemValue ? '' : itemValue
129
- );
121
+ onItemSelect: (itemValue) => {
122
+ setValue((prevValue) => prevValue === itemValue ? "" : itemValue);
130
123
  },
131
- onItemDismiss: ()=>setValue('')
132
- }, /*#__PURE__*/ $yHMN2$createElement($yHMN2$Primitive.nav, $yHMN2$babelruntimehelpersesmextends({
133
- "aria-label": "Main",
134
- "data-orientation": orientation,
135
- dir: direction
136
- }, NavigationMenuProps, {
137
- ref: composedRef
138
- })));
139
- });
140
- /*#__PURE__*/ Object.assign($322c88a641701f3b$export$5b2278cf1e8bcae2, {
141
- displayName: $322c88a641701f3b$var$NAVIGATION_MENU_NAME
142
- });
143
- /* -------------------------------------------------------------------------------------------------
144
- * NavigationMenuSub
145
- * -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$var$SUB_NAME = 'NavigationMenuSub';
146
- const $322c88a641701f3b$export$5958edd6c4ee7c79 = /*#__PURE__*/ $yHMN2$forwardRef((props, forwardedRef)=>{
147
- const { __scopeNavigationMenu: __scopeNavigationMenu , value: valueProp , onValueChange: onValueChange , defaultValue: defaultValue , orientation: orientation = 'horizontal' , ...subProps } = props;
148
- const context = $322c88a641701f3b$var$useNavigationMenuContext($322c88a641701f3b$var$SUB_NAME, __scopeNavigationMenu);
149
- const [value = '', setValue] = $yHMN2$useControllableState({
150
- prop: valueProp,
151
- onChange: onValueChange,
152
- defaultProp: defaultValue
124
+ onItemDismiss: () => setValue(""),
125
+ children: /* @__PURE__ */ jsx(
126
+ Primitive.nav,
127
+ {
128
+ "aria-label": "Main",
129
+ "data-orientation": orientation,
130
+ dir: direction,
131
+ ...NavigationMenuProps,
132
+ ref: composedRef
133
+ }
134
+ )
135
+ }
136
+ );
137
+ }
138
+ );
139
+ NavigationMenu.displayName = NAVIGATION_MENU_NAME;
140
+ var SUB_NAME = "NavigationMenuSub";
141
+ var NavigationMenuSub = React.forwardRef(
142
+ (props, forwardedRef) => {
143
+ const {
144
+ __scopeNavigationMenu,
145
+ value: valueProp,
146
+ onValueChange,
147
+ defaultValue,
148
+ orientation = "horizontal",
149
+ ...subProps
150
+ } = props;
151
+ const context = useNavigationMenuContext(SUB_NAME, __scopeNavigationMenu);
152
+ const [value = "", setValue] = useControllableState({
153
+ prop: valueProp,
154
+ onChange: onValueChange,
155
+ defaultProp: defaultValue
153
156
  });
154
- return /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$NavigationMenuProvider, {
157
+ return /* @__PURE__ */ jsx(
158
+ NavigationMenuProvider,
159
+ {
155
160
  scope: __scopeNavigationMenu,
156
161
  isRootMenu: false,
157
- value: value,
162
+ value,
158
163
  dir: context.dir,
159
- orientation: orientation,
164
+ orientation,
160
165
  rootNavigationMenu: context.rootNavigationMenu,
161
- onTriggerEnter: (itemValue)=>setValue(itemValue)
162
- ,
163
- onItemSelect: (itemValue)=>setValue(itemValue)
164
- ,
165
- onItemDismiss: ()=>setValue('')
166
- }, /*#__PURE__*/ $yHMN2$createElement($yHMN2$Primitive.div, $yHMN2$babelruntimehelpersesmextends({
167
- "data-orientation": orientation
168
- }, subProps, {
169
- ref: forwardedRef
170
- })));
171
- });
172
- /*#__PURE__*/ Object.assign($322c88a641701f3b$export$5958edd6c4ee7c79, {
173
- displayName: $322c88a641701f3b$var$SUB_NAME
174
- });
175
- /* -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$var$NavigationMenuProvider = (props)=>{
176
- const { scope: scope , isRootMenu: isRootMenu , rootNavigationMenu: rootNavigationMenu , dir: dir , orientation: orientation , children: children , value: value , onItemSelect: onItemSelect , onItemDismiss: onItemDismiss , onTriggerEnter: onTriggerEnter , onTriggerLeave: onTriggerLeave , onContentEnter: onContentEnter , onContentLeave: onContentLeave } = props;
177
- const [viewport, setViewport] = $yHMN2$useState(null);
178
- const [viewportContent, setViewportContent] = $yHMN2$useState(new Map());
179
- const [indicatorTrack, setIndicatorTrack] = $yHMN2$useState(null);
180
- return /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$NavigationMenuProviderImpl, {
181
- scope: scope,
182
- isRootMenu: isRootMenu,
183
- rootNavigationMenu: rootNavigationMenu,
184
- value: value,
185
- previousValue: $yHMN2$usePrevious(value),
186
- baseId: $yHMN2$useId(),
187
- dir: dir,
188
- orientation: orientation,
189
- viewport: viewport,
190
- onViewportChange: setViewport,
191
- indicatorTrack: indicatorTrack,
192
- onIndicatorTrackChange: setIndicatorTrack,
193
- onTriggerEnter: $yHMN2$useCallbackRef(onTriggerEnter),
194
- onTriggerLeave: $yHMN2$useCallbackRef(onTriggerLeave),
195
- onContentEnter: $yHMN2$useCallbackRef(onContentEnter),
196
- onContentLeave: $yHMN2$useCallbackRef(onContentLeave),
197
- onItemSelect: $yHMN2$useCallbackRef(onItemSelect),
198
- onItemDismiss: $yHMN2$useCallbackRef(onItemDismiss),
199
- onViewportContentChange: $yHMN2$useCallback((contentValue, contentData)=>{
200
- setViewportContent((prevContent)=>{
201
- prevContent.set(contentValue, contentData);
202
- return new Map(prevContent);
203
- });
204
- }, []),
205
- onViewportContentRemove: $yHMN2$useCallback((contentValue)=>{
206
- setViewportContent((prevContent)=>{
207
- if (!prevContent.has(contentValue)) return prevContent;
208
- prevContent.delete(contentValue);
209
- return new Map(prevContent);
210
- });
211
- }, [])
212
- }, /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$Collection.Provider, {
213
- scope: scope
214
- }, /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$ViewportContentProvider, {
215
- scope: scope,
216
- items: viewportContent
217
- }, children)));
166
+ onTriggerEnter: (itemValue) => setValue(itemValue),
167
+ onItemSelect: (itemValue) => setValue(itemValue),
168
+ onItemDismiss: () => setValue(""),
169
+ children: /* @__PURE__ */ jsx(Primitive.div, { "data-orientation": orientation, ...subProps, ref: forwardedRef })
170
+ }
171
+ );
172
+ }
173
+ );
174
+ NavigationMenuSub.displayName = SUB_NAME;
175
+ var NavigationMenuProvider = (props) => {
176
+ const {
177
+ scope,
178
+ isRootMenu,
179
+ rootNavigationMenu,
180
+ dir,
181
+ orientation,
182
+ children,
183
+ value,
184
+ onItemSelect,
185
+ onItemDismiss,
186
+ onTriggerEnter,
187
+ onTriggerLeave,
188
+ onContentEnter,
189
+ onContentLeave
190
+ } = props;
191
+ const [viewport, setViewport] = React.useState(null);
192
+ const [viewportContent, setViewportContent] = React.useState(/* @__PURE__ */ new Map());
193
+ const [indicatorTrack, setIndicatorTrack] = React.useState(null);
194
+ return /* @__PURE__ */ jsx(
195
+ NavigationMenuProviderImpl,
196
+ {
197
+ scope,
198
+ isRootMenu,
199
+ rootNavigationMenu,
200
+ value,
201
+ previousValue: usePrevious(value),
202
+ baseId: useId(),
203
+ dir,
204
+ orientation,
205
+ viewport,
206
+ onViewportChange: setViewport,
207
+ indicatorTrack,
208
+ onIndicatorTrackChange: setIndicatorTrack,
209
+ onTriggerEnter: useCallbackRef(onTriggerEnter),
210
+ onTriggerLeave: useCallbackRef(onTriggerLeave),
211
+ onContentEnter: useCallbackRef(onContentEnter),
212
+ onContentLeave: useCallbackRef(onContentLeave),
213
+ onItemSelect: useCallbackRef(onItemSelect),
214
+ onItemDismiss: useCallbackRef(onItemDismiss),
215
+ onViewportContentChange: React.useCallback((contentValue, contentData) => {
216
+ setViewportContent((prevContent) => {
217
+ prevContent.set(contentValue, contentData);
218
+ return new Map(prevContent);
219
+ });
220
+ }, []),
221
+ onViewportContentRemove: React.useCallback((contentValue) => {
222
+ setViewportContent((prevContent) => {
223
+ if (!prevContent.has(contentValue)) return prevContent;
224
+ prevContent.delete(contentValue);
225
+ return new Map(prevContent);
226
+ });
227
+ }, []),
228
+ children: /* @__PURE__ */ jsx(Collection.Provider, { scope, children: /* @__PURE__ */ jsx(ViewportContentProvider, { scope, items: viewportContent, children }) })
229
+ }
230
+ );
218
231
  };
219
- /* -------------------------------------------------------------------------------------------------
220
- * NavigationMenuList
221
- * -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$var$LIST_NAME = 'NavigationMenuList';
222
- const $322c88a641701f3b$export$c361068a95fd2286 = /*#__PURE__*/ $yHMN2$forwardRef((props, forwardedRef)=>{
223
- const { __scopeNavigationMenu: __scopeNavigationMenu , ...listProps } = props;
224
- const context = $322c88a641701f3b$var$useNavigationMenuContext($322c88a641701f3b$var$LIST_NAME, __scopeNavigationMenu);
225
- const list = /*#__PURE__*/ $yHMN2$createElement($yHMN2$Primitive.ul, $yHMN2$babelruntimehelpersesmextends({
226
- "data-orientation": context.orientation
227
- }, listProps, {
228
- ref: forwardedRef
229
- }));
230
- return /*#__PURE__*/ $yHMN2$createElement($yHMN2$Primitive.div, {
231
- style: {
232
- position: 'relative'
233
- },
234
- ref: context.onIndicatorTrackChange
235
- }, /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$Collection.Slot, {
236
- scope: __scopeNavigationMenu
237
- }, context.isRootMenu ? /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$FocusGroup, {
238
- asChild: true
239
- }, list) : list));
240
- });
241
- /*#__PURE__*/ Object.assign($322c88a641701f3b$export$c361068a95fd2286, {
242
- displayName: $322c88a641701f3b$var$LIST_NAME
243
- });
244
- /* -------------------------------------------------------------------------------------------------
245
- * NavigationMenuItem
246
- * -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$var$ITEM_NAME = 'NavigationMenuItem';
247
- const [$322c88a641701f3b$var$NavigationMenuItemContextProvider, $322c88a641701f3b$var$useNavigationMenuItemContext] = $322c88a641701f3b$var$createNavigationMenuContext($322c88a641701f3b$var$ITEM_NAME);
248
- const $322c88a641701f3b$export$ffdbb83a2de845c2 = /*#__PURE__*/ $yHMN2$forwardRef((props, forwardedRef)=>{
249
- const { __scopeNavigationMenu: __scopeNavigationMenu , value: valueProp , ...itemProps } = props;
250
- const autoValue = $yHMN2$useId(); // We need to provide an initial deterministic value as `useId` will return
251
- // empty string on the first render and we don't want to match our internal "closed" value.
252
- const value = valueProp || autoValue || 'LEGACY_REACT_AUTO_VALUE';
253
- const contentRef = $yHMN2$useRef(null);
254
- const triggerRef = $yHMN2$useRef(null);
255
- const focusProxyRef = $yHMN2$useRef(null);
256
- const restoreContentTabOrderRef = $yHMN2$useRef(()=>{});
257
- const wasEscapeCloseRef = $yHMN2$useRef(false);
258
- const handleContentEntry = $yHMN2$useCallback((side = 'start')=>{
259
- if (contentRef.current) {
260
- restoreContentTabOrderRef.current();
261
- const candidates = $322c88a641701f3b$var$getTabbableCandidates(contentRef.current);
262
- if (candidates.length) $322c88a641701f3b$var$focusFirst(side === 'start' ? candidates : candidates.reverse());
263
- }
232
+ var LIST_NAME = "NavigationMenuList";
233
+ var NavigationMenuList = React.forwardRef(
234
+ (props, forwardedRef) => {
235
+ const { __scopeNavigationMenu, ...listProps } = props;
236
+ const context = useNavigationMenuContext(LIST_NAME, __scopeNavigationMenu);
237
+ const list = /* @__PURE__ */ jsx(Primitive.ul, { "data-orientation": context.orientation, ...listProps, ref: forwardedRef });
238
+ return /* @__PURE__ */ jsx(Primitive.div, { style: { position: "relative" }, ref: context.onIndicatorTrackChange, children: /* @__PURE__ */ jsx(Collection.Slot, { scope: __scopeNavigationMenu, children: context.isRootMenu ? /* @__PURE__ */ jsx(FocusGroup, { asChild: true, children: list }) : list }) });
239
+ }
240
+ );
241
+ NavigationMenuList.displayName = LIST_NAME;
242
+ var ITEM_NAME = "NavigationMenuItem";
243
+ var [NavigationMenuItemContextProvider, useNavigationMenuItemContext] = createNavigationMenuContext(ITEM_NAME);
244
+ var NavigationMenuItem = React.forwardRef(
245
+ (props, forwardedRef) => {
246
+ const { __scopeNavigationMenu, value: valueProp, ...itemProps } = props;
247
+ const autoValue = useId();
248
+ const value = valueProp || autoValue || "LEGACY_REACT_AUTO_VALUE";
249
+ const contentRef = React.useRef(null);
250
+ const triggerRef = React.useRef(null);
251
+ const focusProxyRef = React.useRef(null);
252
+ const restoreContentTabOrderRef = React.useRef(() => {
253
+ });
254
+ const wasEscapeCloseRef = React.useRef(false);
255
+ const handleContentEntry = React.useCallback((side = "start") => {
256
+ if (contentRef.current) {
257
+ restoreContentTabOrderRef.current();
258
+ const candidates = getTabbableCandidates(contentRef.current);
259
+ if (candidates.length) focusFirst(side === "start" ? candidates : candidates.reverse());
260
+ }
264
261
  }, []);
265
- const handleContentExit = $yHMN2$useCallback(()=>{
266
- if (contentRef.current) {
267
- const candidates = $322c88a641701f3b$var$getTabbableCandidates(contentRef.current);
268
- if (candidates.length) restoreContentTabOrderRef.current = $322c88a641701f3b$var$removeFromTabOrder(candidates);
269
- }
262
+ const handleContentExit = React.useCallback(() => {
263
+ if (contentRef.current) {
264
+ const candidates = getTabbableCandidates(contentRef.current);
265
+ if (candidates.length) restoreContentTabOrderRef.current = removeFromTabOrder(candidates);
266
+ }
270
267
  }, []);
271
- return /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$NavigationMenuItemContextProvider, {
268
+ return /* @__PURE__ */ jsx(
269
+ NavigationMenuItemContextProvider,
270
+ {
272
271
  scope: __scopeNavigationMenu,
273
- value: value,
274
- triggerRef: triggerRef,
275
- contentRef: contentRef,
276
- focusProxyRef: focusProxyRef,
277
- wasEscapeCloseRef: wasEscapeCloseRef,
272
+ value,
273
+ triggerRef,
274
+ contentRef,
275
+ focusProxyRef,
276
+ wasEscapeCloseRef,
278
277
  onEntryKeyDown: handleContentEntry,
279
278
  onFocusProxyEnter: handleContentEntry,
280
279
  onRootContentClose: handleContentExit,
281
- onContentFocusOutside: handleContentExit
282
- }, /*#__PURE__*/ $yHMN2$createElement($yHMN2$Primitive.li, $yHMN2$babelruntimehelpersesmextends({}, itemProps, {
283
- ref: forwardedRef
284
- })));
285
- });
286
- /*#__PURE__*/ Object.assign($322c88a641701f3b$export$ffdbb83a2de845c2, {
287
- displayName: $322c88a641701f3b$var$ITEM_NAME
288
- });
289
- /* -------------------------------------------------------------------------------------------------
290
- * NavigationMenuTrigger
291
- * -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$var$TRIGGER_NAME = 'NavigationMenuTrigger';
292
- const $322c88a641701f3b$export$37fe8002734d8f2 = /*#__PURE__*/ $yHMN2$forwardRef((props, forwardedRef)=>{
293
- const { __scopeNavigationMenu: __scopeNavigationMenu , disabled: disabled , ...triggerProps } = props;
294
- const context = $322c88a641701f3b$var$useNavigationMenuContext($322c88a641701f3b$var$TRIGGER_NAME, props.__scopeNavigationMenu);
295
- const itemContext = $322c88a641701f3b$var$useNavigationMenuItemContext($322c88a641701f3b$var$TRIGGER_NAME, props.__scopeNavigationMenu);
296
- const ref = $yHMN2$useRef(null);
297
- const composedRefs = $yHMN2$useComposedRefs(ref, itemContext.triggerRef, forwardedRef);
298
- const triggerId = $322c88a641701f3b$var$makeTriggerId(context.baseId, itemContext.value);
299
- const contentId = $322c88a641701f3b$var$makeContentId(context.baseId, itemContext.value);
300
- const hasPointerMoveOpenedRef = $yHMN2$useRef(false);
301
- const wasClickCloseRef = $yHMN2$useRef(false);
302
- const open = itemContext.value === context.value;
303
- return /*#__PURE__*/ $yHMN2$createElement($yHMN2$Fragment, null, /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$Collection.ItemSlot, {
304
- scope: __scopeNavigationMenu,
305
- value: itemContext.value
306
- }, /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$FocusGroupItem, {
307
- asChild: true
308
- }, /*#__PURE__*/ $yHMN2$createElement($yHMN2$Primitive.button, $yHMN2$babelruntimehelpersesmextends({
280
+ onContentFocusOutside: handleContentExit,
281
+ children: /* @__PURE__ */ jsx(Primitive.li, { ...itemProps, ref: forwardedRef })
282
+ }
283
+ );
284
+ }
285
+ );
286
+ NavigationMenuItem.displayName = ITEM_NAME;
287
+ var TRIGGER_NAME = "NavigationMenuTrigger";
288
+ var NavigationMenuTrigger = React.forwardRef((props, forwardedRef) => {
289
+ const { __scopeNavigationMenu, disabled, ...triggerProps } = props;
290
+ const context = useNavigationMenuContext(TRIGGER_NAME, props.__scopeNavigationMenu);
291
+ const itemContext = useNavigationMenuItemContext(TRIGGER_NAME, props.__scopeNavigationMenu);
292
+ const ref = React.useRef(null);
293
+ const composedRefs = useComposedRefs(ref, itemContext.triggerRef, forwardedRef);
294
+ const triggerId = makeTriggerId(context.baseId, itemContext.value);
295
+ const contentId = makeContentId(context.baseId, itemContext.value);
296
+ const hasPointerMoveOpenedRef = React.useRef(false);
297
+ const wasClickCloseRef = React.useRef(false);
298
+ const open = itemContext.value === context.value;
299
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
300
+ /* @__PURE__ */ jsx(Collection.ItemSlot, { scope: __scopeNavigationMenu, value: itemContext.value, children: /* @__PURE__ */ jsx(FocusGroupItem, { asChild: true, children: /* @__PURE__ */ jsx(
301
+ Primitive.button,
302
+ {
309
303
  id: triggerId,
310
- disabled: disabled,
311
- "data-disabled": disabled ? '' : undefined,
312
- "data-state": $322c88a641701f3b$var$getOpenState(open),
304
+ disabled,
305
+ "data-disabled": disabled ? "" : void 0,
306
+ "data-state": getOpenState(open),
313
307
  "aria-expanded": open,
314
- "aria-controls": contentId
315
- }, triggerProps, {
308
+ "aria-controls": contentId,
309
+ ...triggerProps,
316
310
  ref: composedRefs,
317
- onPointerEnter: $yHMN2$composeEventHandlers(props.onPointerEnter, ()=>{
318
- wasClickCloseRef.current = false;
319
- itemContext.wasEscapeCloseRef.current = false;
311
+ onPointerEnter: composeEventHandlers(props.onPointerEnter, () => {
312
+ wasClickCloseRef.current = false;
313
+ itemContext.wasEscapeCloseRef.current = false;
320
314
  }),
321
- onPointerMove: $yHMN2$composeEventHandlers(props.onPointerMove, $322c88a641701f3b$var$whenMouse(()=>{
322
- if (disabled || wasClickCloseRef.current || itemContext.wasEscapeCloseRef.current || hasPointerMoveOpenedRef.current) return;
315
+ onPointerMove: composeEventHandlers(
316
+ props.onPointerMove,
317
+ whenMouse(() => {
318
+ if (disabled || wasClickCloseRef.current || itemContext.wasEscapeCloseRef.current || hasPointerMoveOpenedRef.current)
319
+ return;
323
320
  context.onTriggerEnter(itemContext.value);
324
321
  hasPointerMoveOpenedRef.current = true;
325
- })),
326
- onPointerLeave: $yHMN2$composeEventHandlers(props.onPointerLeave, $322c88a641701f3b$var$whenMouse(()=>{
322
+ })
323
+ ),
324
+ onPointerLeave: composeEventHandlers(
325
+ props.onPointerLeave,
326
+ whenMouse(() => {
327
327
  if (disabled) return;
328
328
  context.onTriggerLeave();
329
329
  hasPointerMoveOpenedRef.current = false;
330
- })),
331
- onClick: $yHMN2$composeEventHandlers(props.onClick, ()=>{
332
- context.onItemSelect(itemContext.value);
333
- wasClickCloseRef.current = open;
330
+ })
331
+ ),
332
+ onClick: composeEventHandlers(props.onClick, () => {
333
+ context.onItemSelect(itemContext.value);
334
+ wasClickCloseRef.current = open;
334
335
  }),
335
- onKeyDown: $yHMN2$composeEventHandlers(props.onKeyDown, (event)=>{
336
- const verticalEntryKey = context.dir === 'rtl' ? 'ArrowLeft' : 'ArrowRight';
337
- const entryKey = {
338
- horizontal: 'ArrowDown',
339
- vertical: verticalEntryKey
340
- }[context.orientation];
341
- if (open && event.key === entryKey) {
342
- itemContext.onEntryKeyDown(); // Prevent FocusGroupItem from handling the event
343
- event.preventDefault();
344
- }
336
+ onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
337
+ const verticalEntryKey = context.dir === "rtl" ? "ArrowLeft" : "ArrowRight";
338
+ const entryKey = { horizontal: "ArrowDown", vertical: verticalEntryKey }[context.orientation];
339
+ if (open && event.key === entryKey) {
340
+ itemContext.onEntryKeyDown();
341
+ event.preventDefault();
342
+ }
345
343
  })
346
- })))), open && /*#__PURE__*/ $yHMN2$createElement($yHMN2$Fragment, null, /*#__PURE__*/ $yHMN2$createElement($yHMN2$Root, {
347
- "aria-hidden": true,
348
- tabIndex: 0,
349
- ref: itemContext.focusProxyRef,
350
- onFocus: (event)=>{
344
+ }
345
+ ) }) }),
346
+ open && /* @__PURE__ */ jsxs(Fragment, { children: [
347
+ /* @__PURE__ */ jsx(
348
+ VisuallyHiddenPrimitive.Root,
349
+ {
350
+ "aria-hidden": true,
351
+ tabIndex: 0,
352
+ ref: itemContext.focusProxyRef,
353
+ onFocus: (event) => {
351
354
  const content = itemContext.contentRef.current;
352
355
  const prevFocusedElement = event.relatedTarget;
353
356
  const wasTriggerFocused = prevFocusedElement === ref.current;
354
- const wasFocusFromContent = content === null || content === void 0 ? void 0 : content.contains(prevFocusedElement);
355
- if (wasTriggerFocused || !wasFocusFromContent) itemContext.onFocusProxyEnter(wasTriggerFocused ? 'start' : 'end');
357
+ const wasFocusFromContent = content?.contains(prevFocusedElement);
358
+ if (wasTriggerFocused || !wasFocusFromContent) {
359
+ itemContext.onFocusProxyEnter(wasTriggerFocused ? "start" : "end");
360
+ }
361
+ }
356
362
  }
357
- }), context.viewport && /*#__PURE__*/ $yHMN2$createElement("span", {
358
- "aria-owns": contentId
359
- })));
363
+ ),
364
+ context.viewport && /* @__PURE__ */ jsx("span", { "aria-owns": contentId })
365
+ ] })
366
+ ] });
360
367
  });
361
- /*#__PURE__*/ Object.assign($322c88a641701f3b$export$37fe8002734d8f2, {
362
- displayName: $322c88a641701f3b$var$TRIGGER_NAME
363
- });
364
- /* -------------------------------------------------------------------------------------------------
365
- * NavigationMenuLink
366
- * -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$var$LINK_NAME = 'NavigationMenuLink';
367
- const $322c88a641701f3b$var$LINK_SELECT = 'navigationMenu.linkSelect';
368
- const $322c88a641701f3b$export$6893bf21536567da = /*#__PURE__*/ $yHMN2$forwardRef((props, forwardedRef)=>{
369
- const { __scopeNavigationMenu: __scopeNavigationMenu , active: active , onSelect: onSelect , ...linkProps } = props;
370
- return /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$FocusGroupItem, {
371
- asChild: true
372
- }, /*#__PURE__*/ $yHMN2$createElement($yHMN2$Primitive.a, $yHMN2$babelruntimehelpersesmextends({
373
- "data-active": active ? '' : undefined,
374
- "aria-current": active ? 'page' : undefined
375
- }, linkProps, {
368
+ NavigationMenuTrigger.displayName = TRIGGER_NAME;
369
+ var LINK_NAME = "NavigationMenuLink";
370
+ var LINK_SELECT = "navigationMenu.linkSelect";
371
+ var NavigationMenuLink = React.forwardRef(
372
+ (props, forwardedRef) => {
373
+ const { __scopeNavigationMenu, active, onSelect, ...linkProps } = props;
374
+ return /* @__PURE__ */ jsx(FocusGroupItem, { asChild: true, children: /* @__PURE__ */ jsx(
375
+ Primitive.a,
376
+ {
377
+ "data-active": active ? "" : void 0,
378
+ "aria-current": active ? "page" : void 0,
379
+ ...linkProps,
376
380
  ref: forwardedRef,
377
- onClick: $yHMN2$composeEventHandlers(props.onClick, (event1)=>{
378
- const target = event1.target;
379
- const linkSelectEvent = new CustomEvent($322c88a641701f3b$var$LINK_SELECT, {
381
+ onClick: composeEventHandlers(
382
+ props.onClick,
383
+ (event) => {
384
+ const target = event.target;
385
+ const linkSelectEvent = new CustomEvent(LINK_SELECT, {
386
+ bubbles: true,
387
+ cancelable: true
388
+ });
389
+ target.addEventListener(LINK_SELECT, (event2) => onSelect?.(event2), { once: true });
390
+ dispatchDiscreteCustomEvent(target, linkSelectEvent);
391
+ if (!linkSelectEvent.defaultPrevented && !event.metaKey) {
392
+ const rootContentDismissEvent = new CustomEvent(ROOT_CONTENT_DISMISS, {
380
393
  bubbles: true,
381
394
  cancelable: true
382
- });
383
- target.addEventListener($322c88a641701f3b$var$LINK_SELECT, (event)=>onSelect === null || onSelect === void 0 ? void 0 : onSelect(event)
384
- , {
385
- once: true
386
- });
387
- $yHMN2$dispatchDiscreteCustomEvent(target, linkSelectEvent);
388
- if (!linkSelectEvent.defaultPrevented && !event1.metaKey) {
389
- const rootContentDismissEvent = new CustomEvent($322c88a641701f3b$var$ROOT_CONTENT_DISMISS, {
390
- bubbles: true,
391
- cancelable: true
392
- });
393
- $yHMN2$dispatchDiscreteCustomEvent(target, rootContentDismissEvent);
395
+ });
396
+ dispatchDiscreteCustomEvent(target, rootContentDismissEvent);
394
397
  }
395
- }, {
396
- checkForDefaultPrevented: false
397
- })
398
- })));
398
+ },
399
+ { checkForDefaultPrevented: false }
400
+ )
401
+ }
402
+ ) });
403
+ }
404
+ );
405
+ NavigationMenuLink.displayName = LINK_NAME;
406
+ var INDICATOR_NAME = "NavigationMenuIndicator";
407
+ var NavigationMenuIndicator = React.forwardRef((props, forwardedRef) => {
408
+ const { forceMount, ...indicatorProps } = props;
409
+ const context = useNavigationMenuContext(INDICATOR_NAME, props.__scopeNavigationMenu);
410
+ const isVisible = Boolean(context.value);
411
+ return context.indicatorTrack ? ReactDOM.createPortal(
412
+ /* @__PURE__ */ jsx(Presence, { present: forceMount || isVisible, children: /* @__PURE__ */ jsx(NavigationMenuIndicatorImpl, { ...indicatorProps, ref: forwardedRef }) }),
413
+ context.indicatorTrack
414
+ ) : null;
399
415
  });
400
- /*#__PURE__*/ Object.assign($322c88a641701f3b$export$6893bf21536567da, {
401
- displayName: $322c88a641701f3b$var$LINK_NAME
416
+ NavigationMenuIndicator.displayName = INDICATOR_NAME;
417
+ var NavigationMenuIndicatorImpl = React.forwardRef((props, forwardedRef) => {
418
+ const { __scopeNavigationMenu, ...indicatorProps } = props;
419
+ const context = useNavigationMenuContext(INDICATOR_NAME, __scopeNavigationMenu);
420
+ const getItems = useCollection(__scopeNavigationMenu);
421
+ const [activeTrigger, setActiveTrigger] = React.useState(
422
+ null
423
+ );
424
+ const [position, setPosition] = React.useState(null);
425
+ const isHorizontal = context.orientation === "horizontal";
426
+ const isVisible = Boolean(context.value);
427
+ React.useEffect(() => {
428
+ const items = getItems();
429
+ const triggerNode = items.find((item) => item.value === context.value)?.ref.current;
430
+ if (triggerNode) setActiveTrigger(triggerNode);
431
+ }, [getItems, context.value]);
432
+ const handlePositionChange = () => {
433
+ if (activeTrigger) {
434
+ setPosition({
435
+ size: isHorizontal ? activeTrigger.offsetWidth : activeTrigger.offsetHeight,
436
+ offset: isHorizontal ? activeTrigger.offsetLeft : activeTrigger.offsetTop
437
+ });
438
+ }
439
+ };
440
+ useResizeObserver(activeTrigger, handlePositionChange);
441
+ useResizeObserver(context.indicatorTrack, handlePositionChange);
442
+ return position ? /* @__PURE__ */ jsx(
443
+ Primitive.div,
444
+ {
445
+ "aria-hidden": true,
446
+ "data-state": isVisible ? "visible" : "hidden",
447
+ "data-orientation": context.orientation,
448
+ ...indicatorProps,
449
+ ref: forwardedRef,
450
+ style: {
451
+ position: "absolute",
452
+ ...isHorizontal ? {
453
+ left: 0,
454
+ width: position.size + "px",
455
+ transform: `translateX(${position.offset}px)`
456
+ } : {
457
+ top: 0,
458
+ height: position.size + "px",
459
+ transform: `translateY(${position.offset}px)`
460
+ },
461
+ ...indicatorProps.style
462
+ }
463
+ }
464
+ ) : null;
402
465
  });
403
- /* -------------------------------------------------------------------------------------------------
404
- * NavigationMenuIndicator
405
- * -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$var$INDICATOR_NAME = 'NavigationMenuIndicator';
406
- const $322c88a641701f3b$export$8ddb526647c0d8fb = /*#__PURE__*/ $yHMN2$forwardRef((props, forwardedRef)=>{
407
- const { forceMount: forceMount , ...indicatorProps } = props;
408
- const context = $322c88a641701f3b$var$useNavigationMenuContext($322c88a641701f3b$var$INDICATOR_NAME, props.__scopeNavigationMenu);
409
- const isVisible = Boolean(context.value);
410
- return context.indicatorTrack ? /*#__PURE__*/ $yHMN2$reactdom.createPortal(/*#__PURE__*/ $yHMN2$createElement($yHMN2$Presence, {
411
- present: forceMount || isVisible
412
- }, /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$NavigationMenuIndicatorImpl, $yHMN2$babelruntimehelpersesmextends({}, indicatorProps, {
413
- ref: forwardedRef
414
- }))), context.indicatorTrack) : null;
466
+ var CONTENT_NAME = "NavigationMenuContent";
467
+ var NavigationMenuContent = React.forwardRef((props, forwardedRef) => {
468
+ const { forceMount, ...contentProps } = props;
469
+ const context = useNavigationMenuContext(CONTENT_NAME, props.__scopeNavigationMenu);
470
+ const itemContext = useNavigationMenuItemContext(CONTENT_NAME, props.__scopeNavigationMenu);
471
+ const composedRefs = useComposedRefs(itemContext.contentRef, forwardedRef);
472
+ const open = itemContext.value === context.value;
473
+ const commonProps = {
474
+ value: itemContext.value,
475
+ triggerRef: itemContext.triggerRef,
476
+ focusProxyRef: itemContext.focusProxyRef,
477
+ wasEscapeCloseRef: itemContext.wasEscapeCloseRef,
478
+ onContentFocusOutside: itemContext.onContentFocusOutside,
479
+ onRootContentClose: itemContext.onRootContentClose,
480
+ ...contentProps
481
+ };
482
+ return !context.viewport ? /* @__PURE__ */ jsx(Presence, { present: forceMount || open, children: /* @__PURE__ */ jsx(
483
+ NavigationMenuContentImpl,
484
+ {
485
+ "data-state": getOpenState(open),
486
+ ...commonProps,
487
+ ref: composedRefs,
488
+ onPointerEnter: composeEventHandlers(props.onPointerEnter, context.onContentEnter),
489
+ onPointerLeave: composeEventHandlers(
490
+ props.onPointerLeave,
491
+ whenMouse(context.onContentLeave)
492
+ ),
493
+ style: {
494
+ // Prevent interaction when animating out
495
+ pointerEvents: !open && context.isRootMenu ? "none" : void 0,
496
+ ...commonProps.style
497
+ }
498
+ }
499
+ ) }) : /* @__PURE__ */ jsx(ViewportContentMounter, { forceMount, ...commonProps, ref: composedRefs });
415
500
  });
416
- /*#__PURE__*/ Object.assign($322c88a641701f3b$export$8ddb526647c0d8fb, {
417
- displayName: $322c88a641701f3b$var$INDICATOR_NAME
501
+ NavigationMenuContent.displayName = CONTENT_NAME;
502
+ var ViewportContentMounter = React.forwardRef((props, forwardedRef) => {
503
+ const context = useNavigationMenuContext(CONTENT_NAME, props.__scopeNavigationMenu);
504
+ const { onViewportContentChange, onViewportContentRemove } = context;
505
+ useLayoutEffect(() => {
506
+ onViewportContentChange(props.value, {
507
+ ref: forwardedRef,
508
+ ...props
509
+ });
510
+ }, [props, forwardedRef, onViewportContentChange]);
511
+ useLayoutEffect(() => {
512
+ return () => onViewportContentRemove(props.value);
513
+ }, [props.value, onViewportContentRemove]);
514
+ return null;
418
515
  });
419
- const $322c88a641701f3b$var$NavigationMenuIndicatorImpl = /*#__PURE__*/ $yHMN2$forwardRef((props, forwardedRef)=>{
420
- const { __scopeNavigationMenu: __scopeNavigationMenu , ...indicatorProps } = props;
421
- const context = $322c88a641701f3b$var$useNavigationMenuContext($322c88a641701f3b$var$INDICATOR_NAME, __scopeNavigationMenu);
422
- const getItems = $322c88a641701f3b$var$useCollection(__scopeNavigationMenu);
423
- const [activeTrigger, setActiveTrigger] = $yHMN2$useState(null);
424
- const [position, setPosition] = $yHMN2$useState(null);
425
- const isHorizontal = context.orientation === 'horizontal';
426
- const isVisible = Boolean(context.value);
427
- $yHMN2$useEffect(()=>{
428
- var _items$find;
429
- const items = getItems();
430
- const triggerNode = (_items$find = items.find((item)=>item.value === context.value
431
- )) === null || _items$find === void 0 ? void 0 : _items$find.ref.current;
432
- if (triggerNode) setActiveTrigger(triggerNode);
433
- }, [
434
- getItems,
435
- context.value
436
- ]);
437
- /**
438
- * Update position when the indicator or parent track size changes
439
- */ const handlePositionChange = ()=>{
440
- if (activeTrigger) setPosition({
441
- size: isHorizontal ? activeTrigger.offsetWidth : activeTrigger.offsetHeight,
442
- offset: isHorizontal ? activeTrigger.offsetLeft : activeTrigger.offsetTop
516
+ var ROOT_CONTENT_DISMISS = "navigationMenu.rootContentDismiss";
517
+ var NavigationMenuContentImpl = React.forwardRef((props, forwardedRef) => {
518
+ const {
519
+ __scopeNavigationMenu,
520
+ value,
521
+ triggerRef,
522
+ focusProxyRef,
523
+ wasEscapeCloseRef,
524
+ onRootContentClose,
525
+ onContentFocusOutside,
526
+ ...contentProps
527
+ } = props;
528
+ const context = useNavigationMenuContext(CONTENT_NAME, __scopeNavigationMenu);
529
+ const ref = React.useRef(null);
530
+ const composedRefs = useComposedRefs(ref, forwardedRef);
531
+ const triggerId = makeTriggerId(context.baseId, value);
532
+ const contentId = makeContentId(context.baseId, value);
533
+ const getItems = useCollection(__scopeNavigationMenu);
534
+ const prevMotionAttributeRef = React.useRef(null);
535
+ const { onItemDismiss } = context;
536
+ React.useEffect(() => {
537
+ const content = ref.current;
538
+ if (context.isRootMenu && content) {
539
+ const handleClose = () => {
540
+ onItemDismiss();
541
+ onRootContentClose();
542
+ if (content.contains(document.activeElement)) triggerRef.current?.focus();
543
+ };
544
+ content.addEventListener(ROOT_CONTENT_DISMISS, handleClose);
545
+ return () => content.removeEventListener(ROOT_CONTENT_DISMISS, handleClose);
546
+ }
547
+ }, [context.isRootMenu, props.value, triggerRef, onItemDismiss, onRootContentClose]);
548
+ const motionAttribute = React.useMemo(() => {
549
+ const items = getItems();
550
+ const values = items.map((item) => item.value);
551
+ if (context.dir === "rtl") values.reverse();
552
+ const index = values.indexOf(context.value);
553
+ const prevIndex = values.indexOf(context.previousValue);
554
+ const isSelected = value === context.value;
555
+ const wasSelected = prevIndex === values.indexOf(value);
556
+ if (!isSelected && !wasSelected) return prevMotionAttributeRef.current;
557
+ const attribute = (() => {
558
+ if (index !== prevIndex) {
559
+ if (isSelected && prevIndex !== -1) return index > prevIndex ? "from-end" : "from-start";
560
+ if (wasSelected && index !== -1) return index > prevIndex ? "to-start" : "to-end";
561
+ }
562
+ return null;
563
+ })();
564
+ prevMotionAttributeRef.current = attribute;
565
+ return attribute;
566
+ }, [context.previousValue, context.value, context.dir, getItems, value]);
567
+ return /* @__PURE__ */ jsx(FocusGroup, { asChild: true, children: /* @__PURE__ */ jsx(
568
+ DismissableLayer,
569
+ {
570
+ id: contentId,
571
+ "aria-labelledby": triggerId,
572
+ "data-motion": motionAttribute,
573
+ "data-orientation": context.orientation,
574
+ ...contentProps,
575
+ ref: composedRefs,
576
+ disableOutsidePointerEvents: false,
577
+ onDismiss: () => {
578
+ const rootContentDismissEvent = new Event(ROOT_CONTENT_DISMISS, {
579
+ bubbles: true,
580
+ cancelable: true
443
581
  });
444
- };
445
- $322c88a641701f3b$var$useResizeObserver(activeTrigger, handlePositionChange);
446
- $322c88a641701f3b$var$useResizeObserver(context.indicatorTrack, handlePositionChange); // We need to wait for the indicator position to be available before rendering to
447
- // snap immediately into position rather than transitioning from initial
448
- return position ? /*#__PURE__*/ $yHMN2$createElement($yHMN2$Primitive.div, $yHMN2$babelruntimehelpersesmextends({
449
- "aria-hidden": true,
450
- "data-state": isVisible ? 'visible' : 'hidden',
451
- "data-orientation": context.orientation
452
- }, indicatorProps, {
453
- ref: forwardedRef,
454
- style: {
455
- position: 'absolute',
456
- ...isHorizontal ? {
457
- left: 0,
458
- width: position.size + 'px',
459
- transform: `translateX(${position.offset}px)`
460
- } : {
461
- top: 0,
462
- height: position.size + 'px',
463
- transform: `translateY(${position.offset}px)`
464
- },
465
- ...indicatorProps.style
582
+ ref.current?.dispatchEvent(rootContentDismissEvent);
583
+ },
584
+ onFocusOutside: composeEventHandlers(props.onFocusOutside, (event) => {
585
+ onContentFocusOutside();
586
+ const target = event.target;
587
+ if (context.rootNavigationMenu?.contains(target)) event.preventDefault();
588
+ }),
589
+ onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => {
590
+ const target = event.target;
591
+ const isTrigger = getItems().some((item) => item.ref.current?.contains(target));
592
+ const isRootViewport = context.isRootMenu && context.viewport?.contains(target);
593
+ if (isTrigger || isRootViewport || !context.isRootMenu) event.preventDefault();
594
+ }),
595
+ onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
596
+ const isMetaKey = event.altKey || event.ctrlKey || event.metaKey;
597
+ const isTabKey = event.key === "Tab" && !isMetaKey;
598
+ if (isTabKey) {
599
+ const candidates = getTabbableCandidates(event.currentTarget);
600
+ const focusedElement = document.activeElement;
601
+ const index = candidates.findIndex((candidate) => candidate === focusedElement);
602
+ const isMovingBackwards = event.shiftKey;
603
+ const nextCandidates = isMovingBackwards ? candidates.slice(0, index).reverse() : candidates.slice(index + 1, candidates.length);
604
+ if (focusFirst(nextCandidates)) {
605
+ event.preventDefault();
606
+ } else {
607
+ focusProxyRef.current?.focus();
608
+ }
466
609
  }
467
- })) : null;
610
+ }),
611
+ onEscapeKeyDown: composeEventHandlers(props.onEscapeKeyDown, (event) => {
612
+ wasEscapeCloseRef.current = true;
613
+ })
614
+ }
615
+ ) });
468
616
  });
469
- /* -------------------------------------------------------------------------------------------------
470
- * NavigationMenuContent
471
- * -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$var$CONTENT_NAME = 'NavigationMenuContent';
472
- const $322c88a641701f3b$export$38e00e996c2f93f7 = /*#__PURE__*/ $yHMN2$forwardRef((props, forwardedRef)=>{
473
- const { forceMount: forceMount , ...contentProps } = props;
474
- const context = $322c88a641701f3b$var$useNavigationMenuContext($322c88a641701f3b$var$CONTENT_NAME, props.__scopeNavigationMenu);
475
- const itemContext = $322c88a641701f3b$var$useNavigationMenuItemContext($322c88a641701f3b$var$CONTENT_NAME, props.__scopeNavigationMenu);
476
- const composedRefs = $yHMN2$useComposedRefs(itemContext.contentRef, forwardedRef);
477
- const open = itemContext.value === context.value;
478
- const commonProps = {
479
- value: itemContext.value,
480
- triggerRef: itemContext.triggerRef,
481
- focusProxyRef: itemContext.focusProxyRef,
482
- wasEscapeCloseRef: itemContext.wasEscapeCloseRef,
483
- onContentFocusOutside: itemContext.onContentFocusOutside,
484
- onRootContentClose: itemContext.onRootContentClose,
485
- ...contentProps
486
- };
487
- return !context.viewport ? /*#__PURE__*/ $yHMN2$createElement($yHMN2$Presence, {
488
- present: forceMount || open
489
- }, /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$NavigationMenuContentImpl, $yHMN2$babelruntimehelpersesmextends({
490
- "data-state": $322c88a641701f3b$var$getOpenState(open)
491
- }, commonProps, {
492
- ref: composedRefs,
493
- onPointerEnter: $yHMN2$composeEventHandlers(props.onPointerEnter, context.onContentEnter),
494
- onPointerLeave: $yHMN2$composeEventHandlers(props.onPointerLeave, $322c88a641701f3b$var$whenMouse(context.onContentLeave)),
495
- style: {
496
- // Prevent interaction when animating out
497
- pointerEvents: !open && context.isRootMenu ? 'none' : undefined,
498
- ...commonProps.style
499
- }
500
- }))) : /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$ViewportContentMounter, $yHMN2$babelruntimehelpersesmextends({
501
- forceMount: forceMount
502
- }, commonProps, {
503
- ref: composedRefs
504
- }));
617
+ var VIEWPORT_NAME = "NavigationMenuViewport";
618
+ var NavigationMenuViewport = React.forwardRef((props, forwardedRef) => {
619
+ const { forceMount, ...viewportProps } = props;
620
+ const context = useNavigationMenuContext(VIEWPORT_NAME, props.__scopeNavigationMenu);
621
+ const open = Boolean(context.value);
622
+ return /* @__PURE__ */ jsx(Presence, { present: forceMount || open, children: /* @__PURE__ */ jsx(NavigationMenuViewportImpl, { ...viewportProps, ref: forwardedRef }) });
505
623
  });
506
- /*#__PURE__*/ Object.assign($322c88a641701f3b$export$38e00e996c2f93f7, {
507
- displayName: $322c88a641701f3b$var$CONTENT_NAME
508
- });
509
- /* -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$var$ViewportContentMounter = /*#__PURE__*/ $yHMN2$forwardRef((props, forwardedRef)=>{
510
- const context = $322c88a641701f3b$var$useNavigationMenuContext($322c88a641701f3b$var$CONTENT_NAME, props.__scopeNavigationMenu);
511
- const { onViewportContentChange: onViewportContentChange , onViewportContentRemove: onViewportContentRemove } = context;
512
- $yHMN2$useLayoutEffect(()=>{
513
- onViewportContentChange(props.value, {
514
- ref: forwardedRef,
515
- ...props
516
- });
517
- }, [
518
- props,
519
- forwardedRef,
520
- onViewportContentChange
521
- ]);
522
- $yHMN2$useLayoutEffect(()=>{
523
- return ()=>onViewportContentRemove(props.value)
524
- ;
525
- }, [
526
- props.value,
527
- onViewportContentRemove
528
- ]); // Content is proxied into the viewport
529
- return null;
530
- });
531
- /* -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$var$ROOT_CONTENT_DISMISS = 'navigationMenu.rootContentDismiss';
532
- const $322c88a641701f3b$var$NavigationMenuContentImpl = /*#__PURE__*/ $yHMN2$forwardRef((props, forwardedRef)=>{
533
- const { __scopeNavigationMenu: __scopeNavigationMenu , value: value , triggerRef: triggerRef , focusProxyRef: focusProxyRef , wasEscapeCloseRef: wasEscapeCloseRef , onRootContentClose: onRootContentClose , onContentFocusOutside: onContentFocusOutside , ...contentProps } = props;
534
- const context = $322c88a641701f3b$var$useNavigationMenuContext($322c88a641701f3b$var$CONTENT_NAME, __scopeNavigationMenu);
535
- const ref = $yHMN2$useRef(null);
536
- const composedRefs = $yHMN2$useComposedRefs(ref, forwardedRef);
537
- const triggerId = $322c88a641701f3b$var$makeTriggerId(context.baseId, value);
538
- const contentId = $322c88a641701f3b$var$makeContentId(context.baseId, value);
539
- const getItems = $322c88a641701f3b$var$useCollection(__scopeNavigationMenu);
540
- const prevMotionAttributeRef = $yHMN2$useRef(null);
541
- const { onItemDismiss: onItemDismiss } = context;
542
- $yHMN2$useEffect(()=>{
543
- const content = ref.current; // Bubble dismiss to the root content node and focus its trigger
544
- if (context.isRootMenu && content) {
545
- const handleClose = ()=>{
546
- var _triggerRef$current;
547
- onItemDismiss();
548
- onRootContentClose();
549
- if (content.contains(document.activeElement)) (_triggerRef$current = triggerRef.current) === null || _triggerRef$current === void 0 || _triggerRef$current.focus();
550
- };
551
- content.addEventListener($322c88a641701f3b$var$ROOT_CONTENT_DISMISS, handleClose);
552
- return ()=>content.removeEventListener($322c88a641701f3b$var$ROOT_CONTENT_DISMISS, handleClose)
553
- ;
554
- }
555
- }, [
556
- context.isRootMenu,
557
- props.value,
558
- triggerRef,
559
- onItemDismiss,
560
- onRootContentClose
561
- ]);
562
- const motionAttribute = $yHMN2$useMemo(()=>{
563
- const items = getItems();
564
- const values = items.map((item)=>item.value
565
- );
566
- if (context.dir === 'rtl') values.reverse();
567
- const index = values.indexOf(context.value);
568
- const prevIndex = values.indexOf(context.previousValue);
569
- const isSelected = value === context.value;
570
- const wasSelected = prevIndex === values.indexOf(value); // We only want to update selected and the last selected content
571
- // this avoids animations being interrupted outside of that range
572
- if (!isSelected && !wasSelected) return prevMotionAttributeRef.current;
573
- const attribute = (()=>{
574
- // Don't provide a direction on the initial open
575
- if (index !== prevIndex) {
576
- // If we're moving to this item from another
577
- if (isSelected && prevIndex !== -1) return index > prevIndex ? 'from-end' : 'from-start'; // If we're leaving this item for another
578
- if (wasSelected && index !== -1) return index > prevIndex ? 'to-start' : 'to-end';
579
- } // Otherwise we're entering from closed or leaving the list
580
- // entirely and should not animate in any direction
581
- return null;
582
- })();
583
- prevMotionAttributeRef.current = attribute;
584
- return attribute;
585
- }, [
586
- context.previousValue,
587
- context.value,
588
- context.dir,
589
- getItems,
590
- value
591
- ]);
592
- return /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$FocusGroup, {
593
- asChild: true
594
- }, /*#__PURE__*/ $yHMN2$createElement($yHMN2$DismissableLayer, $yHMN2$babelruntimehelpersesmextends({
595
- id: contentId,
596
- "aria-labelledby": triggerId,
597
- "data-motion": motionAttribute,
598
- "data-orientation": context.orientation
599
- }, contentProps, {
600
- ref: composedRefs,
601
- disableOutsidePointerEvents: false,
602
- onDismiss: ()=>{
603
- var _ref$current;
604
- const rootContentDismissEvent = new Event($322c88a641701f3b$var$ROOT_CONTENT_DISMISS, {
605
- bubbles: true,
606
- cancelable: true
607
- });
608
- (_ref$current = ref.current) === null || _ref$current === void 0 || _ref$current.dispatchEvent(rootContentDismissEvent);
609
- },
610
- onFocusOutside: $yHMN2$composeEventHandlers(props.onFocusOutside, (event)=>{
611
- var _context$rootNavigati;
612
- onContentFocusOutside();
613
- const target = event.target; // Only dismiss content when focus moves outside of the menu
614
- if ((_context$rootNavigati = context.rootNavigationMenu) !== null && _context$rootNavigati !== void 0 && _context$rootNavigati.contains(target)) event.preventDefault();
615
- }),
616
- onPointerDownOutside: $yHMN2$composeEventHandlers(props.onPointerDownOutside, (event)=>{
617
- var _context$viewport;
618
- const target = event.target;
619
- const isTrigger = getItems().some((item)=>{
620
- var _item$ref$current;
621
- return (_item$ref$current = item.ref.current) === null || _item$ref$current === void 0 ? void 0 : _item$ref$current.contains(target);
622
- });
623
- const isRootViewport = context.isRootMenu && ((_context$viewport = context.viewport) === null || _context$viewport === void 0 ? void 0 : _context$viewport.contains(target));
624
- if (isTrigger || isRootViewport || !context.isRootMenu) event.preventDefault();
625
- }),
626
- onKeyDown: $yHMN2$composeEventHandlers(props.onKeyDown, (event)=>{
627
- const isMetaKey = event.altKey || event.ctrlKey || event.metaKey;
628
- const isTabKey = event.key === 'Tab' && !isMetaKey;
629
- if (isTabKey) {
630
- const candidates = $322c88a641701f3b$var$getTabbableCandidates(event.currentTarget);
631
- const focusedElement = document.activeElement;
632
- const index = candidates.findIndex((candidate)=>candidate === focusedElement
633
- );
634
- const isMovingBackwards = event.shiftKey;
635
- const nextCandidates = isMovingBackwards ? candidates.slice(0, index).reverse() : candidates.slice(index + 1, candidates.length);
636
- if ($322c88a641701f3b$var$focusFirst(nextCandidates)) // prevent browser tab keydown because we've handled focus
637
- event.preventDefault();
638
- else {
639
- var _focusProxyRef$curren;
640
- // If we can't focus that means we're at the edges
641
- // so focus the proxy and let browser handle
642
- // tab/shift+tab keypress on the proxy instead
643
- (_focusProxyRef$curren = focusProxyRef.current) === null || _focusProxyRef$curren === void 0 || _focusProxyRef$curren.focus();
644
- }
645
- }
646
- }),
647
- onEscapeKeyDown: $yHMN2$composeEventHandlers(props.onEscapeKeyDown, (event)=>{
648
- // prevent the dropdown from reopening
649
- // after the escape key has been pressed
650
- wasEscapeCloseRef.current = true;
651
- })
652
- })));
653
- });
654
- /* -------------------------------------------------------------------------------------------------
655
- * NavigationMenuViewport
656
- * -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$var$VIEWPORT_NAME = 'NavigationMenuViewport';
657
- const $322c88a641701f3b$export$ee880b97cc6d44a5 = /*#__PURE__*/ $yHMN2$forwardRef((props, forwardedRef)=>{
658
- const { forceMount: forceMount , ...viewportProps } = props;
659
- const context = $322c88a641701f3b$var$useNavigationMenuContext($322c88a641701f3b$var$VIEWPORT_NAME, props.__scopeNavigationMenu);
660
- const open = Boolean(context.value);
661
- return /*#__PURE__*/ $yHMN2$createElement($yHMN2$Presence, {
662
- present: forceMount || open
663
- }, /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$NavigationMenuViewportImpl, $yHMN2$babelruntimehelpersesmextends({}, viewportProps, {
664
- ref: forwardedRef
665
- })));
666
- });
667
- /*#__PURE__*/ Object.assign($322c88a641701f3b$export$ee880b97cc6d44a5, {
668
- displayName: $322c88a641701f3b$var$VIEWPORT_NAME
669
- });
670
- /* -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$var$NavigationMenuViewportImpl = /*#__PURE__*/ $yHMN2$forwardRef((props1, forwardedRef)=>{
671
- const { __scopeNavigationMenu: __scopeNavigationMenu , children: children , ...viewportImplProps } = props1;
672
- const context = $322c88a641701f3b$var$useNavigationMenuContext($322c88a641701f3b$var$VIEWPORT_NAME, __scopeNavigationMenu);
673
- const composedRefs = $yHMN2$useComposedRefs(forwardedRef, context.onViewportChange);
674
- const viewportContentContext = $322c88a641701f3b$var$useViewportContentContext($322c88a641701f3b$var$CONTENT_NAME, props1.__scopeNavigationMenu);
675
- const [size, setSize] = $yHMN2$useState(null);
676
- const [content, setContent] = $yHMN2$useState(null);
677
- const viewportWidth = size ? (size === null || size === void 0 ? void 0 : size.width) + 'px' : undefined;
678
- const viewportHeight = size ? (size === null || size === void 0 ? void 0 : size.height) + 'px' : undefined;
679
- const open = Boolean(context.value); // We persist the last active content value as the viewport may be animating out
680
- // and we want the content to remain mounted for the lifecycle of the viewport.
681
- const activeContentValue = open ? context.value : context.previousValue;
682
- /**
683
- * Update viewport size to match the active content node.
684
- * We prefer offset dimensions over `getBoundingClientRect` as the latter respects CSS transform.
685
- * For example, if content animates in from `scale(0.5)` the dimensions would be anything
686
- * from `0.5` to `1` of the intended size.
687
- */ const handleSizeChange = ()=>{
688
- if (content) setSize({
689
- width: content.offsetWidth,
690
- height: content.offsetHeight
691
- });
692
- };
693
- $322c88a641701f3b$var$useResizeObserver(content, handleSizeChange);
694
- return /*#__PURE__*/ $yHMN2$createElement($yHMN2$Primitive.div, $yHMN2$babelruntimehelpersesmextends({
695
- "data-state": $322c88a641701f3b$var$getOpenState(open),
696
- "data-orientation": context.orientation
697
- }, viewportImplProps, {
698
- ref: composedRefs,
699
- style: {
700
- // Prevent interaction when animating out
701
- pointerEvents: !open && context.isRootMenu ? 'none' : undefined,
702
- ['--radix-navigation-menu-viewport-width']: viewportWidth,
703
- ['--radix-navigation-menu-viewport-height']: viewportHeight,
704
- ...viewportImplProps.style
705
- },
706
- onPointerEnter: $yHMN2$composeEventHandlers(props1.onPointerEnter, context.onContentEnter),
707
- onPointerLeave: $yHMN2$composeEventHandlers(props1.onPointerLeave, $322c88a641701f3b$var$whenMouse(context.onContentLeave))
708
- }), Array.from(viewportContentContext.items).map(([value, { ref: ref , forceMount: forceMount , ...props }])=>{
624
+ NavigationMenuViewport.displayName = VIEWPORT_NAME;
625
+ var NavigationMenuViewportImpl = React.forwardRef((props, forwardedRef) => {
626
+ const { __scopeNavigationMenu, children, ...viewportImplProps } = props;
627
+ const context = useNavigationMenuContext(VIEWPORT_NAME, __scopeNavigationMenu);
628
+ const composedRefs = useComposedRefs(forwardedRef, context.onViewportChange);
629
+ const viewportContentContext = useViewportContentContext(
630
+ CONTENT_NAME,
631
+ props.__scopeNavigationMenu
632
+ );
633
+ const [size, setSize] = React.useState(null);
634
+ const [content, setContent] = React.useState(null);
635
+ const viewportWidth = size ? size?.width + "px" : void 0;
636
+ const viewportHeight = size ? size?.height + "px" : void 0;
637
+ const open = Boolean(context.value);
638
+ const activeContentValue = open ? context.value : context.previousValue;
639
+ const handleSizeChange = () => {
640
+ if (content) setSize({ width: content.offsetWidth, height: content.offsetHeight });
641
+ };
642
+ useResizeObserver(content, handleSizeChange);
643
+ return /* @__PURE__ */ jsx(
644
+ Primitive.div,
645
+ {
646
+ "data-state": getOpenState(open),
647
+ "data-orientation": context.orientation,
648
+ ...viewportImplProps,
649
+ ref: composedRefs,
650
+ style: {
651
+ // Prevent interaction when animating out
652
+ pointerEvents: !open && context.isRootMenu ? "none" : void 0,
653
+ ["--radix-navigation-menu-viewport-width"]: viewportWidth,
654
+ ["--radix-navigation-menu-viewport-height"]: viewportHeight,
655
+ ...viewportImplProps.style
656
+ },
657
+ onPointerEnter: composeEventHandlers(props.onPointerEnter, context.onContentEnter),
658
+ onPointerLeave: composeEventHandlers(props.onPointerLeave, whenMouse(context.onContentLeave)),
659
+ children: Array.from(viewportContentContext.items).map(([value, { ref, forceMount, ...props2 }]) => {
709
660
  const isActive = activeContentValue === value;
710
- return /*#__PURE__*/ $yHMN2$createElement($yHMN2$Presence, {
711
- key: value,
712
- present: forceMount || isActive
713
- }, /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$NavigationMenuContentImpl, $yHMN2$babelruntimehelpersesmextends({}, props, {
714
- ref: $yHMN2$composeRefs(ref, (node)=>{
715
- // We only want to update the stored node when another is available
716
- // as we need to smoothly transition between them.
717
- if (isActive && node) setContent(node);
661
+ return /* @__PURE__ */ jsx(Presence, { present: forceMount || isActive, children: /* @__PURE__ */ jsx(
662
+ NavigationMenuContentImpl,
663
+ {
664
+ ...props2,
665
+ ref: composeRefs(ref, (node) => {
666
+ if (isActive && node) setContent(node);
718
667
  })
719
- })));
720
- }));
721
- });
722
- /* -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$var$FOCUS_GROUP_NAME = 'FocusGroup';
723
- const $322c88a641701f3b$var$FocusGroup = /*#__PURE__*/ $yHMN2$forwardRef((props, forwardedRef)=>{
724
- const { __scopeNavigationMenu: __scopeNavigationMenu , ...groupProps } = props;
725
- const context = $322c88a641701f3b$var$useNavigationMenuContext($322c88a641701f3b$var$FOCUS_GROUP_NAME, __scopeNavigationMenu);
726
- return /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$FocusGroupCollection.Provider, {
727
- scope: __scopeNavigationMenu
728
- }, /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$FocusGroupCollection.Slot, {
729
- scope: __scopeNavigationMenu
730
- }, /*#__PURE__*/ $yHMN2$createElement($yHMN2$Primitive.div, $yHMN2$babelruntimehelpersesmextends({
731
- dir: context.dir
732
- }, groupProps, {
733
- ref: forwardedRef
734
- }))));
668
+ }
669
+ ) }, value);
670
+ })
671
+ }
672
+ );
735
673
  });
736
- /* -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$var$ARROW_KEYS = [
737
- 'ArrowRight',
738
- 'ArrowLeft',
739
- 'ArrowUp',
740
- 'ArrowDown'
741
- ];
742
- const $322c88a641701f3b$var$FOCUS_GROUP_ITEM_NAME = 'FocusGroupItem';
743
- const $322c88a641701f3b$var$FocusGroupItem = /*#__PURE__*/ $yHMN2$forwardRef((props, forwardedRef)=>{
744
- const { __scopeNavigationMenu: __scopeNavigationMenu , ...groupProps } = props;
745
- const getItems = $322c88a641701f3b$var$useFocusGroupCollection(__scopeNavigationMenu);
746
- const context = $322c88a641701f3b$var$useNavigationMenuContext($322c88a641701f3b$var$FOCUS_GROUP_ITEM_NAME, __scopeNavigationMenu);
747
- return /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$FocusGroupCollection.ItemSlot, {
748
- scope: __scopeNavigationMenu
749
- }, /*#__PURE__*/ $yHMN2$createElement($yHMN2$Primitive.button, $yHMN2$babelruntimehelpersesmextends({}, groupProps, {
674
+ var FOCUS_GROUP_NAME = "FocusGroup";
675
+ var FocusGroup = React.forwardRef(
676
+ (props, forwardedRef) => {
677
+ const { __scopeNavigationMenu, ...groupProps } = props;
678
+ const context = useNavigationMenuContext(FOCUS_GROUP_NAME, __scopeNavigationMenu);
679
+ return /* @__PURE__ */ jsx(FocusGroupCollection.Provider, { scope: __scopeNavigationMenu, children: /* @__PURE__ */ jsx(FocusGroupCollection.Slot, { scope: __scopeNavigationMenu, children: /* @__PURE__ */ jsx(Primitive.div, { dir: context.dir, ...groupProps, ref: forwardedRef }) }) });
680
+ }
681
+ );
682
+ var ARROW_KEYS = ["ArrowRight", "ArrowLeft", "ArrowUp", "ArrowDown"];
683
+ var FOCUS_GROUP_ITEM_NAME = "FocusGroupItem";
684
+ var FocusGroupItem = React.forwardRef(
685
+ (props, forwardedRef) => {
686
+ const { __scopeNavigationMenu, ...groupProps } = props;
687
+ const getItems = useFocusGroupCollection(__scopeNavigationMenu);
688
+ const context = useNavigationMenuContext(FOCUS_GROUP_ITEM_NAME, __scopeNavigationMenu);
689
+ return /* @__PURE__ */ jsx(FocusGroupCollection.ItemSlot, { scope: __scopeNavigationMenu, children: /* @__PURE__ */ jsx(
690
+ Primitive.button,
691
+ {
692
+ ...groupProps,
750
693
  ref: forwardedRef,
751
- onKeyDown: $yHMN2$composeEventHandlers(props.onKeyDown, (event)=>{
752
- const isFocusNavigationKey = [
753
- 'Home',
754
- 'End',
755
- ...$322c88a641701f3b$var$ARROW_KEYS
756
- ].includes(event.key);
757
- if (isFocusNavigationKey) {
758
- let candidateNodes = getItems().map((item)=>item.ref.current
759
- );
760
- const prevItemKey = context.dir === 'rtl' ? 'ArrowRight' : 'ArrowLeft';
761
- const prevKeys = [
762
- prevItemKey,
763
- 'ArrowUp',
764
- 'End'
765
- ];
766
- if (prevKeys.includes(event.key)) candidateNodes.reverse();
767
- if ($322c88a641701f3b$var$ARROW_KEYS.includes(event.key)) {
768
- const currentIndex = candidateNodes.indexOf(event.currentTarget);
769
- candidateNodes = candidateNodes.slice(currentIndex + 1);
770
- }
771
- /**
772
- * Imperative focus during keydown is risky so we prevent React's batching updates
773
- * to avoid potential bugs. See: https://github.com/facebook/react/issues/20332
774
- */ setTimeout(()=>$322c88a641701f3b$var$focusFirst(candidateNodes)
775
- ); // Prevent page scroll while navigating
776
- event.preventDefault();
694
+ onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
695
+ const isFocusNavigationKey = ["Home", "End", ...ARROW_KEYS].includes(event.key);
696
+ if (isFocusNavigationKey) {
697
+ let candidateNodes = getItems().map((item) => item.ref.current);
698
+ const prevItemKey = context.dir === "rtl" ? "ArrowRight" : "ArrowLeft";
699
+ const prevKeys = [prevItemKey, "ArrowUp", "End"];
700
+ if (prevKeys.includes(event.key)) candidateNodes.reverse();
701
+ if (ARROW_KEYS.includes(event.key)) {
702
+ const currentIndex = candidateNodes.indexOf(event.currentTarget);
703
+ candidateNodes = candidateNodes.slice(currentIndex + 1);
777
704
  }
705
+ setTimeout(() => focusFirst(candidateNodes));
706
+ event.preventDefault();
707
+ }
778
708
  })
779
- })));
780
- });
781
- /**
782
- * Returns a list of potential tabbable candidates.
783
- *
784
- * NOTE: This is only a close approximation. For example it doesn't take into account cases like when
785
- * elements are not visible. This cannot be worked out easily by just reading a property, but rather
786
- * necessitate runtime knowledge (computed styles, etc). We deal with these cases separately.
787
- *
788
- * See: https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker
789
- * Credit: https://github.com/discord/focus-layers/blob/master/src/util/wrapFocus.tsx#L1
790
- */ function $322c88a641701f3b$var$getTabbableCandidates(container) {
791
- const nodes = [];
792
- const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
793
- acceptNode: (node)=>{
794
- const isHiddenInput = node.tagName === 'INPUT' && node.type === 'hidden';
795
- if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP; // `.tabIndex` is not the same as the `tabindex` attribute. It works on the
796
- // runtime's understanding of tabbability, so this automatically accounts
797
- // for any kind of element that could be tabbed to.
798
- return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
799
- }
800
- });
801
- while(walker.nextNode())nodes.push(walker.currentNode); // we do not take into account the order of nodes with positive `tabIndex` as it
802
- // hinders accessibility to have tab order different from visual order.
803
- return nodes;
709
+ }
710
+ ) });
711
+ }
712
+ );
713
+ function getTabbableCandidates(container) {
714
+ const nodes = [];
715
+ const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
716
+ acceptNode: (node) => {
717
+ const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
718
+ if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP;
719
+ return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
720
+ }
721
+ });
722
+ while (walker.nextNode()) nodes.push(walker.currentNode);
723
+ return nodes;
804
724
  }
805
- function $322c88a641701f3b$var$focusFirst(candidates) {
806
- const previouslyFocusedElement = document.activeElement;
807
- return candidates.some((candidate)=>{
808
- // if focus is already where we want to go, we don't want to keep going through the candidates
809
- if (candidate === previouslyFocusedElement) return true;
810
- candidate.focus();
811
- return document.activeElement !== previouslyFocusedElement;
812
- });
725
+ function focusFirst(candidates) {
726
+ const previouslyFocusedElement = document.activeElement;
727
+ return candidates.some((candidate) => {
728
+ if (candidate === previouslyFocusedElement) return true;
729
+ candidate.focus();
730
+ return document.activeElement !== previouslyFocusedElement;
731
+ });
813
732
  }
814
- function $322c88a641701f3b$var$removeFromTabOrder(candidates) {
815
- candidates.forEach((candidate)=>{
816
- candidate.dataset.tabindex = candidate.getAttribute('tabindex') || '';
817
- candidate.setAttribute('tabindex', '-1');
733
+ function removeFromTabOrder(candidates) {
734
+ candidates.forEach((candidate) => {
735
+ candidate.dataset.tabindex = candidate.getAttribute("tabindex") || "";
736
+ candidate.setAttribute("tabindex", "-1");
737
+ });
738
+ return () => {
739
+ candidates.forEach((candidate) => {
740
+ const prevTabIndex = candidate.dataset.tabindex;
741
+ candidate.setAttribute("tabindex", prevTabIndex);
818
742
  });
819
- return ()=>{
820
- candidates.forEach((candidate)=>{
821
- const prevTabIndex = candidate.dataset.tabindex;
822
- candidate.setAttribute('tabindex', prevTabIndex);
823
- });
824
- };
743
+ };
825
744
  }
826
- function $322c88a641701f3b$var$useResizeObserver(element, onResize) {
827
- const handleResize = $yHMN2$useCallbackRef(onResize);
828
- $yHMN2$useLayoutEffect(()=>{
829
- let rAF = 0;
830
- if (element) {
831
- /**
832
- * Resize Observer will throw an often benign error that says `ResizeObserver loop
833
- * completed with undelivered notifications`. This means that ResizeObserver was not
834
- * able to deliver all observations within a single animation frame, so we use
835
- * `requestAnimationFrame` to ensure we don't deliver unnecessary observations.
836
- * Further reading: https://github.com/WICG/resize-observer/issues/38
837
- */ const resizeObserver = new ResizeObserver(()=>{
838
- cancelAnimationFrame(rAF);
839
- rAF = window.requestAnimationFrame(handleResize);
840
- });
841
- resizeObserver.observe(element);
842
- return ()=>{
843
- window.cancelAnimationFrame(rAF);
844
- resizeObserver.unobserve(element);
845
- };
846
- }
847
- }, [
848
- element,
849
- handleResize
850
- ]);
745
+ function useResizeObserver(element, onResize) {
746
+ const handleResize = useCallbackRef(onResize);
747
+ useLayoutEffect(() => {
748
+ let rAF = 0;
749
+ if (element) {
750
+ const resizeObserver = new ResizeObserver(() => {
751
+ cancelAnimationFrame(rAF);
752
+ rAF = window.requestAnimationFrame(handleResize);
753
+ });
754
+ resizeObserver.observe(element);
755
+ return () => {
756
+ window.cancelAnimationFrame(rAF);
757
+ resizeObserver.unobserve(element);
758
+ };
759
+ }
760
+ }, [element, handleResize]);
851
761
  }
852
- function $322c88a641701f3b$var$getOpenState(open) {
853
- return open ? 'open' : 'closed';
762
+ function getOpenState(open) {
763
+ return open ? "open" : "closed";
854
764
  }
855
- function $322c88a641701f3b$var$makeTriggerId(baseId, value) {
856
- return `${baseId}-trigger-${value}`;
765
+ function makeTriggerId(baseId, value) {
766
+ return `${baseId}-trigger-${value}`;
857
767
  }
858
- function $322c88a641701f3b$var$makeContentId(baseId, value) {
859
- return `${baseId}-content-${value}`;
768
+ function makeContentId(baseId, value) {
769
+ return `${baseId}-content-${value}`;
860
770
  }
861
- function $322c88a641701f3b$var$whenMouse(handler) {
862
- return (event)=>event.pointerType === 'mouse' ? handler(event) : undefined
863
- ;
771
+ function whenMouse(handler) {
772
+ return (event) => event.pointerType === "mouse" ? handler(event) : void 0;
864
773
  }
865
- /* -----------------------------------------------------------------------------------------------*/ const $322c88a641701f3b$export$be92b6f5f03c0fe9 = $322c88a641701f3b$export$5b2278cf1e8bcae2;
866
- const $322c88a641701f3b$export$d7a01e11500dfb6f = $322c88a641701f3b$export$5958edd6c4ee7c79;
867
- const $322c88a641701f3b$export$54c2e3dc7acea9f5 = $322c88a641701f3b$export$c361068a95fd2286;
868
- const $322c88a641701f3b$export$6d08773d2e66f8f2 = $322c88a641701f3b$export$ffdbb83a2de845c2;
869
- const $322c88a641701f3b$export$41fb9f06171c75f4 = $322c88a641701f3b$export$37fe8002734d8f2;
870
- const $322c88a641701f3b$export$a6c7ac8248d6e38a = $322c88a641701f3b$export$6893bf21536567da;
871
- const $322c88a641701f3b$export$adb584737d712b70 = $322c88a641701f3b$export$8ddb526647c0d8fb;
872
- const $322c88a641701f3b$export$7c6e2c02157bb7d2 = $322c88a641701f3b$export$38e00e996c2f93f7;
873
- const $322c88a641701f3b$export$d5c6c08dc2d3ca7 = $322c88a641701f3b$export$ee880b97cc6d44a5;
874
-
875
-
876
-
877
-
878
- export {$322c88a641701f3b$export$fb8ea5af8c9fcdf0 as createNavigationMenuScope, $322c88a641701f3b$export$5b2278cf1e8bcae2 as NavigationMenu, $322c88a641701f3b$export$5958edd6c4ee7c79 as NavigationMenuSub, $322c88a641701f3b$export$c361068a95fd2286 as NavigationMenuList, $322c88a641701f3b$export$ffdbb83a2de845c2 as NavigationMenuItem, $322c88a641701f3b$export$37fe8002734d8f2 as NavigationMenuTrigger, $322c88a641701f3b$export$6893bf21536567da as NavigationMenuLink, $322c88a641701f3b$export$8ddb526647c0d8fb as NavigationMenuIndicator, $322c88a641701f3b$export$38e00e996c2f93f7 as NavigationMenuContent, $322c88a641701f3b$export$ee880b97cc6d44a5 as NavigationMenuViewport, $322c88a641701f3b$export$be92b6f5f03c0fe9 as Root, $322c88a641701f3b$export$d7a01e11500dfb6f as Sub, $322c88a641701f3b$export$54c2e3dc7acea9f5 as List, $322c88a641701f3b$export$6d08773d2e66f8f2 as Item, $322c88a641701f3b$export$41fb9f06171c75f4 as Trigger, $322c88a641701f3b$export$a6c7ac8248d6e38a as Link, $322c88a641701f3b$export$adb584737d712b70 as Indicator, $322c88a641701f3b$export$7c6e2c02157bb7d2 as Content, $322c88a641701f3b$export$d5c6c08dc2d3ca7 as Viewport};
774
+ var Root2 = NavigationMenu;
775
+ var Sub = NavigationMenuSub;
776
+ var List = NavigationMenuList;
777
+ var Item = NavigationMenuItem;
778
+ var Trigger = NavigationMenuTrigger;
779
+ var Link = NavigationMenuLink;
780
+ var Indicator = NavigationMenuIndicator;
781
+ var Content = NavigationMenuContent;
782
+ var Viewport = NavigationMenuViewport;
783
+ export {
784
+ Content,
785
+ Indicator,
786
+ Item,
787
+ Link,
788
+ List,
789
+ NavigationMenu,
790
+ NavigationMenuContent,
791
+ NavigationMenuIndicator,
792
+ NavigationMenuItem,
793
+ NavigationMenuLink,
794
+ NavigationMenuList,
795
+ NavigationMenuSub,
796
+ NavigationMenuTrigger,
797
+ NavigationMenuViewport,
798
+ Root2 as Root,
799
+ Sub,
800
+ Trigger,
801
+ Viewport,
802
+ createNavigationMenuScope
803
+ };
879
804
  //# sourceMappingURL=index.mjs.map