@naeil/ui 0.4.0 → 0.6.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 (42) hide show
  1. package/CHANGELOG.md +19 -1
  2. package/DESIGN.md +24 -1
  3. package/README.md +25 -9
  4. package/THIRD_PARTY_NOTICES.md +4 -0
  5. package/dist/chunk-CE73AEJZ.js +667 -0
  6. package/dist/{chunk-QKVN6Q6C.js → chunk-QSTGUEEI.js} +60 -175
  7. package/dist/chunk-VL7FS4QM.js +1512 -0
  8. package/dist/components/index.d.ts +19 -5
  9. package/dist/components/index.js +135 -1618
  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 +2 -0
  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/footer.d.ts +13 -4
  17. package/dist/source/components/footer.js +74 -71
  18. package/dist/source/components/index.d.ts +5 -3
  19. package/dist/source/components/locale-switcher.js +1 -1
  20. package/dist/source/components/naeil-header-content.d.ts +171 -0
  21. package/dist/source/components/naeil-header-content.js +176 -0
  22. package/dist/source/components/naeil-header.d.ts +52 -0
  23. package/dist/source/components/naeil-header.js +196 -0
  24. package/dist/source/components/nav.d.ts +10 -2
  25. package/dist/source/components/nav.js +51 -347
  26. package/dist/source/components/ui/index.d.ts +2 -0
  27. package/dist/source/components/ui/index.js +4 -0
  28. package/dist/source/components/ui/navigation.d.ts +48 -0
  29. package/dist/source/components/ui/navigation.js +347 -0
  30. package/dist/source/components/ui/site-footer.d.ts +21 -0
  31. package/dist/source/components/ui/site-footer.js +93 -0
  32. package/docs/components/README.md +8 -1
  33. package/docs/components/application-layout.md +102 -0
  34. package/docs/components/common.md +2 -2
  35. package/docs/components/naeil-header.md +50 -0
  36. package/docs/components/navigation.md +57 -0
  37. package/docs/design/public-ui-support.md +14 -1
  38. package/docs/design/v2-migration.md +59 -26
  39. package/docs/package-release.md +40 -14
  40. package/package.json +13 -1
  41. package/src/styles/components.css +292 -0
  42. package/src/styles/theme.css +7 -1
