@radix-ui/react-navigation-menu 1.1.5-rc.8 → 1.2.0-rc.1

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,802 @@
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";
18
-
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
1
+ // packages/react/navigation-menu/src/NavigationMenu.tsx
2
+ import * as React from "react";
3
+ import ReactDOM from "react-dom";
4
+ import { createContextScope } from "@radix-ui/react-context";
5
+ import { composeEventHandlers } from "@radix-ui/primitive";
6
+ import { Primitive, dispatchDiscreteCustomEvent } from "@radix-ui/react-primitive";
7
+ import { useControllableState } from "@radix-ui/react-use-controllable-state";
8
+ import { composeRefs, useComposedRefs } from "@radix-ui/react-compose-refs";
9
+ import { useDirection } from "@radix-ui/react-direction";
10
+ import { Presence } from "@radix-ui/react-presence";
11
+ import { useId } from "@radix-ui/react-id";
12
+ import { createCollection } from "@radix-ui/react-collection";
13
+ import { DismissableLayer } from "@radix-ui/react-dismissable-layer";
14
+ import { usePrevious } from "@radix-ui/react-use-previous";
15
+ import { useLayoutEffect } from "@radix-ui/react-use-layout-effect";
16
+ import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
17
+ import * as VisuallyHiddenPrimitive from "@radix-ui/react-visually-hidden";
18
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
19
+ var NAVIGATION_MENU_NAME = "NavigationMenu";
20
+ var [Collection, useCollection, createCollectionScope] = createCollection(NAVIGATION_MENU_NAME);
21
+ var [FocusGroupCollection, useFocusGroupCollection, createFocusGroupCollectionScope] = createCollection(NAVIGATION_MENU_NAME);
22
+ var [createNavigationMenuContext, createNavigationMenuScope] = createContextScope(
23
+ NAVIGATION_MENU_NAME,
24
+ [createCollectionScope, createFocusGroupCollectionScope]
25
+ );
26
+ var [NavigationMenuProviderImpl, useNavigationMenuContext] = createNavigationMenuContext(NAVIGATION_MENU_NAME);
27
+ var [ViewportContentProvider, useViewportContentContext] = createNavigationMenuContext(NAVIGATION_MENU_NAME);
28
+ var NavigationMenu = React.forwardRef(
29
+ (props, forwardedRef) => {
30
+ const {
31
+ __scopeNavigationMenu,
32
+ value: valueProp,
33
+ onValueChange,
34
+ defaultValue,
35
+ delayDuration = 200,
36
+ skipDelayDuration = 300,
37
+ orientation = "horizontal",
38
+ dir,
39
+ ...NavigationMenuProps
40
+ } = props;
41
+ const [navigationMenu, setNavigationMenu] = React.useState(null);
42
+ const composedRef = useComposedRefs(forwardedRef, (node) => setNavigationMenu(node));
43
+ const direction = useDirection(dir);
44
+ const openTimerRef = React.useRef(0);
45
+ const closeTimerRef = React.useRef(0);
46
+ const skipDelayTimerRef = React.useRef(0);
47
+ const [isOpenDelayed, setIsOpenDelayed] = React.useState(true);
48
+ const [value = "", setValue] = useControllableState({
49
+ prop: valueProp,
50
+ onChange: (value2) => {
51
+ const isOpen = value2 !== "";
52
+ const hasSkipDelayDuration = skipDelayDuration > 0;
53
+ if (isOpen) {
54
+ window.clearTimeout(skipDelayTimerRef.current);
55
+ if (hasSkipDelayDuration) setIsOpenDelayed(false);
56
+ } else {
57
+ window.clearTimeout(skipDelayTimerRef.current);
58
+ skipDelayTimerRef.current = window.setTimeout(
59
+ () => setIsOpenDelayed(true),
60
+ skipDelayDuration
61
+ );
62
+ }
63
+ onValueChange?.(value2);
64
+ },
65
+ defaultProp: defaultValue
73
66
  });
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)=>{
67
+ const startCloseTimer = React.useCallback(() => {
68
+ window.clearTimeout(closeTimerRef.current);
69
+ closeTimerRef.current = window.setTimeout(() => setValue(""), 150);
70
+ }, [setValue]);
71
+ const handleOpen = React.useCallback(
72
+ (itemValue) => {
82
73
  window.clearTimeout(closeTimerRef.current);
83
74
  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(()=>{
75
+ },
76
+ [setValue]
77
+ );
78
+ const handleDelayedOpen = React.useCallback(
79
+ (itemValue) => {
80
+ const isOpenItem = value === itemValue;
81
+ if (isOpenItem) {
82
+ window.clearTimeout(closeTimerRef.current);
83
+ } else {
84
+ openTimerRef.current = window.setTimeout(() => {
93
85
  window.clearTimeout(closeTimerRef.current);
94
86
  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
- };
87
+ }, delayDuration);
88
+ }
89
+ },
90
+ [value, setValue, delayDuration]
91
+ );
92
+ React.useEffect(() => {
93
+ return () => {
94
+ window.clearTimeout(openTimerRef.current);
95
+ window.clearTimeout(closeTimerRef.current);
96
+ window.clearTimeout(skipDelayTimerRef.current);
97
+ };
107
98
  }, []);
108
- return /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$NavigationMenuProvider, {
99
+ return /* @__PURE__ */ jsx(
100
+ NavigationMenuProvider,
101
+ {
109
102
  scope: __scopeNavigationMenu,
110
103
  isRootMenu: true,
111
- value: value1,
104
+ value,
112
105
  dir: direction,
113
- orientation: orientation,
106
+ orientation,
114
107
  rootNavigationMenu: navigationMenu,
115
- onTriggerEnter: (itemValue)=>{
116
- window.clearTimeout(openTimerRef.current);
117
- if (isOpenDelayed) handleDelayedOpen(itemValue);
118
- else handleOpen(itemValue);
108
+ onTriggerEnter: (itemValue) => {
109
+ window.clearTimeout(openTimerRef.current);
110
+ if (isOpenDelayed) handleDelayedOpen(itemValue);
111
+ else handleOpen(itemValue);
119
112
  },
120
- onTriggerLeave: ()=>{
121
- window.clearTimeout(openTimerRef.current);
122
- startCloseTimer();
113
+ onTriggerLeave: () => {
114
+ window.clearTimeout(openTimerRef.current);
115
+ startCloseTimer();
123
116
  },
124
- onContentEnter: ()=>window.clearTimeout(closeTimerRef.current)
125
- ,
117
+ onContentEnter: () => window.clearTimeout(closeTimerRef.current),
126
118
  onContentLeave: startCloseTimer,
127
- onItemSelect: (itemValue)=>{
128
- setValue((prevValue)=>prevValue === itemValue ? '' : itemValue
129
- );
119
+ onItemSelect: (itemValue) => {
120
+ setValue((prevValue) => prevValue === itemValue ? "" : itemValue);
130
121
  },
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
122
+ onItemDismiss: () => setValue(""),
123
+ children: /* @__PURE__ */ jsx(
124
+ Primitive.nav,
125
+ {
126
+ "aria-label": "Main",
127
+ "data-orientation": orientation,
128
+ dir: direction,
129
+ ...NavigationMenuProps,
130
+ ref: composedRef
131
+ }
132
+ )
133
+ }
134
+ );
135
+ }
136
+ );
137
+ NavigationMenu.displayName = NAVIGATION_MENU_NAME;
138
+ var SUB_NAME = "NavigationMenuSub";
139
+ var NavigationMenuSub = React.forwardRef(
140
+ (props, forwardedRef) => {
141
+ const {
142
+ __scopeNavigationMenu,
143
+ value: valueProp,
144
+ onValueChange,
145
+ defaultValue,
146
+ orientation = "horizontal",
147
+ ...subProps
148
+ } = props;
149
+ const context = useNavigationMenuContext(SUB_NAME, __scopeNavigationMenu);
150
+ const [value = "", setValue] = useControllableState({
151
+ prop: valueProp,
152
+ onChange: onValueChange,
153
+ defaultProp: defaultValue
153
154
  });
154
- return /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$NavigationMenuProvider, {
155
+ return /* @__PURE__ */ jsx(
156
+ NavigationMenuProvider,
157
+ {
155
158
  scope: __scopeNavigationMenu,
156
159
  isRootMenu: false,
157
- value: value,
160
+ value,
158
161
  dir: context.dir,
159
- orientation: orientation,
162
+ orientation,
160
163
  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)));
164
+ onTriggerEnter: (itemValue) => setValue(itemValue),
165
+ onItemSelect: (itemValue) => setValue(itemValue),
166
+ onItemDismiss: () => setValue(""),
167
+ children: /* @__PURE__ */ jsx(Primitive.div, { "data-orientation": orientation, ...subProps, ref: forwardedRef })
168
+ }
169
+ );
170
+ }
171
+ );
172
+ NavigationMenuSub.displayName = SUB_NAME;
173
+ var NavigationMenuProvider = (props) => {
174
+ const {
175
+ scope,
176
+ isRootMenu,
177
+ rootNavigationMenu,
178
+ dir,
179
+ orientation,
180
+ children,
181
+ value,
182
+ onItemSelect,
183
+ onItemDismiss,
184
+ onTriggerEnter,
185
+ onTriggerLeave,
186
+ onContentEnter,
187
+ onContentLeave
188
+ } = props;
189
+ const [viewport, setViewport] = React.useState(null);
190
+ const [viewportContent, setViewportContent] = React.useState(/* @__PURE__ */ new Map());
191
+ const [indicatorTrack, setIndicatorTrack] = React.useState(null);
192
+ return /* @__PURE__ */ jsx(
193
+ NavigationMenuProviderImpl,
194
+ {
195
+ scope,
196
+ isRootMenu,
197
+ rootNavigationMenu,
198
+ value,
199
+ previousValue: usePrevious(value),
200
+ baseId: useId(),
201
+ dir,
202
+ orientation,
203
+ viewport,
204
+ onViewportChange: setViewport,
205
+ indicatorTrack,
206
+ onIndicatorTrackChange: setIndicatorTrack,
207
+ onTriggerEnter: useCallbackRef(onTriggerEnter),
208
+ onTriggerLeave: useCallbackRef(onTriggerLeave),
209
+ onContentEnter: useCallbackRef(onContentEnter),
210
+ onContentLeave: useCallbackRef(onContentLeave),
211
+ onItemSelect: useCallbackRef(onItemSelect),
212
+ onItemDismiss: useCallbackRef(onItemDismiss),
213
+ onViewportContentChange: React.useCallback((contentValue, contentData) => {
214
+ setViewportContent((prevContent) => {
215
+ prevContent.set(contentValue, contentData);
216
+ return new Map(prevContent);
217
+ });
218
+ }, []),
219
+ onViewportContentRemove: React.useCallback((contentValue) => {
220
+ setViewportContent((prevContent) => {
221
+ if (!prevContent.has(contentValue)) return prevContent;
222
+ prevContent.delete(contentValue);
223
+ return new Map(prevContent);
224
+ });
225
+ }, []),
226
+ children: /* @__PURE__ */ jsx(Collection.Provider, { scope, children: /* @__PURE__ */ jsx(ViewportContentProvider, { scope, items: viewportContent, children }) })
227
+ }
228
+ );
218
229
  };
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
- }
230
+ var LIST_NAME = "NavigationMenuList";
231
+ var NavigationMenuList = React.forwardRef(
232
+ (props, forwardedRef) => {
233
+ const { __scopeNavigationMenu, ...listProps } = props;
234
+ const context = useNavigationMenuContext(LIST_NAME, __scopeNavigationMenu);
235
+ const list = /* @__PURE__ */ jsx(Primitive.ul, { "data-orientation": context.orientation, ...listProps, ref: forwardedRef });
236
+ 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 }) });
237
+ }
238
+ );
239
+ NavigationMenuList.displayName = LIST_NAME;
240
+ var ITEM_NAME = "NavigationMenuItem";
241
+ var [NavigationMenuItemContextProvider, useNavigationMenuItemContext] = createNavigationMenuContext(ITEM_NAME);
242
+ var NavigationMenuItem = React.forwardRef(
243
+ (props, forwardedRef) => {
244
+ const { __scopeNavigationMenu, value: valueProp, ...itemProps } = props;
245
+ const autoValue = useId();
246
+ const value = valueProp || autoValue || "LEGACY_REACT_AUTO_VALUE";
247
+ const contentRef = React.useRef(null);
248
+ const triggerRef = React.useRef(null);
249
+ const focusProxyRef = React.useRef(null);
250
+ const restoreContentTabOrderRef = React.useRef(() => {
251
+ });
252
+ const wasEscapeCloseRef = React.useRef(false);
253
+ const handleContentEntry = React.useCallback((side = "start") => {
254
+ if (contentRef.current) {
255
+ restoreContentTabOrderRef.current();
256
+ const candidates = getTabbableCandidates(contentRef.current);
257
+ if (candidates.length) focusFirst(side === "start" ? candidates : candidates.reverse());
258
+ }
264
259
  }, []);
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
- }
260
+ const handleContentExit = React.useCallback(() => {
261
+ if (contentRef.current) {
262
+ const candidates = getTabbableCandidates(contentRef.current);
263
+ if (candidates.length) restoreContentTabOrderRef.current = removeFromTabOrder(candidates);
264
+ }
270
265
  }, []);
271
- return /*#__PURE__*/ $yHMN2$createElement($322c88a641701f3b$var$NavigationMenuItemContextProvider, {
266
+ return /* @__PURE__ */ jsx(
267
+ NavigationMenuItemContextProvider,
268
+ {
272
269
  scope: __scopeNavigationMenu,
273
- value: value,
274
- triggerRef: triggerRef,
275
- contentRef: contentRef,
276
- focusProxyRef: focusProxyRef,
277
- wasEscapeCloseRef: wasEscapeCloseRef,
270
+ value,
271
+ triggerRef,
272
+ contentRef,
273
+ focusProxyRef,
274
+ wasEscapeCloseRef,
278
275
  onEntryKeyDown: handleContentEntry,
279
276
  onFocusProxyEnter: handleContentEntry,
280
277
  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({
278
+ onContentFocusOutside: handleContentExit,
279
+ children: /* @__PURE__ */ jsx(Primitive.li, { ...itemProps, ref: forwardedRef })
280
+ }
281
+ );
282
+ }
283
+ );
284
+ NavigationMenuItem.displayName = ITEM_NAME;
285
+ var TRIGGER_NAME = "NavigationMenuTrigger";
286
+ var NavigationMenuTrigger = React.forwardRef((props, forwardedRef) => {
287
+ const { __scopeNavigationMenu, disabled, ...triggerProps } = props;
288
+ const context = useNavigationMenuContext(TRIGGER_NAME, props.__scopeNavigationMenu);
289
+ const itemContext = useNavigationMenuItemContext(TRIGGER_NAME, props.__scopeNavigationMenu);
290
+ const ref = React.useRef(null);
291
+ const composedRefs = useComposedRefs(ref, itemContext.triggerRef, forwardedRef);
292
+ const triggerId = makeTriggerId(context.baseId, itemContext.value);
293
+ const contentId = makeContentId(context.baseId, itemContext.value);
294
+ const hasPointerMoveOpenedRef = React.useRef(false);
295
+ const wasClickCloseRef = React.useRef(false);
296
+ const open = itemContext.value === context.value;
297
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
298
+ /* @__PURE__ */ jsx(Collection.ItemSlot, { scope: __scopeNavigationMenu, value: itemContext.value, children: /* @__PURE__ */ jsx(FocusGroupItem, { asChild: true, children: /* @__PURE__ */ jsx(
299
+ Primitive.button,
300
+ {
309
301
  id: triggerId,
310
- disabled: disabled,
311
- "data-disabled": disabled ? '' : undefined,
312
- "data-state": $322c88a641701f3b$var$getOpenState(open),
302
+ disabled,
303
+ "data-disabled": disabled ? "" : void 0,
304
+ "data-state": getOpenState(open),
313
305
  "aria-expanded": open,
314
- "aria-controls": contentId
315
- }, triggerProps, {
306
+ "aria-controls": contentId,
307
+ ...triggerProps,
316
308
  ref: composedRefs,
317
- onPointerEnter: $yHMN2$composeEventHandlers(props.onPointerEnter, ()=>{
318
- wasClickCloseRef.current = false;
319
- itemContext.wasEscapeCloseRef.current = false;
309
+ onPointerEnter: composeEventHandlers(props.onPointerEnter, () => {
310
+ wasClickCloseRef.current = false;
311
+ itemContext.wasEscapeCloseRef.current = false;
320
312
  }),
321
- onPointerMove: $yHMN2$composeEventHandlers(props.onPointerMove, $322c88a641701f3b$var$whenMouse(()=>{
322
- if (disabled || wasClickCloseRef.current || itemContext.wasEscapeCloseRef.current || hasPointerMoveOpenedRef.current) return;
313
+ onPointerMove: composeEventHandlers(
314
+ props.onPointerMove,
315
+ whenMouse(() => {
316
+ if (disabled || wasClickCloseRef.current || itemContext.wasEscapeCloseRef.current || hasPointerMoveOpenedRef.current)
317
+ return;
323
318
  context.onTriggerEnter(itemContext.value);
324
319
  hasPointerMoveOpenedRef.current = true;
325
- })),
326
- onPointerLeave: $yHMN2$composeEventHandlers(props.onPointerLeave, $322c88a641701f3b$var$whenMouse(()=>{
320
+ })
321
+ ),
322
+ onPointerLeave: composeEventHandlers(
323
+ props.onPointerLeave,
324
+ whenMouse(() => {
327
325
  if (disabled) return;
328
326
  context.onTriggerLeave();
329
327
  hasPointerMoveOpenedRef.current = false;
330
- })),
331
- onClick: $yHMN2$composeEventHandlers(props.onClick, ()=>{
332
- context.onItemSelect(itemContext.value);
333
- wasClickCloseRef.current = open;
328
+ })
329
+ ),
330
+ onClick: composeEventHandlers(props.onClick, () => {
331
+ context.onItemSelect(itemContext.value);
332
+ wasClickCloseRef.current = open;
334
333
  }),
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
- }
334
+ onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
335
+ const verticalEntryKey = context.dir === "rtl" ? "ArrowLeft" : "ArrowRight";
336
+ const entryKey = { horizontal: "ArrowDown", vertical: verticalEntryKey }[context.orientation];
337
+ if (open && event.key === entryKey) {
338
+ itemContext.onEntryKeyDown();
339
+ event.preventDefault();
340
+ }
345
341
  })
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)=>{
342
+ }
343
+ ) }) }),
344
+ open && /* @__PURE__ */ jsxs(Fragment, { children: [
345
+ /* @__PURE__ */ jsx(
346
+ VisuallyHiddenPrimitive.Root,
347
+ {
348
+ "aria-hidden": true,
349
+ tabIndex: 0,
350
+ ref: itemContext.focusProxyRef,
351
+ onFocus: (event) => {
351
352
  const content = itemContext.contentRef.current;
352
353
  const prevFocusedElement = event.relatedTarget;
353
354
  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');
355
+ const wasFocusFromContent = content?.contains(prevFocusedElement);
356
+ if (wasTriggerFocused || !wasFocusFromContent) {
357
+ itemContext.onFocusProxyEnter(wasTriggerFocused ? "start" : "end");
358
+ }
359
+ }
356
360
  }
357
- }), context.viewport && /*#__PURE__*/ $yHMN2$createElement("span", {
358
- "aria-owns": contentId
359
- })));
360
- });
361
- /*#__PURE__*/ Object.assign($322c88a641701f3b$export$37fe8002734d8f2, {
362
- displayName: $322c88a641701f3b$var$TRIGGER_NAME
361
+ ),
362
+ context.viewport && /* @__PURE__ */ jsx("span", { "aria-owns": contentId })
363
+ ] })
364
+ ] });
363
365
  });
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, {
366
+ NavigationMenuTrigger.displayName = TRIGGER_NAME;
367
+ var LINK_NAME = "NavigationMenuLink";
368
+ var LINK_SELECT = "navigationMenu.linkSelect";
369
+ var NavigationMenuLink = React.forwardRef(
370
+ (props, forwardedRef) => {
371
+ const { __scopeNavigationMenu, active, onSelect, ...linkProps } = props;
372
+ return /* @__PURE__ */ jsx(FocusGroupItem, { asChild: true, children: /* @__PURE__ */ jsx(
373
+ Primitive.a,
374
+ {
375
+ "data-active": active ? "" : void 0,
376
+ "aria-current": active ? "page" : void 0,
377
+ ...linkProps,
376
378
  ref: forwardedRef,
377
- onClick: $yHMN2$composeEventHandlers(props.onClick, (event1)=>{
378
- const target = event1.target;
379
- const linkSelectEvent = new CustomEvent($322c88a641701f3b$var$LINK_SELECT, {
379
+ onClick: composeEventHandlers(
380
+ props.onClick,
381
+ (event) => {
382
+ const target = event.target;
383
+ const linkSelectEvent = new CustomEvent(LINK_SELECT, {
384
+ bubbles: true,
385
+ cancelable: true
386
+ });
387
+ target.addEventListener(LINK_SELECT, (event2) => onSelect?.(event2), { once: true });
388
+ dispatchDiscreteCustomEvent(target, linkSelectEvent);
389
+ if (!linkSelectEvent.defaultPrevented && !event.metaKey) {
390
+ const rootContentDismissEvent = new CustomEvent(ROOT_CONTENT_DISMISS, {
380
391
  bubbles: true,
381
392
  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);
393
+ });
394
+ dispatchDiscreteCustomEvent(target, rootContentDismissEvent);
394
395
  }
395
- }, {
396
- checkForDefaultPrevented: false
397
- })
398
- })));
399
- });
400
- /*#__PURE__*/ Object.assign($322c88a641701f3b$export$6893bf21536567da, {
401
- displayName: $322c88a641701f3b$var$LINK_NAME
402
- });
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;
396
+ },
397
+ { checkForDefaultPrevented: false }
398
+ )
399
+ }
400
+ ) });
401
+ }
402
+ );
403
+ NavigationMenuLink.displayName = LINK_NAME;
404
+ var INDICATOR_NAME = "NavigationMenuIndicator";
405
+ var NavigationMenuIndicator = React.forwardRef((props, forwardedRef) => {
406
+ const { forceMount, ...indicatorProps } = props;
407
+ const context = useNavigationMenuContext(INDICATOR_NAME, props.__scopeNavigationMenu);
408
+ const isVisible = Boolean(context.value);
409
+ return context.indicatorTrack ? ReactDOM.createPortal(
410
+ /* @__PURE__ */ jsx(Presence, { present: forceMount || isVisible, children: /* @__PURE__ */ jsx(NavigationMenuIndicatorImpl, { ...indicatorProps, ref: forwardedRef }) }),
411
+ context.indicatorTrack
412
+ ) : null;
415
413
  });
