@bccampus/ui-components 0.4.3 → 0.5.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.
Files changed (170) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/.yarn/releases/yarn-4.12.0.cjs +942 -0
  3. package/.yarnrc.yml +3 -0
  4. package/dist/_chunks/createLucideIcon.js +79 -0
  5. package/dist/_chunks/index.js +103 -0
  6. package/dist/_chunks/index2.js +44 -0
  7. package/dist/_chunks/index3.js +39 -0
  8. package/dist/_chunks/index4.js +615 -0
  9. package/dist/{utils-CRiPKpXj.js → _chunks/utils.js} +828 -544
  10. package/dist/components/index.d.ts +16 -0
  11. package/dist/components/index.js +84 -0
  12. package/dist/components/ui/banner.d.ts +10 -0
  13. package/dist/components/ui/banner.js +39 -0
  14. package/dist/components/ui/button.d.ts +11 -0
  15. package/dist/{button.js → components/ui/button.js} +11 -10
  16. package/dist/components/ui/card.d.ts +27 -0
  17. package/dist/components/ui/card.js +109 -0
  18. package/dist/components/ui/composite/CompositeData.d.ts +20 -0
  19. package/dist/components/ui/composite/CompositeData.js +89 -0
  20. package/dist/components/ui/composite/CompositeDataItem.d.ts +28 -0
  21. package/dist/components/ui/composite/CompositeDataItem.js +111 -0
  22. package/dist/components/ui/composite/FocusProvider/AbstractFocusProvider.d.ts +41 -0
  23. package/dist/components/ui/composite/FocusProvider/AbstractFocusProvider.js +36 -0
  24. package/dist/components/ui/composite/FocusProvider/ListboxFocusProvider.d.ts +16 -0
  25. package/dist/components/ui/composite/FocusProvider/ListboxFocusProvider.js +67 -0
  26. package/dist/components/ui/composite/FocusProvider/index.d.ts +2 -0
  27. package/dist/components/ui/composite/FocusProvider/index.js +6 -0
  28. package/dist/components/ui/composite/SelectionProvider/AbstractSelectionProvider.d.ts +23 -0
  29. package/dist/components/ui/composite/SelectionProvider/AbstractSelectionProvider.js +21 -0
  30. package/dist/components/ui/composite/SelectionProvider/MultipleSelectionProvider.d.ts +9 -0
  31. package/dist/components/ui/composite/SelectionProvider/MultipleSelectionProvider.js +20 -0
  32. package/dist/components/ui/composite/SelectionProvider/SingleSelectionProvider.d.ts +9 -0
  33. package/dist/components/ui/composite/SelectionProvider/SingleSelectionProvider.js +25 -0
  34. package/dist/components/ui/composite/SelectionProvider/index.d.ts +3 -0
  35. package/dist/components/ui/composite/SelectionProvider/index.js +8 -0
  36. package/dist/components/ui/composite/composite-component-item.d.ts +2 -0
  37. package/dist/components/ui/composite/composite-component-item.js +52 -0
  38. package/dist/components/ui/composite/composite-component.d.ts +2 -0
  39. package/dist/components/ui/composite/composite-component.js +66 -0
  40. package/dist/components/ui/composite/index.d.ts +8 -0
  41. package/dist/components/ui/composite/index.js +22 -0
  42. package/dist/components/ui/composite/listbox.d.ts +2 -0
  43. package/dist/components/ui/composite/listbox.js +59 -0
  44. package/dist/components/ui/composite/types.d.ts +82 -0
  45. package/dist/components/ui/composite/types.js +1 -0
  46. package/dist/components/ui/horizontal-list.d.ts +10 -0
  47. package/dist/components/ui/horizontal-list.js +70 -0
  48. package/dist/components/ui/icon-generator/generate-tiles.d.ts +4 -0
  49. package/dist/components/ui/icon-generator/generate-tiles.js +223 -0
  50. package/dist/components/ui/icon-generator/icon-generator.d.ts +3 -0
  51. package/dist/components/ui/icon-generator/icon-generator.js +82 -0
  52. package/dist/components/ui/icon-generator/index.d.ts +4 -0
  53. package/dist/components/ui/icon-generator/index.js +11 -0
  54. package/dist/components/ui/icon-generator/masked-image-generator.d.ts +3 -0
  55. package/dist/components/ui/icon-generator/masked-image-generator.js +31 -0
  56. package/dist/{masked-image-generator.d.ts → components/ui/icon-generator/types.d.ts} +48 -58
  57. package/dist/components/ui/icon-generator/types.js +30 -0
  58. package/dist/components/ui/input.d.ts +3 -0
  59. package/dist/{input.js → components/ui/input.js} +8 -8
  60. package/dist/components/ui/navigation-menu.d.ts +16 -0
  61. package/dist/components/ui/navigation-menu.js +1117 -0
  62. package/dist/components/ui/overlay.d.ts +7 -0
  63. package/dist/{overlay.js → components/ui/overlay.js} +7 -7
  64. package/dist/components/ui/page-header.d.ts +5 -0
  65. package/dist/{page-header.js → components/ui/page-header.js} +189 -181
  66. package/dist/components/ui/page-section.d.ts +8 -0
  67. package/dist/{page-section.js → components/ui/page-section.js} +7 -7
  68. package/dist/components/ui/page.d.ts +3 -0
  69. package/dist/components/ui/page.js +8 -0
  70. package/dist/components/ui/popover.d.ts +7 -0
  71. package/dist/components/ui/popover.js +3614 -0
  72. package/dist/components/ui/search-input.d.ts +3 -0
  73. package/dist/components/ui/search-input.js +18 -0
  74. package/dist/components/ui/tag.d.ts +10 -0
  75. package/dist/{tag.js → components/ui/tag.js} +10 -9
  76. package/dist/components/ui/typography/caption.d.ts +8 -0
  77. package/dist/components/ui/typography/caption.js +28 -0
  78. package/dist/components/ui/typography/index.d.ts +1 -0
  79. package/dist/components/ui/typography/index.js +5 -0
  80. package/dist/hooks/index.d.ts +3 -0
  81. package/dist/hooks/index.js +9 -0
  82. package/dist/hooks/use-effect-after-mount.d.ts +2 -0
  83. package/dist/hooks/use-effect-after-mount.js +24 -0
  84. package/dist/hooks/use-id.d.ts +1 -0
  85. package/dist/hooks/use-id.js +7 -0
  86. package/dist/hooks/use-keyboard-event.d.ts +59 -0
  87. package/dist/hooks/use-keyboard-event.js +52 -0
  88. package/dist/lib/index.d.ts +3 -0
  89. package/dist/lib/index.js +16 -0
  90. package/dist/lib/object.d.ts +5 -0
  91. package/dist/lib/object.js +38 -0
  92. package/dist/lib/set-operations.d.ts +5 -0
  93. package/dist/lib/set-operations.js +51 -0
  94. package/dist/{utils.d.ts → lib/utils.d.ts} +2 -5
  95. package/dist/lib/utils.js +4 -0
  96. package/package.json +76 -146
  97. package/src/App.tsx +44 -14
  98. package/src/components/index.ts +17 -0
  99. package/src/components/ui/composite/FocusProvider/index.ts +2 -0
  100. package/src/components/ui/composite/SelectionProvider/MultipleSelectionProvider.ts +1 -1
  101. package/src/components/ui/composite/SelectionProvider/index.ts +3 -0
  102. package/src/components/ui/composite/index.ts +6 -5
  103. package/src/components/ui/icon-generator/index.ts +2 -0
  104. package/src/components/ui/typography/index.ts +1 -0
  105. package/src/hooks/index.ts +3 -0
  106. package/src/index.ts +3 -0
  107. package/src/lib/index.ts +3 -0
  108. package/src/main.tsx +12 -12
  109. package/tsconfig.lib.json +44 -0
  110. package/vite.config.ts +34 -33
  111. package/dist/AbstractFocusProvider-CxvlcEki.js +0 -29
  112. package/dist/AbstractSelectionProvider-BtaROstC.js +0 -30
  113. package/dist/CompositeDataItem-DuHOHCWy.js +0 -158
  114. package/dist/ListboxFocusProvider.d.ts +0 -149
  115. package/dist/ListboxFocusProvider.js +0 -53
  116. package/dist/MultipleSelectionProvider.d.ts +0 -141
  117. package/dist/MultipleSelectionProvider.js +0 -19
  118. package/dist/SingleSelectionProvider.d.ts +0 -141
  119. package/dist/SingleSelectionProvider.js +0 -23
  120. package/dist/banner.d.ts +0 -16
  121. package/dist/banner.js +0 -42
  122. package/dist/button.d.ts +0 -17
  123. package/dist/caption.d.ts +0 -13
  124. package/dist/caption.js +0 -27
  125. package/dist/card.d.ts +0 -46
  126. package/dist/card.js +0 -108
  127. package/dist/composite-component-DSUbd1XS.js +0 -122
  128. package/dist/composite.d.ts +0 -208
  129. package/dist/composite.js +0 -82
  130. package/dist/createLucideIcon-CzehbSja.js +0 -94
  131. package/dist/generate-tiles-DuagGD1d.js +0 -244
  132. package/dist/generate-tiles.d.ts +0 -43
  133. package/dist/generate-tiles.js +0 -7
  134. package/dist/horizontal-list.d.ts +0 -16
  135. package/dist/horizontal-list.js +0 -77
  136. package/dist/icon-generator-tuhuqdpL.js +0 -76
  137. package/dist/icon-generator.d.ts +0 -58
  138. package/dist/icon-generator.js +0 -6
  139. package/dist/index-CQhYMnjT.js +0 -34
  140. package/dist/index-U7DVCmS_.js +0 -76
  141. package/dist/input.d.ts +0 -7
  142. package/dist/listbox.d.ts +0 -171
  143. package/dist/listbox.js +0 -76
  144. package/dist/masked-image-generator.js +0 -29
  145. package/dist/navigation-menu.d.ts +0 -27
  146. package/dist/navigation-menu.js +0 -1139
  147. package/dist/overlay.d.ts +0 -13
  148. package/dist/page-header.d.ts +0 -9
  149. package/dist/page-section.d.ts +0 -14
  150. package/dist/page.d.ts +0 -7
  151. package/dist/page.js +0 -8
  152. package/dist/search-input.d.ts +0 -7
  153. package/dist/search-input.js +0 -23
  154. package/dist/tag.d.ts +0 -16
  155. package/dist/ui-components.d.ts +0 -215
  156. package/dist/ui-components.js +0 -54
  157. package/dist/utils.js +0 -4
  158. package/src/assets/icons/icon_01.svg +0 -6
  159. package/src/assets/icons/icon_02.svg +0 -6
  160. package/src/assets/icons/icon_03.svg +0 -6
  161. package/src/assets/icons/icon_04.svg +0 -6
  162. package/src/assets/icons/icon_05.svg +0 -4
  163. package/src/assets/icons/icon_06.svg +0 -4
  164. package/src/assets/images/image_01.jpg +0 -0
  165. package/src/assets/images/image_02.jpg +0 -0
  166. package/src/assets/images/image_03.webp +0 -0
  167. package/src/assets/images/image_04.png +0 -0
  168. package/src/assets/images/image_05.jpg +0 -0
  169. package/src/assets/images/image_06.jpg +0 -0
  170. package/src/components/ui/index.ts +0 -15