@@ -0,0 +1,54 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { a as NavigationProps, b as NavigationLinkProps, N as NavigationLink, c as NavigationLinkComponent } from '../navigation-CL10a6Eb.js';
4
+
5
+ declare const headerLocales: readonly ["en", "ko", "ja"];
6
+ type NaeilHeaderLocale = (typeof headerLocales)[number];
7
+
8
+ interface NaeilHeaderProps extends Omit<NavigationProps, "brand" | "items" | "toolbar" | "mobileToolbar" | "labels"> {
9
+ locale: NaeilHeaderLocale;
10
+ /** Resolve canonical unlocalized paths. Defaults to the official localized site. */
11
+ resolveHref?: (path: string) => string;
12
+ brandHref?: string;
13
+ brandSlot?: ReactNode;
14
+ brandLinkProps?: Omit<NavigationLinkProps, "href" | "children">;
15
+ /** Omit when the application does not support changing its UI language. */
16
+ onLocaleChange?: (locale: NaeilHeaderLocale) => void;
17
+ /** Application-owned authentication; this module has no site session/backend. */
18
+ authSlot?: ReactNode;
19
+ labels?: NavigationProps["labels"];
20
+ projects?: NavigationLink[];
21
+ /** Legacy remote-catalog mode: generated noncurrent project/blog links use native anchors. */
22
+ projectsExternal?: boolean;
23
+ /** Legacy next-intl copy overrides; catalog/artwork/layout remain shared. */
24
+ translations?: {
25
+ projects: string;
26
+ blog: string;
27
+ project: (key: string) => string;
28
+ };
29
+ showProjects?: boolean;
30
+ showBlog?: boolean;
31
+ subNav?: Array<{
32
+ label: string;
33
+ href: string;
34
+ }>;
35
+ currentProjectKey?: string;
36
+ currentProjectHref?: string;
37
+ /** Compatibility escape hatch replacing the default theme/locale/auth toolbar. */
38
+ toolbarSlot?: ReactNode;
39
+ /** Compatibility escape hatch for the legacy native external brand link. */
40
+ brandLinkComponent?: NavigationLinkComponent;
41
+ }
42
+ /** The actual header theme control; reads only the consumer's theme provider. */
43
+ declare function NaeilHeaderThemeControl({ locale }: {
44
+ locale: NaeilHeaderLocale;
45
+ }): react_jsx_runtime.JSX.Element;
46
+ /** Shared rendering used by the whole header and legacy site control adapters. */
47
+ declare function NaeilHeaderLocaleControl({ locale, onLocaleChange }: {
48
+ locale: NaeilHeaderLocale;
49
+ onLocaleChange: (locale: NaeilHeaderLocale) => void;
50
+ }): react_jsx_runtime.JSX.Element;
51
+ /** One complete, opt-in branded composition shared by naeil.dev and applications. */
52
+ declare function NaeilHeader({ locale, resolveHref, brandHref, brandSlot, brandLinkProps, brandLinkComponent, onLocaleChange, authSlot, toolbarSlot, projects, projectsExternal, translations, showProjects, showBlog, subNav, currentProjectKey, currentProjectHref, labels, Link, currentHref, onNavigate, className, containerClassName, ...props }: NaeilHeaderProps): react_jsx_runtime.JSX.Element;
53
+
54
+ export { NaeilHeader, type NaeilHeaderLocale, NaeilHeaderLocaleControl, type NaeilHeaderProps, NaeilHeaderThemeControl };
@@ -0,0 +1,14 @@
1
+ "use client";
2
+ "use client";
3
+ import {
4
+ NaeilHeader,
5
+ NaeilHeaderLocaleControl,
6
+ NaeilHeaderThemeControl
7
+ } from "../chunk-VL7FS4QM.js";
8
+ import "../chunk-CE73AEJZ.js";
9
+ import "../chunk-JBTDRVZ7.js";
10
+ export {
11
+ NaeilHeader,
12
+ NaeilHeaderLocaleControl,
13
+ NaeilHeaderThemeControl
14
+ };
@@ -4,6 +4,8 @@ import { Avatar as Avatar$1, Dialog as Dialog$1, DropdownMenu as DropdownMenu$1,
4
4
  import * as class_variance_authority_types from 'class-variance-authority/types';
5
5
  import { VariantProps } from 'class-variance-authority';
6
6
  import { ToasterProps } from 'sonner';
7
+ export { d as Navigation, e as NavigationGroup, f as NavigationItem, N as NavigationLink, c as NavigationLinkComponent, b as NavigationLinkProps, a as NavigationProps } from '../../navigation-CL10a6Eb.js';
8
+ export { a as SiteFooter, S as SiteFooterProps } from '../../site-footer-B67meCDv.js';
7
9
 
8
10
  declare function Avatar({ className, size, ...props }: React.ComponentProps<typeof Avatar$1.Root> & {
9
11
  size?: "default" | "sm" | "lg";
@@ -1,7 +1,5 @@
1
1
  "use client";
2
2
  import {
3
- Badge,
4
- Button,
5
3
  DropdownMenu,
6
4
  DropdownMenuCheckboxItem,
7
5
  DropdownMenuContent,
@@ -17,11 +15,25 @@ import {
17
15
  DropdownMenuSubContent,
18
16
  DropdownMenuSubTrigger,
19
17
  DropdownMenuTrigger,
18
+ SiteFooter
19
+ } from "../../chunk-QSTGUEEI.js";
20
+ import {
21
+ Badge,
22
+ Button,
23
+ Navigation,
24
+ Select,
25
+ SelectContent,
26
+ SelectGroup,
27
+ SelectItem,
28
+ SelectLabel,
29
+ SelectScrollDownButton,
30
+ SelectScrollUpButton,
31
+ SelectSeparator,
32
+ SelectTrigger,
33
+ SelectValue,
20
34
  badgeVariants,
21
- buttonVariants,
22
- useOverlayRef,
23
- useRadixHiddenInert
24
- } from "../../chunk-QKVN6Q6C.js";
35
+ buttonVariants
36
+ } from "../../chunk-CE73AEJZ.js";
25
37
  import {
26
38
  __objRest,
27
39
  __spreadProps,
@@ -435,198 +447,45 @@ var Toaster = (_a) => {
435
447
  );
436
448
  };
437
449
 
438
- // src/components/ui/select.tsx
439
- import { Select as Primitive } from "radix-ui";
440
- import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
441
- import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
442
- var Select = Primitive.Root;
443
- var SelectValue = Primitive.Value;
444
- var SelectGroup = Primitive.Group;
445
- function SelectTrigger(_a) {
446
- var _b = _a, {
447
- className,
448
- children
449
- } = _b, props = __objRest(_b, [
450
- "className",
451
- "children"
452
- ]);
453
- return /* @__PURE__ */ jsxs2(
454
- Primitive.Trigger,
455
- __spreadProps(__spreadValues({
456
- "data-slot": "select-trigger",
457
- className: cn(
458
- "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",
459
- className
460
- )
461
- }, props), {
462
- children: [
463
- children,
464
- /* @__PURE__ */ jsx6(Primitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx6(ChevronDownIcon, { className: "size-4 shrink-0" }) })
465
- ]
466
- })
467
- );
468
- }
469
- function SelectContent(_a) {
470
- var _b = _a, {
471
- ref,
472
- className,
473
- children,
474
- position = "popper",
475
- sideOffset = 6
476
- } = _b, props = __objRest(_b, [
477
- "ref",
478
- "className",
479
- "children",
480
- "position",
481
- "sideOffset"
482
- ]);
483
- const [content, contentRef] = useOverlayRef(ref);
484
- useRadixHiddenInert(content);
485
- return /* @__PURE__ */ jsx6(Primitive.Portal, { children: /* @__PURE__ */ jsxs2(
486
- Primitive.Content,
487
- __spreadProps(__spreadValues({
488
- ref: contentRef,
489
- "data-slot": "select-content",
490
- position,
491
- sideOffset,
492
- className: cn(
493
- "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",
494
- className
495
- )
496
- }, props), {
497
- children: [
498
- /* @__PURE__ */ jsx6(SelectScrollUpButton, {}),
499
- /* @__PURE__ */ jsx6(Primitive.Viewport, { className: "p-1", children }),
500
- /* @__PURE__ */ jsx6(SelectScrollDownButton, {})
501
- ]
502
- })
503
- ) });
504
- }
505
- function SelectItem(_a) {
506
- var _b = _a, {
507
- className,
508
- children
509
- } = _b, props = __objRest(_b, [
510
- "className",
511
- "children"
512
- ]);
513
- return /* @__PURE__ */ jsxs2(
514
- Primitive.Item,
515
- __spreadProps(__spreadValues({
516
- "data-slot": "select-item",
517
- className: cn(
518
- "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",
519
- className
520
- )
521
- }, props), {
522
- children: [
523
- /* @__PURE__ */ jsx6(Primitive.ItemText, { children }),
524
- /* @__PURE__ */ jsx6(Primitive.ItemIndicator, { className: "absolute right-3", children: /* @__PURE__ */ jsx6(CheckIcon, { className: "size-4" }) })
525
- ]
526
- })
527
- );
528
- }
529
- function SelectLabel(_a) {
530
- var _b = _a, {
531
- className
532
- } = _b, props = __objRest(_b, [
533
- "className"
534
- ]);
535
- return /* @__PURE__ */ jsx6(
536
- Primitive.Label,
537
- __spreadValues({
538
- "data-slot": "select-label",
539
- className: cn(
540
- "px-3 py-2 text-sm font-medium text-muted-foreground",
541
- className
542
- )
543
- }, props)
544
- );
545
- }
546
- function SelectSeparator(_a) {
547
- var _b = _a, {
548
- className
549
- } = _b, props = __objRest(_b, [
550
- "className"
551
- ]);
552
- return /* @__PURE__ */ jsx6(
553
- Primitive.Separator,
554
- __spreadValues({
555
- "data-slot": "select-separator",
556
- className: cn("my-1 h-px bg-border", className)
557
- }, props)
558
- );
559
- }
560
- function SelectScrollUpButton(_a) {
561
- var _b = _a, {
562
- className
563
- } = _b, props = __objRest(_b, [
564
- "className"
565
- ]);
566
- return /* @__PURE__ */ jsx6(
567
- Primitive.ScrollUpButton,
568
- __spreadProps(__spreadValues({
569
- className: cn("flex h-8 items-center justify-center", className)
570
- }, props), {
571
- children: /* @__PURE__ */ jsx6(ChevronUpIcon, { className: "size-4" })
572
- })
573
- );
574
- }
575
- function SelectScrollDownButton(_a) {
576
- var _b = _a, {
577
- className
578
- } = _b, props = __objRest(_b, [
579
- "className"
580
- ]);
581
- return /* @__PURE__ */ jsx6(
582
- Primitive.ScrollDownButton,
583
- __spreadProps(__spreadValues({
584
- className: cn("flex h-8 items-center justify-center", className)
585
- }, props), {
586
- children: /* @__PURE__ */ jsx6(ChevronDownIcon, { className: "size-4" })
587
- })
588
- );
589
- }
590
-
591
450
  // src/components/ui/switch.tsx
592
- import { Switch as Primitive2 } from "radix-ui";
593
- import { jsx as jsx7 } from "react/jsx-runtime";
451
+ import { Switch as Primitive } from "radix-ui";
452
+ import { jsx as jsx6 } from "react/jsx-runtime";
594
453
  function Switch(_a) {
595
454
  var _b = _a, {
596
455
  className
597
456
  } = _b, props = __objRest(_b, [
598
457
  "className"
599
458
  ]);
600
- return /* @__PURE__ */ jsx7(
601
- Primitive2.Root,
459
+ return /* @__PURE__ */ jsx6(
460
+ Primitive.Root,
602
461
  __spreadProps(__spreadValues({
603
462
  "data-slot": "switch",
604
463
  className: cn("ui-choice ui-focus", className)
605
464
  }, props), {
606
- children: /* @__PURE__ */ jsx7(Primitive2.Thumb, { "data-slot": "switch-thumb" })
465
+ children: /* @__PURE__ */ jsx6(Primitive.Thumb, { "data-slot": "switch-thumb" })
607
466
  })
608
467
  );
609
468
  }
610
469
 
611
470
  // src/components/ui/checkbox.tsx
612
- import { Checkbox as Primitive3 } from "radix-ui";
613
- import { CheckIcon as CheckIcon2, MinusIcon } from "lucide-react";
614
- import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
471
+ import { Checkbox as Primitive2 } from "radix-ui";
472
+ import { CheckIcon, MinusIcon } from "lucide-react";
473
+ import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
615
474
  function Checkbox(_a) {
616
475
  var _b = _a, {
617
476
  className
618
477
  } = _b, props = __objRest(_b, [
619
478
  "className"
620
479
  ]);
621
- return /* @__PURE__ */ jsx8(
622
- Primitive3.Root,
480
+ return /* @__PURE__ */ jsx7(
481
+ Primitive2.Root,
623
482
  __spreadProps(__spreadValues({
624
483
  "data-slot": "checkbox",
625
484
  className: cn("ui-choice ui-focus group/checkbox", className)
626
485
  }, props), {
627
- children: /* @__PURE__ */ jsxs3(Primitive3.Indicator, { className: "flex items-center justify-center", children: [
628
- /* @__PURE__ */ jsx8(CheckIcon2, { className: "size-3.5 group-data-[state=indeterminate]/checkbox:hidden" }),
629
- /* @__PURE__ */ jsx8(MinusIcon, { className: "hidden size-3.5 group-data-[state=indeterminate]/checkbox:block" })
486
+ children: /* @__PURE__ */ jsxs2(Primitive2.Indicator, { className: "flex items-center justify-center", children: [
487
+ /* @__PURE__ */ jsx7(CheckIcon, { className: "size-3.5 group-data-[state=indeterminate]/checkbox:hidden" }),
488
+ /* @__PURE__ */ jsx7(MinusIcon, { className: "hidden size-3.5 group-data-[state=indeterminate]/checkbox:block" })
630
489
  ] })
631
490
  })
632
491
  );
@@ -634,32 +493,32 @@ function Checkbox(_a) {
634
493
 
635
494
  // src/components/ui/tabs.tsx
636
495
  import { Tabs as TabsPrimitive } from "radix-ui";
637
- import { jsx as jsx9 } from "react/jsx-runtime";
496
+ import { jsx as jsx8 } from "react/jsx-runtime";
638
497
  function Tabs(_a) {
639
498
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
640
- return /* @__PURE__ */ jsx9(TabsPrimitive.Root, __spreadValues({ "data-slot": "tabs", className: cn("ui-tabs min-w-0", className) }, props));
499
+ return /* @__PURE__ */ jsx8(TabsPrimitive.Root, __spreadValues({ "data-slot": "tabs", className: cn("ui-tabs min-w-0", className) }, props));
641
500
  }
642
501
  function TabsList(_a) {
643
502
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
644
- return /* @__PURE__ */ jsx9(TabsPrimitive.List, __spreadValues({ "data-slot": "tabs-list", className: cn("ui-tabs-list", className) }, props));
503
+ return /* @__PURE__ */ jsx8(TabsPrimitive.List, __spreadValues({ "data-slot": "tabs-list", className: cn("ui-tabs-list", className) }, props));
645
504
  }
646
505
  function TabsTrigger(_a) {
647
506
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
648
- return /* @__PURE__ */ jsx9(TabsPrimitive.Trigger, __spreadValues({ "data-slot": "tabs-trigger", className: cn(
507
+ return /* @__PURE__ */ jsx8(TabsPrimitive.Trigger, __spreadValues({ "data-slot": "tabs-trigger", className: cn(
649
508
  "ui-tabs-trigger ui-control ui-focus h-auto min-h-(--ui-control-height) w-max max-w-full shrink-0 whitespace-normal break-words rounded-md border-b-2 px-3 text-base leading-normal font-medium disabled:cursor-not-allowed disabled:opacity-50",
650
509
  className
651
510
  ) }, props));
652
511
  }
653
512
  function TabsContent(_a) {
654
513
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
655
- return /* @__PURE__ */ jsx9(TabsPrimitive.Content, __spreadValues({ "data-slot": "tabs-content", className: cn("ui-focus min-w-0 break-words", className) }, props));
514
+ return /* @__PURE__ */ jsx8(TabsPrimitive.Content, __spreadValues({ "data-slot": "tabs-content", className: cn("ui-focus min-w-0 break-words", className) }, props));
656
515
  }
657
516
 
658
517
  // src/components/ui/textarea.tsx
659
- import { jsx as jsx10 } from "react/jsx-runtime";
518
+ import { jsx as jsx9 } from "react/jsx-runtime";
660
519
  function Textarea(_a) {
661
520
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
662
- return /* @__PURE__ */ jsx10(
521
+ return /* @__PURE__ */ jsx9(
663
522
  "textarea",
664
523
  __spreadValues({
665
524
  "data-slot": "textarea",
@@ -714,6 +573,7 @@ export {
714
573
  DropdownMenuSubTrigger,
715
574
  DropdownMenuTrigger,
716
575
  Input,
576
+ Navigation,
717
577
  Select,
718
578
  SelectContent,
719
579
  SelectGroup,
@@ -724,6 +584,7 @@ export {
724
584
  SelectSeparator,
725
585
  SelectTrigger,
726
586
  SelectValue,
587
+ SiteFooter,
727
588
  Switch,
728
589
  Tabs,
729
590
  TabsContent,
@@ -0,0 +1,48 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+
4
+ type NavigationLinkProps = React.ComponentPropsWithoutRef<"a"> & {
5
+ href: string;
6
+ };
7
+ type NavigationLinkComponent = React.ComponentType<NavigationLinkProps>;
8
+ interface NavigationLink {
9
+ id: string;
10
+ label: string;
11
+ href: string;
12
+ description?: string;
13
+ icon?: React.ReactNode;
14
+ badge?: React.ReactNode;
15
+ external?: boolean;
16
+ target?: React.HTMLAttributeAnchorTarget;
17
+ active?: boolean;
18
+ }
19
+ interface NavigationGroup {
20
+ id: string;
21
+ label: string;
22
+ items: NavigationLink[];
23
+ /** Desktop menu layout; the mobile sheet always uses one column. */
24
+ columns?: 1 | 2;
25
+ }
26
+ type NavigationItem = NavigationLink | NavigationGroup;
27
+ interface NavigationProps extends Omit<React.ComponentPropsWithoutRef<"header">, "children" | "onSelect"> {
28
+ brand: React.ReactNode;
29
+ items: NavigationItem[];
30
+ /** Translated landmark/dialog/close labels are supplied by the application. */
31
+ labels: {
32
+ navigation: string;
33
+ menu: string;
34
+ close: string;
35
+ };
36
+ Link?: NavigationLinkComponent;
37
+ currentHref?: string;
38
+ toolbar?: React.ReactNode;
39
+ mobileToolbar?: React.ReactNode;
40
+ mobileFooter?: React.ReactNode;
41
+ /** Use the same product-owned frame class on header, footer and main. */
42
+ containerClassName?: string;
43
+ /** Preserve modified clicks; applications may preventDefault for client routing/guards. */
44
+ onNavigate?: (event: React.MouseEvent<HTMLAnchorElement>, item: NavigationLink) => void;
45
+ }
46
+ declare function Navigation({ brand, items, labels, Link, currentHref, toolbar, mobileToolbar, mobileFooter, containerClassName, onNavigate, className, ...props }: NavigationProps): react_jsx_runtime.JSX.Element;
47
+
48
+ export { type NavigationLink as N, type NavigationProps as a, type NavigationLinkProps as b, type NavigationLinkComponent as c, Navigation as d, type NavigationGroup as e, type NavigationItem as f };
@@ -0,0 +1,21 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { N as NavigationLink, c as NavigationLinkComponent } from './navigation-CL10a6Eb.js';
4
+
5
+ interface SiteFooterProps extends React.ComponentPropsWithoutRef<"footer"> {
6
+ brand?: React.ReactNode;
7
+ description?: React.ReactNode;
8
+ groups?: Array<{
9
+ id: string;
10
+ label: string;
11
+ links: NavigationLink[];
12
+ }>;
13
+ Link?: NavigationLinkComponent;
14
+ meta?: React.ReactNode;
15
+ containerClassName?: string;
16
+ variant?: "full" | "compact";
17
+ }
18
+ /** Product content and translations belong to the consumer, including legal copy. */
19
+ declare function SiteFooter({ brand, description, groups, Link, meta, children, containerClassName, className, variant, ...props }: SiteFooterProps): react_jsx_runtime.JSX.Element;
20
+
21
+ export { type SiteFooterProps as S, SiteFooter as a };
@@ -1,15 +1,24 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { SiteFooterProps } from './ui/site-footer.js';
3
+ import 'react';
4
+ import './ui/navigation.js';
2
5
 
3
6
  interface FooterProps {
4
- /** Link component from consumer */
5
7
  Link?: React.ComponentType<{
6
8
  href: string;
7
9
  children: React.ReactNode;
8
10
  className?: string;
9
11
  }>;
10
- /** Whether links go to naeil.dev (external) or are internal. Default: false */
11
12
  linksExternal?: boolean;
13
+ brandSlot?: React.ReactNode;
14
+ description?: React.ReactNode;
15
+ groups?: SiteFooterProps["groups"];
16
+ socialSlot?: React.ReactNode;
17
+ meta?: React.ReactNode;
18
+ variant?: SiteFooterProps["variant"];
19
+ className?: string;
20
+ containerClassName?: string;
12
21
  }
13
- declare function Footer({ Link, linksExternal }: FooterProps): react_jsx_runtime.JSX.Element;
22
+ declare function Footer({ Link, linksExternal, brandSlot, description, groups, socialSlot, meta, variant, className, containerClassName, }: FooterProps): react_jsx_runtime.JSX.Element;
14
23
 
15
- export { Footer };
24
+ export { Footer, type FooterProps };
@@ -1,45 +1,86 @@
1
1
  "use client";
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
20
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
2
21
  import { jsx, jsxs } from "react/jsx-runtime";
3
22
  import { useTranslations } from "next-intl";
4
23
  import { Logo } from "./logo.js";
5
- function NavLink({
6
- href,
7
- children,
24
+ import { SiteFooter } from "./ui/site-footer.js";
25
+ function Footer({
26
+ Link,
27
+ linksExternal = false,
28
+ brandSlot,
29
+ description,
30
+ groups,
31
+ socialSlot,
32
+ meta,
33
+ variant,
8
34
  className,
9
- linksExternal,
10
- Link
35
+ containerClassName
11
36
  }) {
12
- if (linksExternal) {
13
- return /* @__PURE__ */ jsx(
14
- "a",
15
- {
16
- href: `https://naeil.dev${href}`,
17
- target: "_blank",
18
- rel: "noopener noreferrer",
19
- className,
20
- children
21
- }
22
- );
23
- }
24
- if (Link) {
25
- return /* @__PURE__ */ jsx(Link, { href, className, children });
26
- }
27
- return /* @__PURE__ */ jsx("a", { href, className, children });
28
- }
29
- function Footer({ Link, linksExternal = false }) {
30
37
  const t = useTranslations("footer");
31
- return /* @__PURE__ */ jsx("footer", { className: "border-border/40 border-t", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto flex max-w-7xl flex-col gap-10 px-6 py-16 sm:flex-row sm:justify-between", children: [
32
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
33
- /* @__PURE__ */ jsx(Logo, { variant: "footer", size: 20, className: "block" }),
34
- /* @__PURE__ */ jsx("p", { className: "text-muted-foreground max-w-[240px] text-sm leading-relaxed", children: t("tagline") }),
35
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
38
+ const destinations = [
39
+ { id: "projects", label: t("projects"), href: "/projects" },
40
+ { id: "blog", label: t("blog"), href: "/blog" }
41
+ ];
42
+ return /* @__PURE__ */ jsx(
43
+ SiteFooter,
44
+ {
45
+ Link,
46
+ className,
47
+ containerClassName,
48
+ variant,
49
+ brand: brandSlot != null ? brandSlot : /* @__PURE__ */ jsx(Logo, { variant: "footer", size: 20, className: "block" }),
50
+ description: description === void 0 ? t("tagline") : description,
51
+ groups: groups != null ? groups : [
52
+ {
53
+ id: "navigation",
54
+ label: t("navigation"),
55
+ links: destinations.map((item) => __spreadProps(__spreadValues({}, item), {
56
+ href: linksExternal ? `https://naeil.dev${item.href}` : item.href,
57
+ external: linksExternal,
58
+ target: linksExternal ? "_blank" : void 0
59
+ }))
60
+ },
61
+ {
62
+ id: "social",
63
+ label: t("social"),
64
+ links: [
65
+ {
66
+ id: "github",
67
+ label: "GitHub",
68
+ href: "https://github.com/naeil-dev",
69
+ external: true,
70
+ target: "_blank"
71
+ }
72
+ ]
73
+ }
74
+ ],
75
+ meta,
76
+ children: socialSlot === void 0 ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
36
77
  /* @__PURE__ */ jsx(
37
78
  "a",
38
79
  {
39
80
  href: "https://github.com/naeil-dev",
40
81
  target: "_blank",
41
82
  rel: "noopener noreferrer",
42
- className: "text-muted-foreground hover:text-foreground transition-colors",
83
+ className: "ui-navigation-link ui-focus",
43
84
  "aria-label": "GitHub",
44
85
  children: /* @__PURE__ */ jsx(GitHubIcon, {})
45
86
  }
@@ -50,52 +91,14 @@ function Footer({ Link, linksExternal = false }) {
50
91
  href: "https://x.com",
51
92
  target: "_blank",
52
93
  rel: "noopener noreferrer",
53
- className: "text-muted-foreground hover:text-foreground transition-colors",
94
+ className: "ui-navigation-link ui-focus",
54
95
  "aria-label": "X",
55
96
  children: /* @__PURE__ */ jsx(XIcon, {})
56
97
  }
57
98
  )
58
- ] })
59
- ] }),
60
- /* @__PURE__ */ jsxs("div", { className: "flex gap-10 sm:gap-16", children: [
61
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
62
- /* @__PURE__ */ jsx("span", { className: "text-foreground text-xs font-medium uppercase tracking-wider", children: t("navigation") }),
63
- /* @__PURE__ */ jsx(
64
- NavLink,
65
- {
66
- href: "/projects",
67
- className: "text-muted-foreground hover:text-foreground text-sm transition-colors",
68
- linksExternal,
69
- Link,
70
- children: t("projects")
71
- }
72
- ),
73
- /* @__PURE__ */ jsx(
74
- NavLink,
75
- {
76
- href: "/blog",
77
- className: "text-muted-foreground hover:text-foreground text-sm transition-colors",
78
- linksExternal,
79
- Link,
80
- children: t("blog")
81
- }
82
- )
83
- ] }),
84
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
85
- /* @__PURE__ */ jsx("span", { className: "text-foreground text-xs font-medium uppercase tracking-wider", children: t("social") }),
86
- /* @__PURE__ */ jsx(
87
- "a",
88
- {
89
- href: "https://github.com/naeil-dev",
90
- target: "_blank",
91
- rel: "noopener noreferrer",
92
- className: "text-muted-foreground hover:text-foreground text-sm transition-colors",
93
- children: "GitHub \u2197"
94
- }
95
- )
96
- ] })
97
- ] })
98
- ] }) });
99
+ ] }) : socialSlot
100
+ }
101
+ );
99
102
  }
100
103
  function GitHubIcon() {
101
104
  return /* @__PURE__ */ jsx(
@@ -1,5 +1,5 @@
1
- export { Nav } from './nav.js';
2
- export { Footer } from './footer.js';
1
+ export { Nav, NavProps } from './nav.js';
2
+ export { Footer, FooterProps } from './footer.js';
3
3
  export { LocaleSwitcher } from './locale-switcher.js';
4
4
  export { ThemeToggle } from './theme-toggle.js';
5
5
  export { ThemeProvider } from './theme-provider.js';
@@ -7,5 +7,7 @@ export { ThemeToggleIcon } from './theme-toggle-icon.js';
7
7
  export { Logo, LogoProps } from './logo.js';
8
8
  export { PageTitle, SectionTitle, pageTitleClass, sectionTitleClass } from './typography.js';
9
9
  import 'react/jsx-runtime';
10
- import 'next-themes';
10
+ import './ui/navigation.js';
11
11
  import 'react';
12
+ import './ui/site-footer.js';
13
+ import 'next-themes';