416
- /*#__PURE__*/ Object.assign($322c88a641701f3b$export$8ddb526647c0d8fb, {
417
- displayName: $322c88a641701f3b$var$INDICATOR_NAME
418
- });
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
443
- });
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
466
- }
467
- })) : null;
414
+ NavigationMenuIndicator.displayName = INDICATOR_NAME;
415
+ var NavigationMenuIndicatorImpl = React.forwardRef((props, forwardedRef) => {
416
+ const { __scopeNavigationMenu, ...indicatorProps } = props;
417
+ const context = useNavigationMenuContext(INDICATOR_NAME, __scopeNavigationMenu);
418
+ const getItems = useCollection(__scopeNavigationMenu);
419
+ const [activeTrigger, setActiveTrigger] = React.useState(
420
+ null
421
+ );
422
+ const [position, setPosition] = React.useState(null);
423
+ const isHorizontal = context.orientation === "horizontal";
424
+ const isVisible = Boolean(context.value);
425
+ React.useEffect(() => {
426
+ const items = getItems();
427
+ const triggerNode = items.find((item) => item.value === context.value)?.ref.current;
428
+ if (triggerNode) setActiveTrigger(triggerNode);
429
+ }, [getItems, context.value]);
430
+ const handlePositionChange = () => {
431
+ if (activeTrigger) {
432
+ setPosition({
433
+ size: isHorizontal ? activeTrigger.offsetWidth : activeTrigger.offsetHeight,
434
+ offset: isHorizontal ? activeTrigger.offsetLeft : activeTrigger.offsetTop
435
+ });
436
+ }
437
+ };
438
+ useResizeObserver(activeTrigger, handlePositionChange);
439
+ useResizeObserver(context.indicatorTrack, handlePositionChange);
440
+ return position ? /* @__PURE__ */ jsx(
441
+ Primitive.div,
442
+ {
443
+ "aria-hidden": true,
444
+ "data-state": isVisible ? "visible" : "hidden",
445
+ "data-orientation": context.orientation,
446
+ ...indicatorProps,
447
+ ref: forwardedRef,
448
+ style: {
449
+ position: "absolute",
450
+ ...isHorizontal ? {
451
+ left: 0,
452
+ width: position.size + "px",
453
+ transform: `translateX(${position.offset}px)`
454
+ } : {
455
+ top: 0,
456
+ height: position.size + "px",
457
+ transform: `translateY(${position.offset}px)`
458
+ },
459
+ ...indicatorProps.style
460
+ }
461
+ }
462
+ ) : null;
468
463
  });
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
- }));
464
+ var CONTENT_NAME = "NavigationMenuContent";
465
+ var NavigationMenuContent = React.forwardRef((props, forwardedRef) => {
466
+ const { forceMount, ...contentProps } = props;
467
+ const context = useNavigationMenuContext(CONTENT_NAME, props.__scopeNavigationMenu);
468
+ const itemContext = useNavigationMenuItemContext(CONTENT_NAME, props.__scopeNavigationMenu);
469
+ const composedRefs = useComposedRefs(itemContext.contentRef, forwardedRef);
470
+ const open = itemContext.value === context.value;
471
+ const commonProps = {
472
+ value: itemContext.value,
473
+ triggerRef: itemContext.triggerRef,
474
+ focusProxyRef: itemContext.focusProxyRef,
475
+ wasEscapeCloseRef: itemContext.wasEscapeCloseRef,
476
+ onContentFocusOutside: itemContext.onContentFocusOutside,
477
+ onRootContentClose: itemContext.onRootContentClose,
478
+ ...contentProps
479
+ };
480
+ return !context.viewport ? /* @__PURE__ */ jsx(Presence, { present: forceMount || open, children: /* @__PURE__ */ jsx(
481
+ NavigationMenuContentImpl,
482
+ {
483
+ "data-state": getOpenState(open),
484
+ ...commonProps,
485
+ ref: composedRefs,
486
+ onPointerEnter: composeEventHandlers(props.onPointerEnter, context.onContentEnter),
487
+ onPointerLeave: composeEventHandlers(
488
+ props.onPointerLeave,
489
+ whenMouse(context.onContentLeave)
490
+ ),
491
+ style: {
492
+ // Prevent interaction when animating out
493
+ pointerEvents: !open && context.isRootMenu ? "none" : void 0,
494
+ ...commonProps.style
495
+ }
496
+ }
497
+ ) }) : /* @__PURE__ */ jsx(ViewportContentMounter, { forceMount, ...commonProps, ref: composedRefs });
505
498
  });
