@naeil/ui 0.3.0 → 0.5.0

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 (46) hide show
  1. package/CHANGELOG.md +22 -2
  2. package/DESIGN.md +27 -0
  3. package/README.md +16 -9
  4. package/THIRD_PARTY_NOTICES.md +6 -0
  5. package/dist/chunk-CE73AEJZ.js +667 -0
  6. package/dist/{chunk-QKVN6Q6C.js → chunk-QSTGUEEI.js} +60 -175
  7. package/dist/chunk-S64H3OYQ.js +1512 -0
  8. package/dist/components/index.d.ts +33 -10
  9. package/dist/components/index.js +101 -557
  10. package/dist/components/naeil-header.d.ts +54 -0
  11. package/dist/components/naeil-header.js +14 -0
  12. package/dist/components/ui/index.d.ts +3 -1
  13. package/dist/components/ui/index.js +40 -179
  14. package/dist/navigation-CL10a6Eb.d.ts +48 -0
  15. package/dist/site-footer-B67meCDv.d.ts +21 -0
  16. package/dist/source/components/brand-artwork.generated.d.ts +162 -0
  17. package/dist/source/components/brand-artwork.generated.js +1103 -0
  18. package/dist/source/components/footer.d.ts +13 -4
  19. package/dist/source/components/footer.js +74 -114
  20. package/dist/source/components/index.d.ts +6 -4
  21. package/dist/source/components/locale-switcher.js +1 -1
  22. package/dist/source/components/logo.d.ts +13 -4
  23. package/dist/source/components/logo.js +83 -44
  24. package/dist/source/components/naeil-header-content.d.ts +171 -0
  25. package/dist/source/components/naeil-header-content.js +176 -0
  26. package/dist/source/components/naeil-header.d.ts +52 -0
  27. package/dist/source/components/naeil-header.js +196 -0
  28. package/dist/source/components/nav.d.ts +12 -4
  29. package/dist/source/components/nav.js +51 -384
  30. package/dist/source/components/ui/index.d.ts +2 -0
  31. package/dist/source/components/ui/index.js +4 -0
  32. package/dist/source/components/ui/navigation.d.ts +48 -0
  33. package/dist/source/components/ui/navigation.js +347 -0
  34. package/dist/source/components/ui/site-footer.d.ts +21 -0
  35. package/dist/source/components/ui/site-footer.js +93 -0
  36. package/docs/components/README.md +6 -1
  37. package/docs/components/common.md +1 -1
  38. package/docs/components/naeil-header.md +50 -0
  39. package/docs/components/navigation.md +59 -0
  40. package/docs/design/public-ui-support.md +17 -2
  41. package/docs/design/v2-migration.md +75 -11
  42. package/docs/package-release.md +54 -13
  43. package/licenses/Lato-OFL.txt +93 -0
  44. package/package.json +18 -4
  45. package/src/styles/components.css +292 -0
  46. package/src/styles/theme.css +4 -0