@@ -0,0 +1,1117 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import React__default from "react";
4
+ import ReactDOM__default from "react-dom";
5
+ import { c as createContextScope, P as Primitive, u as useControllableState, a as useId, b as Presence, d as composeEventHandlers, e as useCallbackRef, D as DismissableLayer, f as useLayoutEffect2, g as dispatchDiscreteCustomEvent } from "../../_chunks/index4.js";
6
+ import { c as composeRefs, u as useComposedRefs } from "../../_chunks/index3.js";
7
+ import { c as cn } from "../../_chunks/utils.js";
8
+ import { buttonVariants } from "./button.js";
9
+ import { c as createLucideIcon } from "../../_chunks/createLucideIcon.js";
10
+ const __iconNode = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
11
+ const ChevronDown = createLucideIcon("chevron-down", __iconNode);
12
+ var DirectionContext = React.createContext(void 0);
13
+ function useDirection(localDir) {
14
+ const globalDir = React.useContext(DirectionContext);
15
+ return localDir || globalDir || "ltr";
16
+ }
17
+ // @__NO_SIDE_EFFECTS__
18
+ function createSlot(ownerName) {
19
+ const SlotClone = /* @__PURE__ */ createSlotClone(ownerName);
20
+ const Slot2 = React.forwardRef((props, forwardedRef) => {
21
+ const { children, ...slotProps } = props;
22
+ const childrenArray = React.Children.toArray(children);
23
+ const slottable = childrenArray.find(isSlottable);
24
+ if (slottable) {
25
+ const newElement = slottable.props.children;
26
+ const newChildren = childrenArray.map((child) => {
27
+ if (child === slottable) {
28
+ if (React.Children.count(newElement) > 1) return React.Children.only(null);
29
+ return React.isValidElement(newElement) ? newElement.props.children : null;
30
+ } else {
31
+ return child;
32
+ }
33
+ });
34
+ return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children: React.isValidElement(newElement) ? React.cloneElement(newElement, void 0, newChildren) : null });
35
+ }
36
+ return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children });
37
+ });
38
+ Slot2.displayName = `${ownerName}.Slot`;
39
+ return Slot2;
40
+ }
41
+ // @__NO_SIDE_EFFECTS__
42
+ function createSlotClone(ownerName) {
43
+ const SlotClone = React.forwardRef((props, forwardedRef) => {
44
+ const { children, ...slotProps } = props;
45
+ if (React.isValidElement(children)) {
46
+ const childrenRef = getElementRef(children);
47
+ const props2 = mergeProps(slotProps, children.props);
48
+ if (children.type !== React.Fragment) {
49
+ props2.ref = forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef;
50
+ }
51
+ return React.cloneElement(children, props2);
52
+ }
53
+ return React.Children.count(children) > 1 ? React.Children.only(null) : null;
54
+ });
55
+ SlotClone.displayName = `${ownerName}.SlotClone`;
56
+ return SlotClone;
57
+ }
58
+ var SLOTTABLE_IDENTIFIER = Symbol("radix.slottable");
59
+ function isSlottable(child) {
60
+ return React.isValidElement(child) && typeof child.type === "function" && "__radixId" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;
61
+ }
62
+ function mergeProps(slotProps, childProps) {
63
+ const overrideProps = { ...childProps };
64
+ for (const propName in childProps) {
65
+ const slotPropValue = slotProps[propName];
66
+ const childPropValue = childProps[propName];
67
+ const isHandler = /^on[A-Z]/.test(propName);
68
+ if (isHandler) {
69
+ if (slotPropValue && childPropValue) {
70
+ overrideProps[propName] = (...args) => {
71
+ const result = childPropValue(...args);
72
+ slotPropValue(...args);
73
+ return result;
74
+ };
75
+ } else if (slotPropValue) {
76
+ overrideProps[propName] = slotPropValue;
77
+ }
78
+ } else if (propName === "style") {
79
+ overrideProps[propName] = { ...slotPropValue, ...childPropValue };
80
+ } else if (propName === "className") {
81
+ overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(" ");
82
+ }
83
+ }
84
+ return { ...slotProps, ...overrideProps };
85
+ }
86
+ function getElementRef(element) {
87
+ let getter = Object.getOwnPropertyDescriptor(element.props, "ref")?.get;
88
+ let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
89
+ if (mayWarn) {
90
+ return element.ref;
91
+ }
92
+ getter = Object.getOwnPropertyDescriptor(element, "ref")?.get;
93
+ mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
94
+ if (mayWarn) {
95
+ return element.props.ref;
96
+ }
97
+ return element.props.ref || element.ref;
98
+ }
99
+ function createCollection(name) {
100
+ const PROVIDER_NAME = name + "CollectionProvider";
101
+ const [createCollectionContext, createCollectionScope2] = createContextScope(PROVIDER_NAME);
102
+ const [CollectionProviderImpl, useCollectionContext] = createCollectionContext(
103
+ PROVIDER_NAME,
104
+ { collectionRef: { current: null }, itemMap: /* @__PURE__ */ new Map() }
105
+ );
106
+ const CollectionProvider = (props) => {
107
+ const { scope, children } = props;
108
+ const ref = React__default.useRef(null);
109
+ const itemMap = React__default.useRef(/* @__PURE__ */ new Map()).current;
110
+ return /* @__PURE__ */ jsx(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
111
+ };
112
+ CollectionProvider.displayName = PROVIDER_NAME;
113
+ const COLLECTION_SLOT_NAME = name + "CollectionSlot";
114
+ const CollectionSlotImpl = /* @__PURE__ */ createSlot(COLLECTION_SLOT_NAME);
115
+ const CollectionSlot = React__default.forwardRef(
116
+ (props, forwardedRef) => {
117
+ const { scope, children } = props;
118
+ const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
119
+ const composedRefs = useComposedRefs(forwardedRef, context.collectionRef);
120
+ return /* @__PURE__ */ jsx(CollectionSlotImpl, { ref: composedRefs, children });
121
+ }
122
+ );
123
+ CollectionSlot.displayName = COLLECTION_SLOT_NAME;
124
+ const ITEM_SLOT_NAME = name + "CollectionItemSlot";
125
+ const ITEM_DATA_ATTR = "data-radix-collection-item";
126
+ const CollectionItemSlotImpl = /* @__PURE__ */ createSlot(ITEM_SLOT_NAME);
127
+ const CollectionItemSlot = React__default.forwardRef(
128
+ (props, forwardedRef) => {
129
+ const { scope, children, ...itemData } = props;
130
+ const ref = React__default.useRef(null);
131
+ const composedRefs = useComposedRefs(forwardedRef, ref);
132
+ const context = useCollectionContext(ITEM_SLOT_NAME, scope);
133
+ React__default.useEffect(() => {
134
+ context.itemMap.set(ref, { ref, ...itemData });
135
+ return () => void context.itemMap.delete(ref);
136
+ });
137
+ return /* @__PURE__ */ jsx(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
138
+ }
139
+ );
140
+ CollectionItemSlot.displayName = ITEM_SLOT_NAME;
141
+ function useCollection2(scope) {
142
+ const context = useCollectionContext(name + "CollectionConsumer", scope);
143
+ const getItems = React__default.useCallback(() => {
144
+ const collectionNode = context.collectionRef.current;
145
+ if (!collectionNode) return [];
146
+ const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));
147
+ const items = Array.from(context.itemMap.values());
148
+ const orderedItems = items.sort(
149
+ (a, b) => orderedNodes.indexOf(a.ref.current) - orderedNodes.indexOf(b.ref.current)
150
+ );
151
+ return orderedItems;
152
+ }, [context.collectionRef, context.itemMap]);
153
+ return getItems;
154
+ }
155
+ return [
156
+ { Provider: CollectionProvider, Slot: CollectionSlot, ItemSlot: CollectionItemSlot },
157
+ useCollection2,
158
+ createCollectionScope2
159
+ ];
160
+ }
161
+ function usePrevious(value) {
162
+ const ref = React.useRef({ value, previous: value });
163
+ return React.useMemo(() => {
164
+ if (ref.current.value !== value) {
165
+ ref.current.previous = ref.current.value;
166
+ ref.current.value = value;
167
+ }
168
+ return ref.current.previous;
169
+ }, [value]);
170
+ }
171
+ var VISUALLY_HIDDEN_STYLES = Object.freeze({
172
+ // See: https://github.com/twbs/bootstrap/blob/main/scss/mixins/_visually-hidden.scss
173
+ position: "absolute",
174
+ border: 0,
175
+ width: 1,
176
+ height: 1,
177
+ padding: 0,
178
+ margin: -1,
179
+ overflow: "hidden",
180
+ clip: "rect(0, 0, 0, 0)",
181
+ whiteSpace: "nowrap",
182
+ wordWrap: "normal"
183
+ });
184
+ var NAME = "VisuallyHidden";
185
+ var VisuallyHidden = React.forwardRef(
186
+ (props, forwardedRef) => {
187
+ return /* @__PURE__ */ jsx(
188
+ Primitive.span,
189
+ {
190
+ ...props,
191
+ ref: forwardedRef,
192
+ style: { ...VISUALLY_HIDDEN_STYLES, ...props.style }
193
+ }
194
+ );
195
+ }
196
+ );
197
+ VisuallyHidden.displayName = NAME;
198
+ var Root = VisuallyHidden;
199
+ var NAVIGATION_MENU_NAME = "NavigationMenu";
200
+ var [Collection, useCollection, createCollectionScope] = createCollection(NAVIGATION_MENU_NAME);
201
+ var [FocusGroupCollection, useFocusGroupCollection, createFocusGroupCollectionScope] = createCollection(NAVIGATION_MENU_NAME);
202
+ var [createNavigationMenuContext] = createContextScope(
203
+ NAVIGATION_MENU_NAME,
204
+ [createCollectionScope, createFocusGroupCollectionScope]
205
+ );
206
+ var [NavigationMenuProviderImpl, useNavigationMenuContext] = createNavigationMenuContext(NAVIGATION_MENU_NAME);
207
+ var [ViewportContentProvider, useViewportContentContext] = createNavigationMenuContext(NAVIGATION_MENU_NAME);
208
+ var NavigationMenu$1 = React.forwardRef(
209
+ (props, forwardedRef) => {
210
+ const {
211
+ __scopeNavigationMenu,
212
+ value: valueProp,
213
+ onValueChange,
214
+ defaultValue,
215
+ delayDuration = 200,
216
+ skipDelayDuration = 300,
217
+ orientation = "horizontal",
218
+ dir,
219
+ ...NavigationMenuProps
220
+ } = props;
221
+ const [navigationMenu, setNavigationMenu] = React.useState(null);
222
+ const composedRef = useComposedRefs(forwardedRef, (node) => setNavigationMenu(node));
223
+ const direction = useDirection(dir);
224
+ const openTimerRef = React.useRef(0);
225
+ const closeTimerRef = React.useRef(0);
226
+ const skipDelayTimerRef = React.useRef(0);
227
+ const [isOpenDelayed, setIsOpenDelayed] = React.useState(true);
228
+ const [value, setValue] = useControllableState({
229
+ prop: valueProp,
230
+ onChange: (value2) => {
231
+ const isOpen = value2 !== "";
232
+ const hasSkipDelayDuration = skipDelayDuration > 0;
233
+ if (isOpen) {
234
+ window.clearTimeout(skipDelayTimerRef.current);
235
+ if (hasSkipDelayDuration) setIsOpenDelayed(false);
236
+ } else {
237
+ window.clearTimeout(skipDelayTimerRef.current);
238
+ skipDelayTimerRef.current = window.setTimeout(
239
+ () => setIsOpenDelayed(true),
240
+ skipDelayDuration
241
+ );
242
+ }
243
+ onValueChange?.(value2);
244
+ },
245
+ defaultProp: defaultValue ?? "",
246
+ caller: NAVIGATION_MENU_NAME
247
+ });
248
+ const startCloseTimer = React.useCallback(() => {
249
+ window.clearTimeout(closeTimerRef.current);
250
+ closeTimerRef.current = window.setTimeout(() => setValue(""), 150);
251
+ }, [setValue]);
252
+ const handleOpen = React.useCallback(
253
+ (itemValue) => {
254
+ window.clearTimeout(closeTimerRef.current);
255
+ setValue(itemValue);
256
+ },
257
+ [setValue]
258
+ );
259
+ const handleDelayedOpen = React.useCallback(
260
+ (itemValue) => {
261
+ const isOpenItem = value === itemValue;
262
+ if (isOpenItem) {
263
+ window.clearTimeout(closeTimerRef.current);
264
+ } else {
265
+ openTimerRef.current = window.setTimeout(() => {
266
+ window.clearTimeout(closeTimerRef.current);
267
+ setValue(itemValue);
268
+ }, delayDuration);
269
+ }
270
+ },
271
+ [value, setValue, delayDuration]
272
+ );
273
+ React.useEffect(() => {
274
+ return () => {
275
+ window.clearTimeout(openTimerRef.current);
276
+ window.clearTimeout(closeTimerRef.current);
277
+ window.clearTimeout(skipDelayTimerRef.current);
278
+ };
279
+ }, []);
280
+ return /* @__PURE__ */ jsx(
281
+ NavigationMenuProvider,
282
+ {
283
+ scope: __scopeNavigationMenu,
284
+ isRootMenu: true,
285
+ value,
286
+ dir: direction,
287
+ orientation,
288
+ rootNavigationMenu: navigationMenu,
289
+ onTriggerEnter: (itemValue) => {
290
+ window.clearTimeout(openTimerRef.current);
291
+ if (isOpenDelayed) handleDelayedOpen(itemValue);
292
+ else handleOpen(itemValue);
293
+ },
294
+ onTriggerLeave: () => {
295
+ window.clearTimeout(openTimerRef.current);
296
+ startCloseTimer();
297
+ },
298
+ onContentEnter: () => window.clearTimeout(closeTimerRef.current),
299
+ onContentLeave: startCloseTimer,
300
+ onItemSelect: (itemValue) => {
301
+ setValue((prevValue) => prevValue === itemValue ? "" : itemValue);
302
+ },
303
+ onItemDismiss: () => setValue(""),
304
+ children: /* @__PURE__ */ jsx(
305
+ Primitive.nav,
306
+ {
307
+ "aria-label": "Main",
308
+ "data-orientation": orientation,
309
+ dir: direction,
310
+ ...NavigationMenuProps,
311
+ ref: composedRef
312
+ }
313
+ )
314
+ }
315
+ );
316
+ }
317
+ );
318
+ NavigationMenu$1.displayName = NAVIGATION_MENU_NAME;
319
+ var SUB_NAME = "NavigationMenuSub";
320
+ var NavigationMenuSub = React.forwardRef(
321
+ (props, forwardedRef) => {
322
+ const {
323
+ __scopeNavigationMenu,
324
+ value: valueProp,
325
+ onValueChange,
326
+ defaultValue,
327
+ orientation = "horizontal",
328
+ ...subProps
329
+ } = props;
330
+ const context = useNavigationMenuContext(SUB_NAME, __scopeNavigationMenu);
331
+ const [value, setValue] = useControllableState({
332
+ prop: valueProp,
333
+ onChange: onValueChange,
334
+ defaultProp: defaultValue ?? "",
335
+ caller: SUB_NAME
336
+ });
337
+ return /* @__PURE__ */ jsx(
338
+ NavigationMenuProvider,
339
+ {
340
+ scope: __scopeNavigationMenu,
341
+ isRootMenu: false,
342
+ value,
343
+ dir: context.dir,
344
+ orientation,
345
+ rootNavigationMenu: context.rootNavigationMenu,
346
+ onTriggerEnter: (itemValue) => setValue(itemValue),
347
+ onItemSelect: (itemValue) => setValue(itemValue),
348
+ onItemDismiss: () => setValue(""),
349
+ children: /* @__PURE__ */ jsx(Primitive.div, { "data-orientation": orientation, ...subProps, ref: forwardedRef })
350
+ }
351
+ );
352
+ }
353
+ );
354
+ NavigationMenuSub.displayName = SUB_NAME;
355
+ var NavigationMenuProvider = (props) => {
356
+ const {
357
+ scope,
358
+ isRootMenu,
359
+ rootNavigationMenu,
360
+ dir,
361
+ orientation,
362
+ children,
363
+ value,
364
+ onItemSelect,
365
+ onItemDismiss,
366
+ onTriggerEnter,
367
+ onTriggerLeave,
368
+ onContentEnter,
369
+ onContentLeave
370
+ } = props;
371
+ const [viewport, setViewport] = React.useState(null);
372
+ const [viewportContent, setViewportContent] = React.useState(/* @__PURE__ */ new Map());
373
+ const [indicatorTrack, setIndicatorTrack] = React.useState(null);
374
+ return /* @__PURE__ */ jsx(
375
+ NavigationMenuProviderImpl,
376
+ {
377
+ scope,
378
+ isRootMenu,
379
+ rootNavigationMenu,
380
+ value,
381
+ previousValue: usePrevious(value),
382
+ baseId: useId(),
383
+ dir,
384
+ orientation,
385
+ viewport,
386
+ onViewportChange: setViewport,
387
+ indicatorTrack,
388
+ onIndicatorTrackChange: setIndicatorTrack,
389
+ onTriggerEnter: useCallbackRef(onTriggerEnter),
390
+ onTriggerLeave: useCallbackRef(onTriggerLeave),
391
+ onContentEnter: useCallbackRef(onContentEnter),
392
+ onContentLeave: useCallbackRef(onContentLeave),
393
+ onItemSelect: useCallbackRef(onItemSelect),
394
+ onItemDismiss: useCallbackRef(onItemDismiss),
395
+ onViewportContentChange: React.useCallback((contentValue, contentData) => {
396
+ setViewportContent((prevContent) => {
397
+ prevContent.set(contentValue, contentData);
398
+ return new Map(prevContent);
399
+ });
400
+ }, []),
401
+ onViewportContentRemove: React.useCallback((contentValue) => {
402
+ setViewportContent((prevContent) => {
403
+ if (!prevContent.has(contentValue)) return prevContent;
404
+ prevContent.delete(contentValue);
405
+ return new Map(prevContent);
406
+ });
407
+ }, []),
408
+ children: /* @__PURE__ */ jsx(Collection.Provider, { scope, children: /* @__PURE__ */ jsx(ViewportContentProvider, { scope, items: viewportContent, children }) })
409
+ }
410
+ );
411
+ };
412
+ var LIST_NAME = "NavigationMenuList";
413
+ var NavigationMenuList$1 = React.forwardRef(
414
+ (props, forwardedRef) => {
415
+ const { __scopeNavigationMenu, ...listProps } = props;
416
+ const context = useNavigationMenuContext(LIST_NAME, __scopeNavigationMenu);
417
+ const list = /* @__PURE__ */ jsx(Primitive.ul, { "data-orientation": context.orientation, ...listProps, ref: forwardedRef });
418
+ 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 }) });
419
+ }
420
+ );
421
+ NavigationMenuList$1.displayName = LIST_NAME;
422
+ var ITEM_NAME = "NavigationMenuItem";
423
+ var [NavigationMenuItemContextProvider, useNavigationMenuItemContext] = createNavigationMenuContext(ITEM_NAME);
424
+ var NavigationMenuItem$1 = React.forwardRef(
425
+ (props, forwardedRef) => {
426
+ const { __scopeNavigationMenu, value: valueProp, ...itemProps } = props;
427
+ const autoValue = useId();
428
+ const value = valueProp || autoValue || "LEGACY_REACT_AUTO_VALUE";
429
+ const contentRef = React.useRef(null);
430
+ const triggerRef = React.useRef(null);
431
+ const focusProxyRef = React.useRef(null);
432
+ const restoreContentTabOrderRef = React.useRef(() => {
433
+ });
434
+ const wasEscapeCloseRef = React.useRef(false);
435
+ const handleContentEntry = React.useCallback((side = "start") => {
436
+ if (contentRef.current) {
437
+ restoreContentTabOrderRef.current();
438
+ const candidates = getTabbableCandidates(contentRef.current);
439
+ if (candidates.length) focusFirst(side === "start" ? candidates : candidates.reverse());
440
+ }
441
+ }, []);
442
+ const handleContentExit = React.useCallback(() => {
443
+ if (contentRef.current) {
444
+ const candidates = getTabbableCandidates(contentRef.current);
445
+ if (candidates.length) restoreContentTabOrderRef.current = removeFromTabOrder(candidates);
446
+ }
447
+ }, []);
448
+ return /* @__PURE__ */ jsx(
449
+ NavigationMenuItemContextProvider,
450
+ {
451
+ scope: __scopeNavigationMenu,
452
+ value,
453
+ triggerRef,
454
+ contentRef,
455
+ focusProxyRef,
456
+ wasEscapeCloseRef,
457
+ onEntryKeyDown: handleContentEntry,
458
+ onFocusProxyEnter: handleContentEntry,
459
+ onRootContentClose: handleContentExit,
460
+ onContentFocusOutside: handleContentExit,
461
+ children: /* @__PURE__ */ jsx(Primitive.li, { ...itemProps, ref: forwardedRef })
462
+ }
463
+ );
464
+ }
465
+ );
466
+ NavigationMenuItem$1.displayName = ITEM_NAME;
467
+ var TRIGGER_NAME = "NavigationMenuTrigger";
468
+ var NavigationMenuTrigger$1 = React.forwardRef((props, forwardedRef) => {
469
+ const { __scopeNavigationMenu, disabled, ...triggerProps } = props;
470
+ const context = useNavigationMenuContext(TRIGGER_NAME, props.__scopeNavigationMenu);
471
+ const itemContext = useNavigationMenuItemContext(TRIGGER_NAME, props.__scopeNavigationMenu);
472
+ const ref = React.useRef(null);
473
+ const composedRefs = useComposedRefs(ref, itemContext.triggerRef, forwardedRef);
474
+ const triggerId = makeTriggerId(context.baseId, itemContext.value);
475
+ const contentId = makeContentId(context.baseId, itemContext.value);
476
+ const hasPointerMoveOpenedRef = React.useRef(false);
477
+ const wasClickCloseRef = React.useRef(false);
478
+ const open = itemContext.value === context.value;
479
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
480
+ /* @__PURE__ */ jsx(Collection.ItemSlot, { scope: __scopeNavigationMenu, value: itemContext.value, children: /* @__PURE__ */ jsx(FocusGroupItem, { asChild: true, children: /* @__PURE__ */ jsx(
481
+ Primitive.button,
482
+ {
483
+ id: triggerId,
484
+ disabled,
485
+ "data-disabled": disabled ? "" : void 0,
486
+ "data-state": getOpenState(open),
487
+ "aria-expanded": open,
488
+ "aria-controls": contentId,
489
+ ...triggerProps,
490
+ ref: composedRefs,
491
+ onPointerEnter: composeEventHandlers(props.onPointerEnter, () => {
492
+ wasClickCloseRef.current = false;
493
+ itemContext.wasEscapeCloseRef.current = false;
494
+ }),
495
+ onPointerMove: composeEventHandlers(
496
+ props.onPointerMove,
497
+ whenMouse(() => {
498
+ if (disabled || wasClickCloseRef.current || itemContext.wasEscapeCloseRef.current || hasPointerMoveOpenedRef.current)
499
+ return;
500
+ context.onTriggerEnter(itemContext.value);
501
+ hasPointerMoveOpenedRef.current = true;
502
+ })
503
+ ),
504
+ onPointerLeave: composeEventHandlers(
505
+ props.onPointerLeave,
506
+ whenMouse(() => {
507
+ if (disabled) return;
508
+ context.onTriggerLeave();
509
+ hasPointerMoveOpenedRef.current = false;
510
+ })
511
+ ),
512
+ onClick: composeEventHandlers(props.onClick, () => {
513
+ context.onItemSelect(itemContext.value);
514
+ wasClickCloseRef.current = open;
515
+ }),
516
+ onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
517
+ const verticalEntryKey = context.dir === "rtl" ? "ArrowLeft" : "ArrowRight";
518
+ const entryKey = { horizontal: "ArrowDown", vertical: verticalEntryKey }[context.orientation];
519
+ if (open && event.key === entryKey) {
520
+ itemContext.onEntryKeyDown();
521
+ event.preventDefault();
522
+ }
523
+ })
524
+ }
525
+ ) }) }),
526
+ open && /* @__PURE__ */ jsxs(Fragment, { children: [
527
+ /* @__PURE__ */ jsx(
528
+ Root,
529
+ {
530
+ "aria-hidden": true,
531
+ tabIndex: 0,
532
+ ref: itemContext.focusProxyRef,
533
+ onFocus: (event) => {
534
+ const content = itemContext.contentRef.current;
535
+ const prevFocusedElement = event.relatedTarget;
536
+ const wasTriggerFocused = prevFocusedElement === ref.current;
537
+ const wasFocusFromContent = content?.contains(prevFocusedElement);
538
+ if (wasTriggerFocused || !wasFocusFromContent) {
539
+ itemContext.onFocusProxyEnter(wasTriggerFocused ? "start" : "end");
540
+ }
541
+ }
542
+ }
543
+ ),
544
+ context.viewport && /* @__PURE__ */ jsx("span", { "aria-owns": contentId })
545
+ ] })
546
+ ] });
547
+ });
548
+ NavigationMenuTrigger$1.displayName = TRIGGER_NAME;
549
+ var LINK_NAME = "NavigationMenuLink";
550
+ var LINK_SELECT = "navigationMenu.linkSelect";
551
+ var NavigationMenuLink$1 = React.forwardRef(
552
+ (props, forwardedRef) => {
553
+ const { __scopeNavigationMenu, active, onSelect, ...linkProps } = props;
554
+ return /* @__PURE__ */ jsx(FocusGroupItem, { asChild: true, children: /* @__PURE__ */ jsx(
555
+ Primitive.a,
556
+ {
557
+ "data-active": active ? "" : void 0,
558
+ "aria-current": active ? "page" : void 0,
559
+ ...linkProps,
560
+ ref: forwardedRef,
561
+ onClick: composeEventHandlers(
562
+ props.onClick,
563
+ (event) => {
564
+ const target = event.target;
565
+ const linkSelectEvent = new CustomEvent(LINK_SELECT, {
566
+ bubbles: true,
567
+ cancelable: true
568
+ });
569
+ target.addEventListener(LINK_SELECT, (event2) => onSelect?.(event2), { once: true });
570
+ dispatchDiscreteCustomEvent(target, linkSelectEvent);
571
+ if (!linkSelectEvent.defaultPrevented && !event.metaKey) {
572
+ const rootContentDismissEvent = new CustomEvent(ROOT_CONTENT_DISMISS, {
573
+ bubbles: true,
574
+ cancelable: true
575
+ });
576
+ dispatchDiscreteCustomEvent(target, rootContentDismissEvent);
577
+ }
578
+ },
579
+ { checkForDefaultPrevented: false }
580
+ )
581
+ }
582
+ ) });
583
+ }
584
+ );
585
+ NavigationMenuLink$1.displayName = LINK_NAME;
586
+ var INDICATOR_NAME = "NavigationMenuIndicator";
587
+ var NavigationMenuIndicator$1 = React.forwardRef((props, forwardedRef) => {
588
+ const { forceMount, ...indicatorProps } = props;
589
+ const context = useNavigationMenuContext(INDICATOR_NAME, props.__scopeNavigationMenu);
590
+ const isVisible = Boolean(context.value);
591
+ return context.indicatorTrack ? ReactDOM__default.createPortal(
592
+ /* @__PURE__ */ jsx(Presence, { present: forceMount || isVisible, children: /* @__PURE__ */ jsx(NavigationMenuIndicatorImpl, { ...indicatorProps, ref: forwardedRef }) }),
593
+ context.indicatorTrack
594
+ ) : null;
595
+ });
596
+ NavigationMenuIndicator$1.displayName = INDICATOR_NAME;
597
+ var NavigationMenuIndicatorImpl = React.forwardRef((props, forwardedRef) => {
598
+ const { __scopeNavigationMenu, ...indicatorProps } = props;
599
+ const context = useNavigationMenuContext(INDICATOR_NAME, __scopeNavigationMenu);
600
+ const getItems = useCollection(__scopeNavigationMenu);
601
+ const [activeTrigger, setActiveTrigger] = React.useState(
602
+ null
603
+ );
604
+ const [position, setPosition] = React.useState(null);
605
+ const isHorizontal = context.orientation === "horizontal";
606
+ const isVisible = Boolean(context.value);
607
+ React.useEffect(() => {
608
+ const items = getItems();
609
+ const triggerNode = items.find((item) => item.value === context.value)?.ref.current;
610
+ if (triggerNode) setActiveTrigger(triggerNode);
611
+ }, [getItems, context.value]);
612
+ const handlePositionChange = () => {
613
+ if (activeTrigger) {
614
+ setPosition({
615
+ size: isHorizontal ? activeTrigger.offsetWidth : activeTrigger.offsetHeight,
616
+ offset: isHorizontal ? activeTrigger.offsetLeft : activeTrigger.offsetTop
617
+ });
618
+ }
619
+ };
620
+ useResizeObserver(activeTrigger, handlePositionChange);
621
+ useResizeObserver(context.indicatorTrack, handlePositionChange);
622
+ return position ? /* @__PURE__ */ jsx(
623
+ Primitive.div,
624
+ {
625
+ "aria-hidden": true,
626
+ "data-state": isVisible ? "visible" : "hidden",
627
+ "data-orientation": context.orientation,
628
+ ...indicatorProps,
629
+ ref: forwardedRef,
630
+ style: {
631
+ position: "absolute",
632
+ ...isHorizontal ? {
633
+ left: 0,
634
+ width: position.size + "px",
635
+ transform: `translateX(${position.offset}px)`
636
+ } : {
637
+ top: 0,
638
+ height: position.size + "px",
639
+ transform: `translateY(${position.offset}px)`
640
+ },
641
+ ...indicatorProps.style
642
+ }
643
+ }
644
+ ) : null;
645
+ });
646
+ var CONTENT_NAME = "NavigationMenuContent";
647
+ var NavigationMenuContent$1 = React.forwardRef((props, forwardedRef) => {
648
+ const { forceMount, ...contentProps } = props;
649
+ const context = useNavigationMenuContext(CONTENT_NAME, props.__scopeNavigationMenu);
650
+ const itemContext = useNavigationMenuItemContext(CONTENT_NAME, props.__scopeNavigationMenu);
651
+ const composedRefs = useComposedRefs(itemContext.contentRef, forwardedRef);
652
+ const open = itemContext.value === context.value;
653
+ const commonProps = {
654
+ value: itemContext.value,
655
+ triggerRef: itemContext.triggerRef,
656
+ focusProxyRef: itemContext.focusProxyRef,
657
+ wasEscapeCloseRef: itemContext.wasEscapeCloseRef,
658
+ onContentFocusOutside: itemContext.onContentFocusOutside,
659
+ onRootContentClose: itemContext.onRootContentClose,
660
+ ...contentProps
661
+ };
662
+ return !context.viewport ? /* @__PURE__ */ jsx(Presence, { present: forceMount || open, children: /* @__PURE__ */ jsx(
663
+ NavigationMenuContentImpl,
664
+ {
665
+ "data-state": getOpenState(open),
666
+ ...commonProps,
667
+ ref: composedRefs,
668
+ onPointerEnter: composeEventHandlers(props.onPointerEnter, context.onContentEnter),
669
+ onPointerLeave: composeEventHandlers(
670
+ props.onPointerLeave,
671
+ whenMouse(context.onContentLeave)
672
+ ),
673
+ style: {
674
+ // Prevent interaction when animating out
675
+ pointerEvents: !open && context.isRootMenu ? "none" : void 0,
676
+ ...commonProps.style
677
+ }
678
+ }
679
+ ) }) : /* @__PURE__ */ jsx(ViewportContentMounter, { forceMount, ...commonProps, ref: composedRefs });
680
+ });
681
+ NavigationMenuContent$1.displayName = CONTENT_NAME;
682
+ var ViewportContentMounter = React.forwardRef((props, forwardedRef) => {
683
+ const context = useNavigationMenuContext(CONTENT_NAME, props.__scopeNavigationMenu);
684
+ const { onViewportContentChange, onViewportContentRemove } = context;
685
+ useLayoutEffect2(() => {
686
+ onViewportContentChange(props.value, {
687
+ ref: forwardedRef,
688
+ ...props
689
+ });
690
+ }, [props, forwardedRef, onViewportContentChange]);
691
+ useLayoutEffect2(() => {
692
+ return () => onViewportContentRemove(props.value);
693
+ }, [props.value, onViewportContentRemove]);
694
+ return null;
695
+ });
696
+ var ROOT_CONTENT_DISMISS = "navigationMenu.rootContentDismiss";
697
+ var NavigationMenuContentImpl = React.forwardRef((props, forwardedRef) => {
698
+ const {
699
+ __scopeNavigationMenu,
700
+ value,
701
+ triggerRef,
702
+ focusProxyRef,
703
+ wasEscapeCloseRef,
704
+ onRootContentClose,
705
+ onContentFocusOutside,
706
+ ...contentProps
707
+ } = props;
708
+ const context = useNavigationMenuContext(CONTENT_NAME, __scopeNavigationMenu);
709
+ const ref = React.useRef(null);
710
+ const composedRefs = useComposedRefs(ref, forwardedRef);
711
+ const triggerId = makeTriggerId(context.baseId, value);
712
+ const contentId = makeContentId(context.baseId, value);
713
+ const getItems = useCollection(__scopeNavigationMenu);
714
+ const prevMotionAttributeRef = React.useRef(null);
715
+ const { onItemDismiss } = context;
716
+ React.useEffect(() => {
717
+ const content = ref.current;
718
+ if (context.isRootMenu && content) {
719
+ const handleClose = () => {
720
+ onItemDismiss();
721
+ onRootContentClose();
722
+ if (content.contains(document.activeElement)) triggerRef.current?.focus();
723
+ };
724
+ content.addEventListener(ROOT_CONTENT_DISMISS, handleClose);
725
+ return () => content.removeEventListener(ROOT_CONTENT_DISMISS, handleClose);
726
+ }
727
+ }, [context.isRootMenu, props.value, triggerRef, onItemDismiss, onRootContentClose]);
728
+ const motionAttribute = React.useMemo(() => {
729
+ const items = getItems();
730
+ const values = items.map((item) => item.value);
731
+ if (context.dir === "rtl") values.reverse();
732
+ const index = values.indexOf(context.value);
733
+ const prevIndex = values.indexOf(context.previousValue);
734
+ const isSelected = value === context.value;
735
+ const wasSelected = prevIndex === values.indexOf(value);
736
+ if (!isSelected && !wasSelected) return prevMotionAttributeRef.current;
737
+ const attribute = (() => {
738
+ if (index !== prevIndex) {
739
+ if (isSelected && prevIndex !== -1) return index > prevIndex ? "from-end" : "from-start";
740
+ if (wasSelected && index !== -1) return index > prevIndex ? "to-start" : "to-end";
741
+ }
742
+ return null;
743
+ })();
744
+ prevMotionAttributeRef.current = attribute;
745
+ return attribute;
746
+ }, [context.previousValue, context.value, context.dir, getItems, value]);
747
+ return /* @__PURE__ */ jsx(FocusGroup, { asChild: true, children: /* @__PURE__ */ jsx(
748
+ DismissableLayer,
749
+ {
750
+ id: contentId,
751
+ "aria-labelledby": triggerId,
752
+ "data-motion": motionAttribute,
753
+ "data-orientation": context.orientation,
754
+ ...contentProps,
755
+ ref: composedRefs,
756
+ disableOutsidePointerEvents: false,
757
+ onDismiss: () => {
758
+ const rootContentDismissEvent = new Event(ROOT_CONTENT_DISMISS, {
759
+ bubbles: true,
760
+ cancelable: true
761
+ });
762
+ ref.current?.dispatchEvent(rootContentDismissEvent);
763
+ },
764
+ onFocusOutside: composeEventHandlers(props.onFocusOutside, (event) => {
765
+ onContentFocusOutside();
766
+ const target = event.target;
767
+ if (context.rootNavigationMenu?.contains(target)) event.preventDefault();
768
+ }),
769
+ onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => {
770
+ const target = event.target;
771
+ const isTrigger = getItems().some((item) => item.ref.current?.contains(target));
772
+ const isRootViewport = context.isRootMenu && context.viewport?.contains(target);
773
+ if (isTrigger || isRootViewport || !context.isRootMenu) event.preventDefault();
774
+ }),
775
+ onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
776
+ const isMetaKey = event.altKey || event.ctrlKey || event.metaKey;
777
+ const isTabKey = event.key === "Tab" && !isMetaKey;
778
+ if (isTabKey) {
779
+ const candidates = getTabbableCandidates(event.currentTarget);
780
+ const focusedElement = document.activeElement;
781
+ const index = candidates.findIndex((candidate) => candidate === focusedElement);
782
+ const isMovingBackwards = event.shiftKey;
783
+ const nextCandidates = isMovingBackwards ? candidates.slice(0, index).reverse() : candidates.slice(index + 1, candidates.length);
784
+ if (focusFirst(nextCandidates)) {
785
+ event.preventDefault();
786
+ } else {
787
+ focusProxyRef.current?.focus();
788
+ }
789
+ }
790
+ }),
791
+ onEscapeKeyDown: composeEventHandlers(props.onEscapeKeyDown, (_event) => {
792
+ wasEscapeCloseRef.current = true;
793
+ })
794
+ }
795
+ ) });
796
+ });
797
+ var VIEWPORT_NAME = "NavigationMenuViewport";
798
+ var NavigationMenuViewport$1 = React.forwardRef((props, forwardedRef) => {
799
+ const { forceMount, ...viewportProps } = props;
800
+ const context = useNavigationMenuContext(VIEWPORT_NAME, props.__scopeNavigationMenu);
801
+ const open = Boolean(context.value);
802
+ return /* @__PURE__ */ jsx(Presence, { present: forceMount || open, children: /* @__PURE__ */ jsx(NavigationMenuViewportImpl, { ...viewportProps, ref: forwardedRef }) });
803
+ });
804
+ NavigationMenuViewport$1.displayName = VIEWPORT_NAME;
805
+ var NavigationMenuViewportImpl = React.forwardRef((props, forwardedRef) => {
806
+ const { __scopeNavigationMenu, children, ...viewportImplProps } = props;
807
+ const context = useNavigationMenuContext(VIEWPORT_NAME, __scopeNavigationMenu);
808
+ const composedRefs = useComposedRefs(forwardedRef, context.onViewportChange);
809
+ const viewportContentContext = useViewportContentContext(
810
+ CONTENT_NAME,
811
+ props.__scopeNavigationMenu
812
+ );
813
+ const [size, setSize] = React.useState(null);
814
+ const [content, setContent] = React.useState(null);
815
+ const viewportWidth = size ? size?.width + "px" : void 0;
816
+ const viewportHeight = size ? size?.height + "px" : void 0;
817
+ const open = Boolean(context.value);
818
+ const activeContentValue = open ? context.value : context.previousValue;
819
+ const handleSizeChange = () => {
820
+ if (content) setSize({ width: content.offsetWidth, height: content.offsetHeight });
821
+ };
822
+ useResizeObserver(content, handleSizeChange);
823
+ return /* @__PURE__ */ jsx(
824
+ Primitive.div,
825
+ {
826
+ "data-state": getOpenState(open),
827
+ "data-orientation": context.orientation,
828
+ ...viewportImplProps,
829
+ ref: composedRefs,
830
+ style: {
831
+ // Prevent interaction when animating out
832
+ pointerEvents: !open && context.isRootMenu ? "none" : void 0,
833
+ ["--radix-navigation-menu-viewport-width"]: viewportWidth,
834
+ ["--radix-navigation-menu-viewport-height"]: viewportHeight,
835
+ ...viewportImplProps.style
836
+ },
837
+ onPointerEnter: composeEventHandlers(props.onPointerEnter, context.onContentEnter),
838
+ onPointerLeave: composeEventHandlers(props.onPointerLeave, whenMouse(context.onContentLeave)),
839
+ children: Array.from(viewportContentContext.items).map(([value, { ref, forceMount, ...props2 }]) => {
840
+ const isActive = activeContentValue === value;
841
+ return /* @__PURE__ */ jsx(Presence, { present: forceMount || isActive, children: /* @__PURE__ */ jsx(
842
+ NavigationMenuContentImpl,
843
+ {
844
+ ...props2,
845
+ ref: composeRefs(ref, (node) => {
846
+ if (isActive && node) setContent(node);
847
+ })
848
+ }
849
+ ) }, value);
850
+ })
851
+ }
852
+ );
853
+ });
854
+ var FOCUS_GROUP_NAME = "FocusGroup";
855
+ var FocusGroup = React.forwardRef(
856
+ (props, forwardedRef) => {
857
+ const { __scopeNavigationMenu, ...groupProps } = props;
858
+ const context = useNavigationMenuContext(FOCUS_GROUP_NAME, __scopeNavigationMenu);
859
+ 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 }) }) });
860
+ }
861
+ );
862
+ var ARROW_KEYS = ["ArrowRight", "ArrowLeft", "ArrowUp", "ArrowDown"];
863
+ var FOCUS_GROUP_ITEM_NAME = "FocusGroupItem";
864
+ var FocusGroupItem = React.forwardRef(
865
+ (props, forwardedRef) => {
866
+ const { __scopeNavigationMenu, ...groupProps } = props;
867
+ const getItems = useFocusGroupCollection(__scopeNavigationMenu);
868
+ const context = useNavigationMenuContext(FOCUS_GROUP_ITEM_NAME, __scopeNavigationMenu);
869
+ return /* @__PURE__ */ jsx(FocusGroupCollection.ItemSlot, { scope: __scopeNavigationMenu, children: /* @__PURE__ */ jsx(
870
+ Primitive.button,
871
+ {
872
+ ...groupProps,
873
+ ref: forwardedRef,
874
+ onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
875
+ const isFocusNavigationKey = ["Home", "End", ...ARROW_KEYS].includes(event.key);
876
+ if (isFocusNavigationKey) {
877
+ let candidateNodes = getItems().map((item) => item.ref.current);
878
+ const prevItemKey = context.dir === "rtl" ? "ArrowRight" : "ArrowLeft";
879
+ const prevKeys = [prevItemKey, "ArrowUp", "End"];
880
+ if (prevKeys.includes(event.key)) candidateNodes.reverse();
881
+ if (ARROW_KEYS.includes(event.key)) {
882
+ const currentIndex = candidateNodes.indexOf(event.currentTarget);
883
+ candidateNodes = candidateNodes.slice(currentIndex + 1);
884
+ }
885
+ setTimeout(() => focusFirst(candidateNodes));
886
+ event.preventDefault();
887
+ }
888
+ })
889
+ }
890
+ ) });
891
+ }
892
+ );
893
+ function getTabbableCandidates(container) {
894
+ const nodes = [];
895
+ const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
896
+ acceptNode: (node) => {
897
+ const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
898
+ if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP;
899
+ return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
900
+ }
901
+ });
902
+ while (walker.nextNode()) nodes.push(walker.currentNode);
903
+ return nodes;
904
+ }
905
+ function focusFirst(candidates) {
906
+ const previouslyFocusedElement = document.activeElement;
907
+ return candidates.some((candidate) => {
908
+ if (candidate === previouslyFocusedElement) return true;
909
+ candidate.focus();
910
+ return document.activeElement !== previouslyFocusedElement;
911
+ });
912
+ }
913
+ function removeFromTabOrder(candidates) {
914
+ candidates.forEach((candidate) => {
915
+ candidate.dataset.tabindex = candidate.getAttribute("tabindex") || "";
916
+ candidate.setAttribute("tabindex", "-1");
917
+ });
918
+ return () => {
919
+ candidates.forEach((candidate) => {
920
+ const prevTabIndex = candidate.dataset.tabindex;
921
+ candidate.setAttribute("tabindex", prevTabIndex);
922
+ });
923
+ };
924
+ }
925
+ function useResizeObserver(element, onResize) {
926
+ const handleResize = useCallbackRef(onResize);
927
+ useLayoutEffect2(() => {
928
+ let rAF = 0;
929
+ if (element) {
930
+ const resizeObserver = new ResizeObserver(() => {
931
+ cancelAnimationFrame(rAF);
932
+ rAF = window.requestAnimationFrame(handleResize);
933
+ });
934
+ resizeObserver.observe(element);
935
+ return () => {
936
+ window.cancelAnimationFrame(rAF);
937
+ resizeObserver.unobserve(element);
938
+ };
939
+ }
940
+ }, [element, handleResize]);
941
+ }
942
+ function getOpenState(open) {
943
+ return open ? "open" : "closed";
944
+ }
945
+ function makeTriggerId(baseId, value) {
946
+ return `${baseId}-trigger-${value}`;
947
+ }
948
+ function makeContentId(baseId, value) {
949
+ return `${baseId}-content-${value}`;
950
+ }
951
+ function whenMouse(handler) {
952
+ return (event) => event.pointerType === "mouse" ? handler(event) : void 0;
953
+ }
954
+ var Root2 = NavigationMenu$1;
955
+ var List = NavigationMenuList$1;
956
+ var Item = NavigationMenuItem$1;
957
+ var Trigger = NavigationMenuTrigger$1;
958
+ var Link = NavigationMenuLink$1;
959
+ var Indicator = NavigationMenuIndicator$1;
960
+ var Content = NavigationMenuContent$1;
961
+ var Viewport = NavigationMenuViewport$1;
962
+ function NavigationMenu({
963
+ className,
964
+ children,
965
+ noViewport = false,
966
+ mega = false,
967
+ ...props
968
+ }) {
969
+ return /* @__PURE__ */ jsxs(
970
+ Root2,
971
+ {
972
+ "data-slot": "navigation-menu",
973
+ "data-mega": mega,
974
+ "data-viewport": !noViewport || mega,
975
+ className: cn(
976
+ "group/navigation-menu flex max-w-max flex-1 items-center justify-center",
977
+ { relative: !mega },
978
+ className
979
+ ),
980
+ ...props,
981
+ children: [
982
+ children,
983
+ (!noViewport || mega) && /* @__PURE__ */ jsx(NavigationMenuViewport, { mega })
984
+ ]
985
+ }
986
+ );
987
+ }
988
+ function NavigationMenuList({ className, ...props }) {
989
+ return /* @__PURE__ */ jsx(
990
+ List,
991
+ {
992
+ "data-slot": "navigation-menu-list",
993
+ className: cn("group flex flex-1 list-none items-center justify-center gap-1", className),
994
+ ...props
995
+ }
996
+ );
997
+ }
998
+ function NavigationMenuItem({ className, ...props }) {
999
+ return /* @__PURE__ */ jsx(Item, { "data-slot": "navigation-menu-item", className: cn("relative", className), ...props });
1000
+ }
1001
+ const navigationMenuTriggerStyle = buttonVariants({
1002
+ variant: "ghost",
1003
+ className: "data-[state=open]:hover:text-secondary data-[state=open]:focus:text-secondary data-[state=open]:text-secondary"
1004
+ });
1005
+ function NavigationMenuTrigger({
1006
+ className,
1007
+ children,
1008
+ ...props
1009
+ }) {
1010
+ return /* @__PURE__ */ jsxs(
1011
+ Trigger,
1012
+ {
1013
+ "data-slot": "navigation-menu-trigger",
1014
+ className: cn(navigationMenuTriggerStyle, "group", className),
1015
+ ...props,
1016
+ children: [
1017
+ children,
1018
+ " ",
1019
+ /* @__PURE__ */ jsx(
1020
+ ChevronDown,
1021
+ {
1022
+ className: "relative top-[1px] ml-1 size-3 transition duration-300 group-data-[state=open]:rotate-180",
1023
+ "aria-hidden": "true"
1024
+ }
1025
+ )
1026
+ ]
1027
+ }
1028
+ );
1029
+ }
1030
+ function NavigationMenuContent({ className, ...props }) {
1031
+ return /* @__PURE__ */ jsx(
1032
+ Content,
1033
+ {
1034
+ "data-slot": "navigation-menu-content",
1035
+ className: cn(
1036
+ "max-md:h-[calc(100vh-var(--spacing-page-nav))] top-0 left-0 min-w-xs w-auto absolute group-data-[mega=true]/navigation-menu:w-full",
1037
+ "data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52",
1038
+ "group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0",
1039
+ "group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:top-full group-data-[viewport=false]/navigation-menu:mt-1.5 group-data-[viewport=false]/navigation-menu:overflow-hidden group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:border group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:duration-200 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none",
1040
+ className
1041
+ ),
1042
+ ...props
1043
+ }
1044
+ );
1045
+ }
1046
+ function NavigationMenuViewport({
1047
+ className,
1048
+ mega = false,
1049
+ ...props
1050
+ }) {
1051
+ return /* @__PURE__ */ jsx(
1052
+ "div",
1053
+ {
1054
+ className: cn("absolute top-full left-0 isolate z-50 flex justify-center bg-popover", {
1055
+ "min-w-xs": !mega,
1056
+ "w-full px-(--spacing-section)": mega
1057
+ }),
1058
+ children: /* @__PURE__ */ jsx(
1059
+ Viewport,
1060
+ {
1061
+ "data-slot": "navigation-menu-viewport",
1062
+ className: cn(
1063
+ "origin-top-center duration-150 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=open]:fade-in",
1064
+ "bg-popover text-popover-foreground relative overflow-hidden w-full h-[var(--radix-navigation-menu-viewport-height)] overscroll-contain",
1065
+ {
1066
+ "mt-1.5 rounded-md border shadow md:w-[var(--radix-navigation-menu-viewport-width)]": !mega,
1067
+ "border-b-1 border-complement-1-50": mega
1068
+ },
1069
+ className
1070
+ ),
1071
+ ...props
1072
+ }
1073
+ )
1074
+ }
1075
+ );
1076
+ }
1077
+ function NavigationMenuLink({ className, ...props }) {
1078
+ return /* @__PURE__ */ jsx(
1079
+ Link,
1080
+ {
1081
+ "data-slot": "navigation-menu-link",
1082
+ className: cn(
1083
+ "[&_svg:not([class*='text-'])]:text-muted-foreground flex flex-col gap-1 rounded-sm p-2 text-sm transition-all outline-none focus-visible:ring-[3px] focus-visible:outline-1 [&_svg:not([class*='size-'])]:size-4",
1084
+ className
1085
+ ),
1086
+ ...props
1087
+ }
1088
+ );
1089
+ }
1090
+ function NavigationMenuIndicator({
1091
+ className,
1092
+ ...props
1093
+ }) {
1094
+ return /* @__PURE__ */ jsx(
1095
+ Indicator,
1096
+ {
1097
+ "data-slot": "navigation-menu-indicator",
1098
+ className: cn(
1099
+ "data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden",
1100
+ className
1101
+ ),
1102
+ ...props,
1103
+ children: /* @__PURE__ */ jsx("div", { className: "bg-border relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm shadow-md" })
1104
+ }
1105
+ );
1106
+ }
1107
+ export {
1108
+ NavigationMenu,
1109
+ NavigationMenuContent,
1110
+ NavigationMenuIndicator,
1111
+ NavigationMenuItem,
1112
+ NavigationMenuLink,
1113
+ NavigationMenuList,
1114
+ NavigationMenuTrigger,
1115
+ NavigationMenuViewport,
1116
+ navigationMenuTriggerStyle
1117
+ };