506
- /*#__PURE__*/ Object.assign($322c88a641701f3b$export$38e00e996c2f93f7, {
507
- displayName: $322c88a641701f3b$var$CONTENT_NAME
499
+ NavigationMenuContent.displayName = CONTENT_NAME;
500
+ var ViewportContentMounter = React.forwardRef((props, forwardedRef) => {
501
+ const context = useNavigationMenuContext(CONTENT_NAME, props.__scopeNavigationMenu);
502
+ const { onViewportContentChange, onViewportContentRemove } = context;
503
+ useLayoutEffect(() => {
504
+ onViewportContentChange(props.value, {
505
+ ref: forwardedRef,
506
+ ...props
507
+ });
508
+ }, [props, forwardedRef, onViewportContentChange]);
509
+ useLayoutEffect(() => {
510
+ return () => onViewportContentRemove(props.value);
511
+ }, [props.value, onViewportContentRemove]);
512
+ return null;
508
513
  });
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
514
+ var ROOT_CONTENT_DISMISS = "navigationMenu.rootContentDismiss";
515
+ var NavigationMenuContentImpl = React.forwardRef((props, forwardedRef) => {
516
+ const {
517
+ __scopeNavigationMenu,
518
+ value,
519
+ triggerRef,
520
+ focusProxyRef,
521
+ wasEscapeCloseRef,
522
+ onRootContentClose,
523
+ onContentFocusOutside,
524
+ ...contentProps
525
+ } = props;
526
+ const context = useNavigationMenuContext(CONTENT_NAME, __scopeNavigationMenu);
527
+ const ref = React.useRef(null);
528
+ const composedRefs = useComposedRefs(ref, forwardedRef);
529
+ const triggerId = makeTriggerId(context.baseId, value);
530
+ const contentId = makeContentId(context.baseId, value);
531
+ const getItems = useCollection(__scopeNavigationMenu);
532
+ const prevMotionAttributeRef = React.useRef(null);
533
+ const { onItemDismiss } = context;
534
+ React.useEffect(() => {
535
+ const content = ref.current;
536
+ if (context.isRootMenu && content) {
537
+ const handleClose = () => {
538
+ onItemDismiss();
539
+ onRootContentClose();
540
+ if (content.contains(document.activeElement)) triggerRef.current?.focus();
541
+ };
542
+ content.addEventListener(ROOT_CONTENT_DISMISS, handleClose);
543
+ return () => content.removeEventListener(ROOT_CONTENT_DISMISS, handleClose);
544
+ }
545
+ }, [context.isRootMenu, props.value, triggerRef, onItemDismiss, onRootContentClose]);
546
+ const motionAttribute = React.useMemo(() => {
547
+ const items = getItems();
548
+ const values = items.map((item) => item.value);
549
+ if (context.dir === "rtl") values.reverse();
550
+ const index = values.indexOf(context.value);
551
+ const prevIndex = values.indexOf(context.previousValue);
552
+ const isSelected = value === context.value;
553
+ const wasSelected = prevIndex === values.indexOf(value);
554
+ if (!isSelected && !wasSelected) return prevMotionAttributeRef.current;
555
+ const attribute = (() => {
556
+ if (index !== prevIndex) {
557
+ if (isSelected && prevIndex !== -1) return index > prevIndex ? "from-end" : "from-start";
558
+ if (wasSelected && index !== -1) return index > prevIndex ? "to-start" : "to-end";
559
+ }
560
+ return null;
561
+ })();
562
+ prevMotionAttributeRef.current = attribute;
563
+ return attribute;
564
+ }, [context.previousValue, context.value, context.dir, getItems, value]);
565
+ return /* @__PURE__ */ jsx(FocusGroup, { asChild: true, children: /* @__PURE__ */ jsx(
566
+ DismissableLayer,
567
+ {
568
+ id: contentId,
569
+ "aria-labelledby": triggerId,
570
+ "data-motion": motionAttribute,
571
+ "data-orientation": context.orientation,
572
+ ...contentProps,
573
+ ref: composedRefs,
574
+ disableOutsidePointerEvents: false,
575
+ onDismiss: () => {
576
+ const rootContentDismissEvent = new Event(ROOT_CONTENT_DISMISS, {
577
+ bubbles: true,
578
+ cancelable: true
516
579
  });
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
- ;
580
+ ref.current?.dispatchEvent(rootContentDismissEvent);
581
+ },
582
+ onFocusOutside: composeEventHandlers(props.onFocusOutside, (event) => {
583
+ onContentFocusOutside();
584
+ const target = event.target;
585
+ if (context.rootNavigationMenu?.contains(target)) event.preventDefault();
586
+ }),
587
+ onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => {
588
+ const target = event.target;
589
+ const isTrigger = getItems().some((item) => item.ref.current?.contains(target));
590
+ const isRootViewport = context.isRootMenu && context.viewport?.contains(target);
591
+ if (isTrigger || isRootViewport || !context.isRootMenu) event.preventDefault();
592
+ }),
593
+ onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
594
+ const isMetaKey = event.altKey || event.ctrlKey || event.metaKey;
595
+ const isTabKey = event.key === "Tab" && !isMetaKey;
596
+ if (isTabKey) {
597
+ const candidates = getTabbableCandidates(event.currentTarget);
598
+ const focusedElement = document.activeElement;
599
+ const index = candidates.findIndex((candidate) => candidate === focusedElement);
600
+ const isMovingBackwards = event.shiftKey;
601
+ const nextCandidates = isMovingBackwards ? candidates.slice(0, index).reverse() : candidates.slice(index + 1, candidates.length);
602
+ if (focusFirst(nextCandidates)) {
603
+ event.preventDefault();
604
+ } else {
605
+ focusProxyRef.current?.focus();
606
+ }
554
607
  }
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
- })));
608
+ }),
609
+ onEscapeKeyDown: composeEventHandlers(props.onEscapeKeyDown, (event) => {
610
+ wasEscapeCloseRef.current = true;
611
+ })
612
+ }
613
+ ) });
666
614
  });