@@ -0,0 +1,667 @@
1
+ "use client";
2
+ import {
3
+ __objRest,
4
+ __spreadProps,
5
+ __spreadValues,
6
+ cn
7
+ } from "./chunk-JBTDRVZ7.js";
8
+
9
+ // src/components/ui/badge.tsx
10
+ import { cva } from "class-variance-authority";
11
+ import { Slot } from "radix-ui";
12
+ import { jsx } from "react/jsx-runtime";
13
+ var badgeVariants = cva(
14
+ "inline-flex items-center justify-center rounded-sm border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none ui-focus aria-invalid:border-error transition-colors overflow-hidden",
15
+ {
16
+ variants: {
17
+ variant: {
18
+ success: "bg-success-bg text-success border-transparent",
19
+ warning: "bg-warning-bg text-warning border-transparent",
20
+ error: "bg-error-bg text-error border-transparent",
21
+ info: "bg-info-bg text-info border-transparent",
22
+ default: "bg-primary text-primary-foreground border-transparent [a&]:hover:bg-primary/90",
23
+ secondary: "bg-secondary text-secondary-foreground border-transparent [a&]:hover:bg-secondary/80",
24
+ outline: "border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
25
+ destructive: "bg-destructive text-destructive-foreground border-transparent [a&]:hover:bg-destructive/90"
26
+ }
27
+ },
28
+ defaultVariants: {
29
+ variant: "default"
30
+ }
31
+ }
32
+ );
33
+ function Badge(_a) {
34
+ var _b = _a, {
35
+ className,
36
+ variant = "default",
37
+ asChild = false
38
+ } = _b, props = __objRest(_b, [
39
+ "className",
40
+ "variant",
41
+ "asChild"
42
+ ]);
43
+ const Comp = asChild ? Slot.Root : "span";
44
+ return /* @__PURE__ */ jsx(
45
+ Comp,
46
+ __spreadValues({
47
+ "data-slot": "badge",
48
+ "data-variant": variant,
49
+ className: cn(badgeVariants({ variant }), className)
50
+ }, props)
51
+ );
52
+ }
53
+
54
+ // src/components/ui/button.tsx
55
+ import { cva as cva2 } from "class-variance-authority";
56
+ import { Slot as Slot2 } from "radix-ui";
57
+ import { jsx as jsx2 } from "react/jsx-runtime";
58
+ var buttonVariants = cva2(
59
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap ui-control ui-focus rounded-md text-base font-medium transition-colors duration-(--ui-motion-fast) cursor-pointer disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 ui-focus aria-invalid:border-error",
60
+ {
61
+ variants: {
62
+ variant: {
63
+ default: "bg-primary text-primary-foreground hover:bg-primary-hover",
64
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90 ",
65
+ outline: "border border-border-strong bg-background hover:bg-surface-subtle",
66
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
67
+ ghost: "hover:bg-surface-subtle",
68
+ link: "text-primary underline-offset-4 hover:underline"
69
+ },
70
+ size: {
71
+ default: "px-4 has-[>svg]:px-3",
72
+ xs: "gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
73
+ sm: "rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
74
+ lg: "rounded-md px-6 has-[>svg]:px-4",
75
+ icon: "",
76
+ "icon-xs": "rounded-md [&_svg:not([class*='size-'])]:size-3",
77
+ "icon-sm": "",
78
+ "icon-lg": ""
79
+ }
80
+ },
81
+ defaultVariants: {
82
+ variant: "default",
83
+ size: "default"
84
+ }
85
+ }
86
+ );
87
+ function Button(_a) {
88
+ var _b = _a, {
89
+ className,
90
+ variant = "default",
91
+ size = "default",
92
+ asChild = false
93
+ } = _b, props = __objRest(_b, [
94
+ "className",
95
+ "variant",
96
+ "size",
97
+ "asChild"
98
+ ]);
99
+ const Comp = asChild ? Slot2.Root : "button";
100
+ return /* @__PURE__ */ jsx2(
101
+ Comp,
102
+ __spreadValues({
103
+ "data-slot": "button",
104
+ "data-variant": variant,
105
+ "data-size": size,
106
+ className: cn(buttonVariants({ variant, size, className }))
107
+ }, props)
108
+ );
109
+ }
110
+
111
+ // src/components/ui/select.tsx
112
+ import { Select as Primitive } from "radix-ui";
113
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
114
+
115
+ // src/lib/design/modal-inert.ts
116
+ import { useEffect, useMemo, useState } from "react";
117
+ var ownershipKey = /* @__PURE__ */ Symbol.for("@naeil/ui/radix-hidden-inert/v1");
118
+ function ownershipFor(doc) {
119
+ var _a;
120
+ const shared = doc;
121
+ return (_a = shared[ownershipKey]) != null ? _a : shared[ownershipKey] = /* @__PURE__ */ new WeakMap();
122
+ }
123
+ function useRadixHiddenInert(content) {
124
+ useEffect(() => {
125
+ if (!content) return;
126
+ const doc = content.ownerDocument;
127
+ const ownership = ownershipFor(doc);
128
+ const held = /* @__PURE__ */ new Set();
129
+ function release(element) {
130
+ held.delete(element);
131
+ const state = ownership.get(element);
132
+ if (!state || --state.users > 0) return;
133
+ element.inert = state.original;
134
+ ownership.delete(element);
135
+ }
136
+ function sync() {
137
+ const hidden = (content == null ? void 0 : content.isConnected) && content.dataset.state === "open" ? [...doc.querySelectorAll('[data-aria-hidden="true"][aria-hidden="true"]')].filter((element) => !element.contains(content)) : [];
138
+ const desired = new Set(hidden);
139
+ for (const element of held) if (!desired.has(element)) release(element);
140
+ for (const element of desired) {
141
+ if (held.has(element)) continue;
142
+ let state = ownership.get(element);
143
+ if (!state) {
144
+ state = { users: 0, original: element.inert };
145
+ ownership.set(element, state);
146
+ }
147
+ state.users++;
148
+ held.add(element);
149
+ element.inert = true;
150
+ }
151
+ }
152
+ const observer = new MutationObserver(sync);
153
+ observer.observe(doc.body, {
154
+ subtree: true,
155
+ childList: true,
156
+ attributes: true,
157
+ attributeFilter: ["aria-hidden", "data-aria-hidden", "data-state"]
158
+ });
159
+ sync();
160
+ return () => {
161
+ observer.disconnect();
162
+ for (const element of held) release(element);
163
+ };
164
+ }, [content]);
165
+ }
166
+ function assignObjectRef(ref, node) {
167
+ ref.current = node;
168
+ }
169
+ function useOverlayRef(consumerRef) {
170
+ const [node, setNode] = useState(null);
171
+ const ref = useMemo(() => (value) => {
172
+ setNode(value);
173
+ const cleanup = typeof consumerRef === "function" ? consumerRef(value) : void 0;
174
+ if (consumerRef && typeof consumerRef !== "function") assignObjectRef(consumerRef, value);
175
+ return () => {
176
+ setNode(null);
177
+ if (typeof cleanup === "function") cleanup();
178
+ else if (typeof consumerRef === "function") consumerRef(null);
179
+ else if (consumerRef) assignObjectRef(consumerRef, null);
180
+ };
181
+ }, [consumerRef]);
182
+ return [node, ref];
183
+ }
184
+
185
+ // src/components/ui/select.tsx
186
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
187
+ var Select = Primitive.Root;
188
+ var SelectValue = Primitive.Value;
189
+ var SelectGroup = Primitive.Group;
190
+ function SelectTrigger(_a) {
191
+ var _b = _a, {
192
+ className,
193
+ children
194
+ } = _b, props = __objRest(_b, [
195
+ "className",
196
+ "children"
197
+ ]);
198
+ return /* @__PURE__ */ jsxs(
199
+ Primitive.Trigger,
200
+ __spreadProps(__spreadValues({
201
+ "data-slot": "select-trigger",
202
+ className: cn(
203
+ "ui-control ui-focus flex w-full items-center justify-between gap-2 border border-input bg-background px-3 text-left text-foreground disabled:cursor-not-allowed disabled:opacity-45 data-[placeholder]:text-muted-foreground [&>span]:min-w-0 [&>span]:truncate",
204
+ className
205
+ )
206
+ }, props), {
207
+ children: [
208
+ children,
209
+ /* @__PURE__ */ jsx3(Primitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx3(ChevronDownIcon, { className: "size-4 shrink-0" }) })
210
+ ]
211
+ })
212
+ );
213
+ }
214
+ function SelectContent(_a) {
215
+ var _b = _a, {
216
+ ref,
217
+ className,
218
+ children,
219
+ position = "popper",
220
+ sideOffset = 6
221
+ } = _b, props = __objRest(_b, [
222
+ "ref",
223
+ "className",
224
+ "children",
225
+ "position",
226
+ "sideOffset"
227
+ ]);
228
+ const [content, contentRef] = useOverlayRef(ref);
229
+ useRadixHiddenInert(content);
230
+ return /* @__PURE__ */ jsx3(Primitive.Portal, { children: /* @__PURE__ */ jsxs(
231
+ Primitive.Content,
232
+ __spreadProps(__spreadValues({
233
+ ref: contentRef,
234
+ "data-slot": "select-content",
235
+ position,
236
+ sideOffset,
237
+ className: cn(
238
+ "ui-menu ui-popup z-50 max-h-(--radix-select-content-available-height) min-w-(--radix-select-trigger-width) max-w-[calc(100vw-24px)] overflow-hidden",
239
+ className
240
+ )
241
+ }, props), {
242
+ children: [
243
+ /* @__PURE__ */ jsx3(SelectScrollUpButton, {}),
244
+ /* @__PURE__ */ jsx3(Primitive.Viewport, { className: "p-1", children }),
245
+ /* @__PURE__ */ jsx3(SelectScrollDownButton, {})
246
+ ]
247
+ })
248
+ ) });
249
+ }
250
+ function SelectItem(_a) {
251
+ var _b = _a, {
252
+ className,
253
+ children
254
+ } = _b, props = __objRest(_b, [
255
+ "className",
256
+ "children"
257
+ ]);
258
+ return /* @__PURE__ */ jsxs(
259
+ Primitive.Item,
260
+ __spreadProps(__spreadValues({
261
+ "data-slot": "select-item",
262
+ className: cn(
263
+ "relative flex cursor-default items-center rounded-sm py-2 pr-9 pl-3 text-base outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-45",
264
+ className
265
+ )
266
+ }, props), {
267
+ children: [
268
+ /* @__PURE__ */ jsx3(Primitive.ItemText, { children }),
269
+ /* @__PURE__ */ jsx3(Primitive.ItemIndicator, { className: "absolute right-3", children: /* @__PURE__ */ jsx3(CheckIcon, { className: "size-4" }) })
270
+ ]
271
+ })
272
+ );
273
+ }
274
+ function SelectLabel(_a) {
275
+ var _b = _a, {
276
+ className
277
+ } = _b, props = __objRest(_b, [
278
+ "className"
279
+ ]);
280
+ return /* @__PURE__ */ jsx3(
281
+ Primitive.Label,
282
+ __spreadValues({
283
+ "data-slot": "select-label",
284
+ className: cn(
285
+ "px-3 py-2 text-sm font-medium text-muted-foreground",
286
+ className
287
+ )
288
+ }, props)
289
+ );
290
+ }
291
+ function SelectSeparator(_a) {
292
+ var _b = _a, {
293
+ className
294
+ } = _b, props = __objRest(_b, [
295
+ "className"
296
+ ]);
297
+ return /* @__PURE__ */ jsx3(
298
+ Primitive.Separator,
299
+ __spreadValues({
300
+ "data-slot": "select-separator",
301
+ className: cn("my-1 h-px bg-border", className)
302
+ }, props)
303
+ );
304
+ }
305
+ function SelectScrollUpButton(_a) {
306
+ var _b = _a, {
307
+ className
308
+ } = _b, props = __objRest(_b, [
309
+ "className"
310
+ ]);
311
+ return /* @__PURE__ */ jsx3(
312
+ Primitive.ScrollUpButton,
313
+ __spreadProps(__spreadValues({
314
+ className: cn("flex h-8 items-center justify-center", className)
315
+ }, props), {
316
+ children: /* @__PURE__ */ jsx3(ChevronUpIcon, { className: "size-4" })
317
+ })
318
+ );
319
+ }
320
+ function SelectScrollDownButton(_a) {
321
+ var _b = _a, {
322
+ className
323
+ } = _b, props = __objRest(_b, [
324
+ "className"
325
+ ]);
326
+ return /* @__PURE__ */ jsx3(
327
+ Primitive.ScrollDownButton,
328
+ __spreadProps(__spreadValues({
329
+ className: cn("flex h-8 items-center justify-center", className)
330
+ }, props), {
331
+ children: /* @__PURE__ */ jsx3(ChevronDownIcon, { className: "size-4" })
332
+ })
333
+ );
334
+ }
335
+
336
+ // src/components/ui/navigation.tsx
337
+ import * as React from "react";
338
+ import { Dialog, Popover } from "radix-ui";
339
+ import { Check, ChevronDown, Menu, X } from "lucide-react";
340
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
341
+ var NativeLink = React.forwardRef(
342
+ function NativeLink2(props, ref) {
343
+ return /* @__PURE__ */ jsx4("a", __spreadValues({ ref }, props));
344
+ }
345
+ );
346
+ function DesktopGroup({
347
+ item,
348
+ active,
349
+ open,
350
+ anotherGroupOpen,
351
+ onOpenChange,
352
+ children
353
+ }) {
354
+ var _a;
355
+ const hoverOpened = React.useRef(false);
356
+ const closeTimer = React.useRef(
357
+ void 0
358
+ );
359
+ const panel = React.useRef(null);
360
+ const trigger = React.useRef(null);
361
+ const pointerType = React.useRef("");
362
+ const cancelClose = React.useCallback(() => {
363
+ clearTimeout(closeTimer.current);
364
+ }, []);
365
+ React.useEffect(() => {
366
+ return cancelClose;
367
+ }, [open, cancelClose]);
368
+ const leave = (event) => {
369
+ if (event.pointerType !== "mouse") return;
370
+ cancelClose();
371
+ const duration = getComputedStyle(event.currentTarget).getPropertyValue("--ui-motion-standard").trim();
372
+ closeTimer.current = setTimeout(
373
+ () => {
374
+ if (hoverOpened.current) onOpenChange(false);
375
+ },
376
+ parseFloat(duration) * (duration.endsWith("ms") ? 1 : 1e3)
377
+ );
378
+ };
379
+ return /* @__PURE__ */ jsxs2(
380
+ Popover.Root,
381
+ {
382
+ open,
383
+ onOpenChange: (next) => {
384
+ cancelClose();
385
+ if (next) hoverOpened.current = false;
386
+ onOpenChange(next);
387
+ },
388
+ children: [
389
+ /* @__PURE__ */ jsxs2(
390
+ Popover.Trigger,
391
+ {
392
+ ref: trigger,
393
+ className: "ui-navigation-link ui-focus",
394
+ "data-active": active || void 0,
395
+ onPointerEnter: (event) => {
396
+ if (event.pointerType !== "mouse") return;
397
+ cancelClose();
398
+ if (!open) {
399
+ hoverOpened.current = true;
400
+ onOpenChange(true);
401
+ }
402
+ },
403
+ onPointerLeave: leave,
404
+ onPointerDown: (event) => {
405
+ pointerType.current = event.pointerType;
406
+ },
407
+ onClick: (event) => {
408
+ var _a2, _b;
409
+ if (event.detail > 0 && pointerType.current === "mouse") {
410
+ event.preventDefault();
411
+ cancelClose();
412
+ hoverOpened.current = true;
413
+ onOpenChange(true);
414
+ return;
415
+ }
416
+ if (open && hoverOpened.current) {
417
+ event.preventDefault();
418
+ hoverOpened.current = false;
419
+ cancelClose();
420
+ (_b = (_a2 = panel.current) == null ? void 0 : _a2.querySelector("a[href]")) == null ? void 0 : _b.focus();
421
+ }
422
+ },
423
+ children: [
424
+ item.label,
425
+ /* @__PURE__ */ jsx4(ChevronDown, { size: 16, "aria-hidden": "true" })
426
+ ]
427
+ }
428
+ ),
429
+ /* @__PURE__ */ jsx4(Popover.Portal, { children: /* @__PURE__ */ jsx4(
430
+ Popover.Content,
431
+ {
432
+ ref: panel,
433
+ "data-slot": "navigation-popover",
434
+ className: "ui-navigation-popover ui-popup",
435
+ "data-columns": (_a = item.columns) != null ? _a : 1,
436
+ align: "start",
437
+ sideOffset: 8,
438
+ "aria-label": item.label,
439
+ onPointerEnter: cancelClose,
440
+ onPointerLeave: leave,
441
+ onFocusCapture: () => {
442
+ hoverOpened.current = false;
443
+ cancelClose();
444
+ },
445
+ onOpenAutoFocus: (event) => {
446
+ if (hoverOpened.current) event.preventDefault();
447
+ },
448
+ onCloseAutoFocus: (event) => {
449
+ if (hoverOpened.current || anotherGroupOpen) event.preventDefault();
450
+ },
451
+ onInteractOutside: (event) => {
452
+ var _a2;
453
+ if ((_a2 = trigger.current) == null ? void 0 : _a2.contains(event.target))
454
+ event.preventDefault();
455
+ },
456
+ children: /* @__PURE__ */ jsx4("nav", { "aria-label": item.label, className: "ui-navigation-menu-grid", children })
457
+ }
458
+ ) })
459
+ ]
460
+ }
461
+ );
462
+ }
463
+ function Navigation(_a) {
464
+ var _b = _a, {
465
+ brand,
466
+ items,
467
+ labels,
468
+ Link = NativeLink,
469
+ currentHref,
470
+ toolbar,
471
+ mobileToolbar,
472
+ mobileFooter,
473
+ containerClassName,
474
+ onNavigate,
475
+ className
476
+ } = _b, props = __objRest(_b, [
477
+ "brand",
478
+ "items",
479
+ "labels",
480
+ "Link",
481
+ "currentHref",
482
+ "toolbar",
483
+ "mobileToolbar",
484
+ "mobileFooter",
485
+ "containerClassName",
486
+ "onNavigate",
487
+ "className"
488
+ ]);
489
+ const [mobileOpen, setMobileOpen] = React.useState(false);
490
+ const [openGroup, setOpenGroup] = React.useState(null);
491
+ const trigger = React.useRef(null);
492
+ const desktop = React.useRef(null);
493
+ React.useEffect(() => {
494
+ setMobileOpen(false);
495
+ setOpenGroup(null);
496
+ }, [currentHref]);
497
+ React.useEffect(() => {
498
+ const element = desktop.current;
499
+ if (!element || typeof ResizeObserver === "undefined") return;
500
+ const observer = new ResizeObserver(() => {
501
+ if (element.getBoundingClientRect().width > 0) setMobileOpen(false);
502
+ else setOpenGroup(null);
503
+ });
504
+ observer.observe(element);
505
+ return () => observer.disconnect();
506
+ }, []);
507
+ const active = (item) => {
508
+ var _a2;
509
+ return (_a2 = item.active) != null ? _a2 : !item.external && item.href === currentHref;
510
+ };
511
+ function link(item, close, entry = false) {
512
+ const Component = item.external ? NativeLink : Link;
513
+ return /* @__PURE__ */ jsxs2(
514
+ Component,
515
+ {
516
+ href: item.href,
517
+ target: item.target,
518
+ rel: item.target === "_blank" ? "noopener noreferrer" : void 0,
519
+ "aria-current": active(item) ? "page" : void 0,
520
+ className: cn(
521
+ "ui-navigation-link ui-focus",
522
+ entry && "ui-navigation-entry"
523
+ ),
524
+ onClick: (event) => {
525
+ onNavigate == null ? void 0 : onNavigate(event, item);
526
+ if (event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey)
527
+ close == null ? void 0 : close();
528
+ },
529
+ children: [
530
+ item.icon && /* @__PURE__ */ jsx4("span", { className: "ui-navigation-icon", "aria-hidden": "true", children: item.icon }),
531
+ /* @__PURE__ */ jsxs2("span", { className: "ui-navigation-copy", children: [
532
+ /* @__PURE__ */ jsxs2("span", { className: "ui-navigation-title", children: [
533
+ /* @__PURE__ */ jsx4("span", { children: item.label }),
534
+ item.badge,
535
+ entry && active(item) && /* @__PURE__ */ jsx4(Check, { size: 16, className: "shrink-0", "aria-hidden": "true" })
536
+ ] }),
537
+ item.description && /* @__PURE__ */ jsx4("span", { className: "ui-navigation-description", children: item.description })
538
+ ] })
539
+ ]
540
+ },
541
+ item.id
542
+ );
543
+ }
544
+ return /* @__PURE__ */ jsx4(
545
+ "header",
546
+ __spreadProps(__spreadValues({
547
+ "data-slot": "navigation",
548
+ className: cn("ui-navigation", className)
549
+ }, props), {
550
+ children: /* @__PURE__ */ jsx4("div", { className: cn("ui-navigation-frame", containerClassName), children: /* @__PURE__ */ jsxs2("div", { className: "ui-navigation-row", children: [
551
+ /* @__PURE__ */ jsx4("div", { className: "ui-navigation-brand", children: brand }),
552
+ /* @__PURE__ */ jsx4(
553
+ "nav",
554
+ {
555
+ ref: desktop,
556
+ "aria-label": labels.navigation,
557
+ className: "ui-navigation-desktop",
558
+ children: items.map(
559
+ (item) => "items" in item ? /* @__PURE__ */ jsx4(
560
+ DesktopGroup,
561
+ {
562
+ item,
563
+ active: item.items.some(active),
564
+ open: openGroup === item.id,
565
+ anotherGroupOpen: openGroup !== null && openGroup !== item.id,
566
+ onOpenChange: (open) => setOpenGroup(
567
+ (current) => open ? item.id : current === item.id ? null : current
568
+ ),
569
+ children: item.items.map(
570
+ (child) => link(child, () => setOpenGroup(null), true)
571
+ )
572
+ },
573
+ item.id
574
+ ) : link(item)
575
+ )
576
+ }
577
+ ),
578
+ /* @__PURE__ */ jsx4("div", { className: "ui-navigation-toolbar", children: toolbar }),
579
+ /* @__PURE__ */ jsxs2(Dialog.Root, { open: mobileOpen, onOpenChange: setMobileOpen, children: [
580
+ /* @__PURE__ */ jsx4(
581
+ Dialog.Trigger,
582
+ {
583
+ ref: trigger,
584
+ className: "ui-navigation-toggle ui-navigation-link ui-focus",
585
+ "aria-label": labels.menu,
586
+ children: /* @__PURE__ */ jsx4(Menu, { "aria-hidden": "true", size: 20 })
587
+ }
588
+ ),
589
+ /* @__PURE__ */ jsxs2(Dialog.Portal, { children: [
590
+ /* @__PURE__ */ jsx4(
591
+ Dialog.Overlay,
592
+ {
593
+ "data-slot": "navigation-overlay",
594
+ className: "ui-navigation-overlay ui-popup"
595
+ }
596
+ ),
597
+ /* @__PURE__ */ jsxs2(
598
+ Dialog.Content,
599
+ {
600
+ "data-slot": "navigation-sheet",
601
+ className: "ui-navigation-sheet ui-popup",
602
+ "aria-describedby": void 0,
603
+ onCloseAutoFocus: (event) => {
604
+ var _a2, _b2;
605
+ if (trigger.current && trigger.current.getBoundingClientRect().width === 0) {
606
+ event.preventDefault();
607
+ (_b2 = (_a2 = desktop.current) == null ? void 0 : _a2.querySelector("button, a")) == null ? void 0 : _b2.focus();
608
+ }
609
+ },
610
+ children: [
611
+ /* @__PURE__ */ jsxs2("div", { className: "ui-navigation-sheet-heading", children: [
612
+ /* @__PURE__ */ jsx4(Dialog.Title, { className: "text-xl font-semibold", children: labels.menu }),
613
+ /* @__PURE__ */ jsx4(
614
+ Dialog.Close,
615
+ {
616
+ className: "ui-navigation-link ui-focus",
617
+ "aria-label": labels.close,
618
+ children: /* @__PURE__ */ jsx4(X, { size: 20, "aria-hidden": "true" })
619
+ }
620
+ )
621
+ ] }),
622
+ /* @__PURE__ */ jsx4(
623
+ "nav",
624
+ {
625
+ "aria-label": labels.navigation,
626
+ className: "ui-navigation-mobile-links",
627
+ children: items.map(
628
+ (item) => "items" in item ? /* @__PURE__ */ jsxs2("section", { "aria-label": item.label, children: [
629
+ /* @__PURE__ */ jsx4("h3", { className: "ui-navigation-group-label", children: item.label }),
630
+ item.items.map(
631
+ (child) => link(child, () => setMobileOpen(false), true)
632
+ )
633
+ ] }, item.id) : link(item, () => setMobileOpen(false))
634
+ )
635
+ }
636
+ ),
637
+ (mobileToolbar != null ? mobileToolbar : toolbar) && /* @__PURE__ */ jsx4("div", { className: "ui-navigation-mobile-toolbar", children: mobileToolbar != null ? mobileToolbar : toolbar }),
638
+ mobileFooter && /* @__PURE__ */ jsx4("div", { className: "ui-navigation-mobile-footer", children: mobileFooter })
639
+ ]
640
+ }
641
+ )
642
+ ] })
643
+ ] })
644
+ ] }) })
645
+ })
646
+ );
647
+ }
648
+
649
+ export {
650
+ badgeVariants,
651
+ Badge,
652
+ buttonVariants,
653
+ Button,
654
+ useRadixHiddenInert,
655
+ useOverlayRef,
656
+ Select,
657
+ SelectValue,
658
+ SelectGroup,
659
+ SelectTrigger,
660
+ SelectContent,
661
+ SelectItem,
662
+ SelectLabel,
663
+ SelectSeparator,
664
+ SelectScrollUpButton,
665
+ SelectScrollDownButton,
666
+ Navigation
667
+ };