667
- /*#__PURE__*/ Object.assign($322c88a641701f3b$export$ee880b97cc6d44a5, {
668
- displayName: $322c88a641701f3b$var$VIEWPORT_NAME
615
+ var VIEWPORT_NAME = "NavigationMenuViewport";
616
+ var NavigationMenuViewport = React.forwardRef((props, forwardedRef) => {
617
+ const { forceMount, ...viewportProps } = props;
618
+ const context = useNavigationMenuContext(VIEWPORT_NAME, props.__scopeNavigationMenu);
619
+ const open = Boolean(context.value);
620
+ return /* @__PURE__ */ jsx(Presence, { present: forceMount || open, children: /* @__PURE__ */ jsx(NavigationMenuViewportImpl, { ...viewportProps, ref: forwardedRef }) });
669
621
  });
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 }])=>{
622
+ NavigationMenuViewport.displayName = VIEWPORT_NAME;
623
+ var NavigationMenuViewportImpl = React.forwardRef((props, forwardedRef) => {
624
+ const { __scopeNavigationMenu, children, ...viewportImplProps } = props;
625
+ const context = useNavigationMenuContext(VIEWPORT_NAME, __scopeNavigationMenu);
626
+ const composedRefs = useComposedRefs(forwardedRef, context.onViewportChange);
627
+ const viewportContentContext = useViewportContentContext(
628
+ CONTENT_NAME,
629
+ props.__scopeNavigationMenu
630
+ );
631
+ const [size, setSize] = React.useState(null);
632
+ const [content, setContent] = React.useState(null);
633
+ const viewportWidth = size ? size?.width + "px" : void 0;
634
+ const viewportHeight = size ? size?.height + "px" : void 0;
635
+ const open = Boolean(context.value);
636
+ const activeContentValue = open ? context.value : context.previousValue;
637
+ const handleSizeChange = () => {
638
+ if (content) setSize({ width: content.offsetWidth, height: content.offsetHeight });
639
+ };
640
+ useResizeObserver(content, handleSizeChange);
641
+ return /* @__PURE__ */ jsx(
642
+ Primitive.div,
643
+ {
644
+ "data-state": getOpenState(open),
645
+ "data-orientation": context.orientation,
646
+ ...viewportImplProps,
647
+ ref: composedRefs,
648
+ style: {
649
+ // Prevent interaction when animating out
650
+ pointerEvents: !open && context.isRootMenu ? "none" : void 0,
651
+ ["--radix-navigation-menu-viewport-width"]: viewportWidth,
652
+ ["--radix-navigation-menu-viewport-height"]: viewportHeight,
653
+ ...viewportImplProps.style
654
+ },
655
+ onPointerEnter: composeEventHandlers(props.onPointerEnter, context.onContentEnter),
656
+ onPointerLeave: composeEventHandlers(props.onPointerLeave, whenMouse(context.onContentLeave)),
657
+ children: Array.from(viewportContentContext.items).map(([value, { ref, forceMount, ...props2 }]) => {
709
658
  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);
659
+ return /* @__PURE__ */ jsx(Presence, { present: forceMount || isActive, children: /* @__PURE__ */ jsx(
660
+ NavigationMenuContentImpl,
661
+ {
662
+ ...props2,
663
+ ref: composeRefs(ref, (node) => {
664
+ if (isActive && node) setContent(node);
718
665
  })
719
- })));
720
- }));
666
+ }
667
+ ) }, value);
668
+ })
669
+ }
670
+ );
721
671
  });
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
- }))));
735
- });
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, {
672
+ var FOCUS_GROUP_NAME = "FocusGroup";
673
+ var FocusGroup = React.forwardRef(
674
+ (props, forwardedRef) => {
675
+ const { __scopeNavigationMenu, ...groupProps } = props;
676
+ const context = useNavigationMenuContext(FOCUS_GROUP_NAME, __scopeNavigationMenu);
677
+ 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 }) }) });
678
+ }
679
+ );
680
+ var ARROW_KEYS = ["ArrowRight", "ArrowLeft", "ArrowUp", "ArrowDown"];
681
+ var FOCUS_GROUP_ITEM_NAME = "FocusGroupItem";
682
+ var FocusGroupItem = React.forwardRef(
683
+ (props, forwardedRef) => {
684
+ const { __scopeNavigationMenu, ...groupProps } = props;
685
+ const getItems = useFocusGroupCollection(__scopeNavigationMenu);
686
+ const context = useNavigationMenuContext(FOCUS_GROUP_ITEM_NAME, __scopeNavigationMenu);
687
+ return /* @__PURE__ */ jsx(FocusGroupCollection.ItemSlot, { scope: __scopeNavigationMenu, children: /* @__PURE__ */ jsx(
688
+ Primitive.button,
689
+ {
690
+ ...groupProps,
750
691
  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();
692
+ onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
693
+ const isFocusNavigationKey = ["Home", "End", ...ARROW_KEYS].includes(event.key);
694
+ if (isFocusNavigationKey) {
695
+ let candidateNodes = getItems().map((item) => item.ref.current);
696
+ const prevItemKey = context.dir === "rtl" ? "ArrowRight" : "ArrowLeft";
697
+ const prevKeys = [prevItemKey, "ArrowUp", "End"];
698
+ if (prevKeys.includes(event.key)) candidateNodes.reverse();
699
+ if (ARROW_KEYS.includes(event.key)) {
700
+ const currentIndex = candidateNodes.indexOf(event.currentTarget);
701
+ candidateNodes = candidateNodes.slice(currentIndex + 1);
777
702
  }
703
+ setTimeout(() => focusFirst(candidateNodes));
704
+ event.preventDefault();
705
+ }
778
706
  })
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;
707
+ }
708
+ ) });
709
+ }
710
+ );
711
+ function getTabbableCandidates(container) {
712
+ const nodes = [];
713
+ const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
714
+ acceptNode: (node) => {
715
+ const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
716
+ if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP;
717
+ return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
718
+ }
719
+ });
720
+ while (walker.nextNode()) nodes.push(walker.currentNode);
721
+ return nodes;
804
722
  }
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
- });
723
+ function focusFirst(candidates) {
724
+ const previouslyFocusedElement = document.activeElement;
725
+ return candidates.some((candidate) => {
726
+ if (candidate === previouslyFocusedElement) return true;
727
+ candidate.focus();
728
+ return document.activeElement !== previouslyFocusedElement;
729
+ });
813
730
  }
814
- function $322c88a641701f3b$var$removeFromTabOrder(candidates) {
815
- candidates.forEach((candidate)=>{
816
- candidate.dataset.tabindex = candidate.getAttribute('tabindex') || '';
817
- candidate.setAttribute('tabindex', '-1');
731
+ function removeFromTabOrder(candidates) {
732
+ candidates.forEach((candidate) => {
733
+ candidate.dataset.tabindex = candidate.getAttribute("tabindex") || "";
734
+ candidate.setAttribute("tabindex", "-1");
735
+ });
736
+ return () => {
737
+ candidates.forEach((candidate) => {
738
+ const prevTabIndex = candidate.dataset.tabindex;
739
+ candidate.setAttribute("tabindex", prevTabIndex);
818
740
  });
819
- return ()=>{
820
- candidates.forEach((candidate)=>{
821
- const prevTabIndex = candidate.dataset.tabindex;
822
- candidate.setAttribute('tabindex', prevTabIndex);
823
- });
824
- };
741
+ };
825
742
  }
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
- ]);
743
+ function useResizeObserver(element, onResize) {
744
+ const handleResize = useCallbackRef(onResize);
745
+ useLayoutEffect(() => {
746
+ let rAF = 0;
747
+ if (element) {
748
+ const resizeObserver = new ResizeObserver(() => {
749
+ cancelAnimationFrame(rAF);
750
+ rAF = window.requestAnimationFrame(handleResize);
751
+ });
752
+ resizeObserver.observe(element);
753
+ return () => {
754
+ window.cancelAnimationFrame(rAF);
755
+ resizeObserver.unobserve(element);
756
+ };
757
+ }
758
+ }, [element, handleResize]);
851
759
  }
852
- function $322c88a641701f3b$var$getOpenState(open) {
853
- return open ? 'open' : 'closed';
760
+ function getOpenState(open) {
761
+ return open ? "open" : "closed";
854
762
  }
855
- function $322c88a641701f3b$var$makeTriggerId(baseId, value) {
856
- return `${baseId}-trigger-${value}`;
763
+ function makeTriggerId(baseId, value) {
764
+ return `${baseId}-trigger-${value}`;
857
765
  }
858
- function $322c88a641701f3b$var$makeContentId(baseId, value) {
859
- return `${baseId}-content-${value}`;
766
+ function makeContentId(baseId, value) {
767
+ return `${baseId}-content-${value}`;
860
768
  }
861
- function $322c88a641701f3b$var$whenMouse(handler) {
862
- return (event)=>event.pointerType === 'mouse' ? handler(event) : undefined
863
- ;
769
+ function whenMouse(handler) {
770
+ return (event) => event.pointerType === "mouse" ? handler(event) : void 0;
864
771
  }
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};
772
+ var Root2 = NavigationMenu;
773
+ var Sub = NavigationMenuSub;
774
+ var List = NavigationMenuList;
775
+ var Item = NavigationMenuItem;
776
+ var Trigger = NavigationMenuTrigger;
777
+ var Link = NavigationMenuLink;
778
+ var Indicator = NavigationMenuIndicator;
779
+ var Content = NavigationMenuContent;
780
+ var Viewport = NavigationMenuViewport;
781
+ export {
782
+ Content,
783
+ Indicator,
784
+ Item,
785
+ Link,
786
+ List,
787
+ NavigationMenu,
788
+ NavigationMenuContent,
789
+ NavigationMenuIndicator,
790
+ NavigationMenuItem,
791
+ NavigationMenuLink,
792
+ NavigationMenuList,
793
+ NavigationMenuSub,
794
+ NavigationMenuTrigger,
795
+ NavigationMenuViewport,
796
+ Root2 as Root,
797
+ Sub,
798
+ Trigger,
799
+ Viewport,
800
+ createNavigationMenuScope
801
+ };
879
802
  //# sourceMappingURL=index.mjs.map