@naeil/ui 0.2.0 → 0.3.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 (106) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/DESIGN.md +186 -0
  3. package/LICENSE +21 -0
  4. package/README.md +77 -53
  5. package/THIRD_PARTY_NOTICES.md +49 -0
  6. package/dist/{chunk-SYI3IKIC.js → chunk-QKVN6Q6C.js} +102 -19
  7. package/dist/components/index.d.ts +2 -2
  8. package/dist/components/index.js +9 -9
  9. package/dist/components/ui/index.d.ts +26 -4
  10. package/dist/components/ui/index.js +288 -33
  11. package/dist/source/components/footer.d.ts +15 -0
  12. package/dist/source/components/footer.js +172 -0
  13. package/dist/source/components/index.d.ts +11 -0
  14. package/dist/source/components/index.js +26 -0
  15. package/dist/source/components/locale-switcher.d.ts +17 -0
  16. package/dist/source/components/locale-switcher.js +66 -0
  17. package/dist/source/components/logo.d.ts +9 -0
  18. package/dist/source/components/logo.js +52 -0
  19. package/dist/source/components/nav.d.ts +39 -0
  20. package/dist/source/components/nav.js +412 -0
  21. package/dist/source/components/theme-provider.d.ts +6 -0
  22. package/dist/source/components/theme-provider.js +45 -0
  23. package/dist/source/components/theme-toggle-icon.d.ts +5 -0
  24. package/dist/source/components/theme-toggle-icon.js +62 -0
  25. package/dist/source/components/theme-toggle.d.ts +5 -0
  26. package/dist/source/components/theme-toggle.js +34 -0
  27. package/dist/source/components/typography.d.ts +12 -0
  28. package/dist/source/components/typography.js +49 -0
  29. package/dist/source/components/ui/avatar.d.ts +14 -0
  30. package/dist/source/components/ui/avatar.js +137 -0
  31. package/dist/source/components/ui/badge.d.ts +13 -0
  32. package/dist/source/components/ui/badge.js +76 -0
  33. package/dist/source/components/ui/button.d.ts +14 -0
  34. package/dist/source/components/ui/button.js +88 -0
  35. package/dist/source/components/ui/card.d.ts +13 -0
  36. package/dist/source/components/ui/card.js +135 -0
  37. package/dist/source/components/ui/checkbox.d.ts +7 -0
  38. package/dist/source/components/ui/checkbox.js +58 -0
  39. package/dist/source/components/ui/dialog.d.ts +20 -0
  40. package/dist/source/components/ui/dialog.js +182 -0
  41. package/dist/source/components/ui/dropdown-menu.d.ts +28 -0
  42. package/dist/source/components/ui/dropdown-menu.js +282 -0
  43. package/dist/source/components/ui/index.d.ts +19 -0
  44. package/dist/source/components/ui/index.js +131 -0
  45. package/dist/source/components/ui/input.d.ts +6 -0
  46. package/dist/source/components/ui/input.js +49 -0
  47. package/dist/source/components/ui/select.d.ts +16 -0
  48. package/dist/source/components/ui/select.js +197 -0
  49. package/dist/source/components/ui/sonner.d.ts +6 -0
  50. package/dist/source/components/ui/sonner.js +80 -0
  51. package/dist/source/components/ui/switch.d.ts +7 -0
  52. package/dist/source/components/ui/switch.js +54 -0
  53. package/dist/source/components/ui/tabs.d.ts +10 -0
  54. package/dist/source/components/ui/tabs.js +57 -0
  55. package/dist/source/components/ui/textarea.d.ts +6 -0
  56. package/dist/source/components/ui/textarea.js +46 -0
  57. package/dist/source/i18n/config.d.ts +6 -0
  58. package/dist/source/i18n/config.js +12 -0
  59. package/dist/source/i18n/routing.d.ts +371 -0
  60. package/dist/source/i18n/routing.js +17 -0
  61. package/dist/source/lib/design/modal-inert.d.ts +6 -0
  62. package/dist/source/lib/design/modal-inert.js +73 -0
  63. package/dist/source/lib/utils.d.ts +5 -0
  64. package/dist/source/lib/utils.js +8 -0
  65. package/dist/tokens.ts +217 -0
  66. package/docs/components/README.md +21 -0
  67. package/docs/components/avatar.md +47 -0
  68. package/docs/components/badge.md +29 -0
  69. package/docs/components/button.md +39 -0
  70. package/docs/components/card.md +32 -0
  71. package/docs/components/checkbox.md +35 -0
  72. package/docs/components/common.md +31 -0
  73. package/docs/components/composition.md +68 -0
  74. package/docs/components/dialog.md +41 -0
  75. package/docs/components/dropdown-menu.md +38 -0
  76. package/docs/components/input.md +32 -0
  77. package/docs/components/select.md +39 -0
  78. package/docs/components/sonner.md +37 -0
  79. package/docs/components/switch.md +33 -0
  80. package/docs/components/tabs.md +40 -0
  81. package/docs/components/textarea.md +35 -0
  82. package/docs/design/component-demand.md +30 -0
  83. package/docs/design/public-ui-final-verification.md +96 -0
  84. package/docs/design/public-ui-release-validation.md +86 -0
  85. package/docs/design/public-ui-stage3-verification.md +98 -0
  86. package/docs/design/public-ui-stage4-verification.md +129 -0
  87. package/docs/design/public-ui-support.md +40 -0
  88. package/docs/design/v2-migration.md +199 -0
  89. package/docs/package-release.md +89 -0
  90. package/licenses/Noto-Sans-JP-OFL.txt +93 -0
  91. package/licenses/Nunito-Sans-OFL.txt +93 -0
  92. package/licenses/Pretendard-OFL.txt +94 -0
  93. package/licenses/React-MIT.txt +21 -0
  94. package/licenses/Storybook-MIT.txt +21 -0
  95. package/licenses/popper-MIT.txt +25 -0
  96. package/licenses/react-remove-scroll-bar-MIT.txt +21 -0
  97. package/licenses/store2-MIT.txt +22 -0
  98. package/licenses/toggle-selection-MIT.txt +21 -0
  99. package/package.json +182 -34
  100. package/src/styles/components.css +276 -0
  101. package/src/styles/globals.css +18 -0
  102. package/src/styles/theme.css +185 -98
  103. package/messages/en.json +0 -221
  104. package/messages/ja.json +0 -221
  105. package/messages/ko.json +0 -221
  106. package/src/app/globals.css +0 -32
@@ -18,8 +18,10 @@ import {
18
18
  DropdownMenuSubTrigger,
19
19
  DropdownMenuTrigger,
20
20
  badgeVariants,
21
- buttonVariants
22
- } from "../../chunk-SYI3IKIC.js";
21
+ buttonVariants,
22
+ useOverlayRef,
23
+ useRadixHiddenInert
24
+ } from "../../chunk-QKVN6Q6C.js";
23
25
  import {
24
26
  __objRest,
25
27
  __spreadProps,
@@ -44,7 +46,7 @@ function Avatar(_a) {
44
46
  "data-slot": "avatar",
45
47
  "data-size": size,
46
48
  className: cn(
47
- "group/avatar relative flex size-8 shrink-0 overflow-hidden rounded-full select-none data-[size=lg]:size-10 data-[size=sm]:size-6 focus-visible:ring-accent/25 focus-visible:ring-[2px] focus-visible:outline-none",
49
+ "group/avatar relative flex size-8 shrink-0 overflow-hidden rounded-full select-none data-[size=lg]:size-10 data-[size=sm]:size-6 ui-focus",
48
50
  className
49
51
  )
50
52
  }, props)
@@ -75,7 +77,7 @@ function AvatarFallback(_a) {
75
77
  __spreadValues({
76
78
  "data-slot": "avatar-fallback",
77
79
  className: cn(
78
- "bg-accent/15 text-accent flex size-full items-center justify-center rounded-full font-medium text-xs group-data-[size=sm]/avatar:text-[10px]",
80
+ "bg-secondary text-secondary-foreground flex size-full items-center justify-center rounded-full font-medium text-xs group-data-[size=sm]/avatar:text-xs",
79
81
  className
80
82
  )
81
83
  }, props)
@@ -137,7 +139,7 @@ function Card(_a) {
137
139
  __spreadValues({
138
140
  "data-slot": "card",
139
141
  className: cn(
140
- "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border border-border-subtle py-6 transition-colors duration-150",
142
+ "bg-card text-card-foreground flex flex-col rounded-xl border border-border-subtle transition-colors duration-(--ui-motion-fast)",
141
143
  className
142
144
  )
143
145
  }, props)
@@ -150,7 +152,7 @@ function CardElevated(_a) {
150
152
  __spreadValues({
151
153
  "data-slot": "card",
152
154
  className: cn(
153
- "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border border-border-subtle py-6 shadow-sm dark:bg-card-elevated transition-colors duration-150",
155
+ "bg-card text-card-foreground flex flex-col rounded-xl border border-border-subtle shadow-sm dark:bg-card-elevated transition-colors duration-(--ui-motion-fast)",
154
156
  className
155
157
  )
156
158
  }, props)
@@ -163,7 +165,7 @@ function CardHeader(_a) {
163
165
  __spreadValues({
164
166
  "data-slot": "card-header",
165
167
  className: cn(
166
- "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
168
+ "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-(--ui-panel-padding) has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-(--ui-panel-padding)",
167
169
  className
168
170
  )
169
171
  }, props)
@@ -208,7 +210,7 @@ function CardContent(_a) {
208
210
  "div",
209
211
  __spreadValues({
210
212
  "data-slot": "card-content",
211
- className: cn("px-6", className)
213
+ className: cn("px-(--ui-panel-padding)", className)
212
214
  }, props)
213
215
  );
214
216
  }
@@ -218,7 +220,10 @@ function CardFooter(_a) {
218
220
  "div",
219
221
  __spreadValues({
220
222
  "data-slot": "card-footer",
221
- className: cn("flex items-center px-6 [.border-t]:pt-6", className)
223
+ className: cn(
224
+ "flex items-center px-(--ui-panel-padding) [.border-t]:pt-(--ui-panel-padding)",
225
+ className
226
+ )
222
227
  }, props)
223
228
  );
224
229
  }
@@ -253,10 +258,7 @@ function DialogOverlay(_a) {
253
258
  DialogPrimitive.Overlay,
254
259
  __spreadValues({
255
260
  "data-slot": "dialog-overlay",
256
- className: cn(
257
- "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/60 backdrop-blur-sm",
258
- className
259
- )
261
+ className: cn("ui-popup fixed inset-0 z-50 bg-black/60 ", className)
260
262
  }, props)
261
263
  );
262
264
  }
@@ -277,7 +279,7 @@ function DialogContent(_a) {
277
279
  __spreadProps(__spreadValues({
278
280
  "data-slot": "dialog-content",
279
281
  className: cn(
280
- "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=open]:duration-200 data-[state=closed]:duration-150 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-xl border border-border-subtle p-6 outline-none sm:max-w-lg",
282
+ "bg-popover ui-popup fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-xl border border-border-strong p-6 sm:max-w-lg",
281
283
  className
282
284
  )
283
285
  }, props), {
@@ -287,7 +289,7 @@ function DialogContent(_a) {
287
289
  DialogPrimitive.Close,
288
290
  {
289
291
  "data-slot": "dialog-close",
290
- className: "absolute top-4 right-4 rounded-sm text-muted-foreground hover:text-foreground transition-colors focus-visible:ring-accent/25 focus-visible:ring-[2px] focus-visible:outline-none disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
292
+ className: "ui-focus absolute top-2 right-2 flex size-10 items-center justify-center rounded-sm text-muted-foreground hover:text-foreground transition-colors ui-focus disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
291
293
  children: [
292
294
  /* @__PURE__ */ jsx3(XIcon, {}),
293
295
  /* @__PURE__ */ jsx3("span", { className: "sr-only", children: "Close" })
@@ -345,7 +347,7 @@ function DialogTitle(_a) {
345
347
  DialogPrimitive.Title,
346
348
  __spreadValues({
347
349
  "data-slot": "dialog-title",
348
- className: cn("text-lg leading-none font-semibold", className)
350
+ className: cn("text-xl leading-normal font-semibold", className)
349
351
  }, props)
350
352
  );
351
353
  }
@@ -374,9 +376,9 @@ function Input(_a) {
374
376
  type,
375
377
  "data-slot": "input",
376
378
  className: cn(
377
- "file:text-foreground placeholder:text-muted-foreground/60 selection:bg-primary selection:text-primary-foreground dark:bg-surface-subtle border-border-subtle h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base transition-colors duration-150 outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
378
- "focus-visible:border-accent focus-visible:ring-accent/25 focus-visible:ring-[2px]",
379
- "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
379
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground ui-control ui-focus border-input w-full min-w-0 rounded-md border bg-background px-3 py-1 text-base transition-colors duration-(--ui-motion-fast) file:inline-flex file:h-7 file:border-0 file:bg-background file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 ",
380
+ "ui-focus",
381
+ "aria-invalid:border-error",
380
382
  className
381
383
  )
382
384
  }, props)
@@ -412,26 +414,262 @@ var Toaster = (_a) => {
412
414
  loading: /* @__PURE__ */ jsx5(Loader2Icon, { className: "size-4 animate-spin" })
413
415
  },
414
416
  style: {
415
- "--normal-bg": "var(--card)",
417
+ "--normal-bg": "var(--popover)",
416
418
  "--normal-text": "var(--card-foreground)",
417
- "--normal-border": "var(--border-subtle)",
418
- "--success-bg": "var(--card)",
419
- "--success-text": "var(--card-foreground)",
420
- "--success-border": "var(--border-subtle)",
421
- "--error-bg": "var(--card)",
422
- "--error-text": "var(--destructive)",
423
- "--error-border": "var(--border-subtle)",
424
- "--info-bg": "var(--card)",
425
- "--info-text": "var(--card-foreground)",
426
- "--info-border": "var(--border-subtle)",
427
- "--warning-bg": "var(--card)",
428
- "--warning-text": "var(--card-foreground)",
429
- "--warning-border": "var(--border-subtle)",
419
+ "--normal-border": "var(--border-strong)",
420
+ "--success-bg": "var(--popover)",
421
+ "--success-text": "var(--success)",
422
+ "--success-border": "var(--border-strong)",
423
+ "--error-bg": "var(--popover)",
424
+ "--error-text": "var(--error)",
425
+ "--error-border": "var(--border-strong)",
426
+ "--info-bg": "var(--popover)",
427
+ "--info-text": "var(--info)",
428
+ "--info-border": "var(--border-strong)",
429
+ "--warning-bg": "var(--popover)",
430
+ "--warning-text": "var(--warning)",
431
+ "--warning-border": "var(--border-strong)",
430
432
  "--border-radius": "var(--radius-md-value)"
431
433
  }
432
434
  }, props)
433
435
  );
434
436
  };
437
+
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
+ // src/components/ui/switch.tsx
592
+ import { Switch as Primitive2 } from "radix-ui";
593
+ import { jsx as jsx7 } from "react/jsx-runtime";
594
+ function Switch(_a) {
595
+ var _b = _a, {
596
+ className
597
+ } = _b, props = __objRest(_b, [
598
+ "className"
599
+ ]);
600
+ return /* @__PURE__ */ jsx7(
601
+ Primitive2.Root,
602
+ __spreadProps(__spreadValues({
603
+ "data-slot": "switch",
604
+ className: cn("ui-choice ui-focus", className)
605
+ }, props), {
606
+ children: /* @__PURE__ */ jsx7(Primitive2.Thumb, { "data-slot": "switch-thumb" })
607
+ })
608
+ );
609
+ }
610
+
611
+ // 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";
615
+ function Checkbox(_a) {
616
+ var _b = _a, {
617
+ className
618
+ } = _b, props = __objRest(_b, [
619
+ "className"
620
+ ]);
621
+ return /* @__PURE__ */ jsx8(
622
+ Primitive3.Root,
623
+ __spreadProps(__spreadValues({
624
+ "data-slot": "checkbox",
625
+ className: cn("ui-choice ui-focus group/checkbox", className)
626
+ }, 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" })
630
+ ] })
631
+ })
632
+ );
633
+ }
634
+
635
+ // src/components/ui/tabs.tsx
636
+ import { Tabs as TabsPrimitive } from "radix-ui";
637
+ import { jsx as jsx9 } from "react/jsx-runtime";
638
+ function Tabs(_a) {
639
+ 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));
641
+ }
642
+ function TabsList(_a) {
643
+ 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));
645
+ }
646
+ function TabsTrigger(_a) {
647
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
648
+ return /* @__PURE__ */ jsx9(TabsPrimitive.Trigger, __spreadValues({ "data-slot": "tabs-trigger", className: cn(
649
+ "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
+ className
651
+ ) }, props));
652
+ }
653
+ function TabsContent(_a) {
654
+ 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));
656
+ }
657
+
658
+ // src/components/ui/textarea.tsx
659
+ import { jsx as jsx10 } from "react/jsx-runtime";
660
+ function Textarea(_a) {
661
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
662
+ return /* @__PURE__ */ jsx10(
663
+ "textarea",
664
+ __spreadValues({
665
+ "data-slot": "textarea",
666
+ className: cn(
667
+ "ui-textarea ui-focus w-full min-w-0 resize-y rounded-md border border-input bg-background px-3 py-2 text-base leading-normal placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-error",
668
+ className
669
+ )
670
+ }, props)
671
+ );
672
+ }
435
673
  export {
436
674
  Avatar,
437
675
  AvatarBadge,
@@ -449,6 +687,7 @@ export {
449
687
  CardFooter,
450
688
  CardHeader,
451
689
  CardTitle,
690
+ Checkbox,
452
691
  Dialog,
453
692
  DialogClose,
454
693
  DialogContent,
@@ -475,6 +714,22 @@ export {
475
714
  DropdownMenuSubTrigger,
476
715
  DropdownMenuTrigger,
477
716
  Input,
717
+ Select,
718
+ SelectContent,
719
+ SelectGroup,
720
+ SelectItem,
721
+ SelectLabel,
722
+ SelectScrollDownButton,
723
+ SelectScrollUpButton,
724
+ SelectSeparator,
725
+ SelectTrigger,
726
+ SelectValue,
727
+ Switch,
728
+ Tabs,
729
+ TabsContent,
730
+ TabsList,
731
+ TabsTrigger,
732
+ Textarea,
478
733
  Toaster,
479
734
  badgeVariants,
480
735
  buttonVariants
@@ -0,0 +1,15 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface FooterProps {
4
+ /** Link component from consumer */
5
+ Link?: React.ComponentType<{
6
+ href: string;
7
+ children: React.ReactNode;
8
+ className?: string;
9
+ }>;
10
+ /** Whether links go to naeil.dev (external) or are internal. Default: false */
11
+ linksExternal?: boolean;
12
+ }
13
+ declare function Footer({ Link, linksExternal }: FooterProps): react_jsx_runtime.JSX.Element;
14
+
15
+ export { Footer };
@@ -0,0 +1,172 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useTranslations } from "next-intl";
4
+ function NavLink({
5
+ href,
6
+ children,
7
+ className,
8
+ linksExternal,
9
+ Link
10
+ }) {
11
+ if (linksExternal) {
12
+ return /* @__PURE__ */ jsx(
13
+ "a",
14
+ {
15
+ href: `https://naeil.dev${href}`,
16
+ target: "_blank",
17
+ rel: "noopener noreferrer",
18
+ className,
19
+ children
20
+ }
21
+ );
22
+ }
23
+ if (Link) {
24
+ return /* @__PURE__ */ jsx(Link, { href, className, children });
25
+ }
26
+ return /* @__PURE__ */ jsx("a", { href, className, children });
27
+ }
28
+ function Footer({ Link, linksExternal = false }) {
29
+ const t = useTranslations("footer");
30
+ 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: [
31
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
32
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
33
+ /* @__PURE__ */ jsx(Logo, { size: 20 }),
34
+ /* @__PURE__ */ jsx("span", { className: "text-foreground text-sm font-semibold tracking-tight", children: ".naeil" })
35
+ ] }),
36
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground max-w-[240px] text-sm leading-relaxed", children: t("tagline") }),
37
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
38
+ /* @__PURE__ */ jsx(
39
+ "a",
40
+ {
41
+ href: "https://github.com/naeil-dev",
42
+ target: "_blank",
43
+ rel: "noopener noreferrer",
44
+ className: "text-muted-foreground hover:text-foreground transition-colors",
45
+ "aria-label": "GitHub",
46
+ children: /* @__PURE__ */ jsx(GitHubIcon, {})
47
+ }
48
+ ),
49
+ /* @__PURE__ */ jsx(
50
+ "a",
51
+ {
52
+ href: "https://x.com",
53
+ target: "_blank",
54
+ rel: "noopener noreferrer",
55
+ className: "text-muted-foreground hover:text-foreground transition-colors",
56
+ "aria-label": "X",
57
+ children: /* @__PURE__ */ jsx(XIcon, {})
58
+ }
59
+ )
60
+ ] })
61
+ ] }),
62
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-10 sm:gap-16", children: [
63
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
64
+ /* @__PURE__ */ jsx("span", { className: "text-foreground text-xs font-medium uppercase tracking-wider", children: t("navigation") }),
65
+ /* @__PURE__ */ jsx(
66
+ NavLink,
67
+ {
68
+ href: "/projects",
69
+ className: "text-muted-foreground hover:text-foreground text-sm transition-colors",
70
+ linksExternal,
71
+ Link,
72
+ children: t("projects")
73
+ }
74
+ ),
75
+ /* @__PURE__ */ jsx(
76
+ NavLink,
77
+ {
78
+ href: "/blog",
79
+ className: "text-muted-foreground hover:text-foreground text-sm transition-colors",
80
+ linksExternal,
81
+ Link,
82
+ children: t("blog")
83
+ }
84
+ )
85
+ ] }),
86
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
87
+ /* @__PURE__ */ jsx("span", { className: "text-foreground text-xs font-medium uppercase tracking-wider", children: t("social") }),
88
+ /* @__PURE__ */ jsx(
89
+ "a",
90
+ {
91
+ href: "https://github.com/naeil-dev",
92
+ target: "_blank",
93
+ rel: "noopener noreferrer",
94
+ className: "text-muted-foreground hover:text-foreground text-sm transition-colors",
95
+ children: "GitHub \u2197"
96
+ }
97
+ )
98
+ ] })
99
+ ] })
100
+ ] }) });
101
+ }
102
+ function Logo({ size = 20 }) {
103
+ const id = `naeil-footer-logo-${size}`;
104
+ return /* @__PURE__ */ jsxs(
105
+ "svg",
106
+ {
107
+ width: size,
108
+ height: size,
109
+ viewBox: "0 0 24 24",
110
+ fill: "none",
111
+ "aria-label": "naeil",
112
+ children: [
113
+ /* @__PURE__ */ jsx(
114
+ "path",
115
+ {
116
+ d: "M6 4 L6 16 L20 16",
117
+ stroke: "currentColor",
118
+ strokeWidth: "2",
119
+ strokeLinecap: "square",
120
+ strokeLinejoin: "miter"
121
+ }
122
+ ),
123
+ /* @__PURE__ */ jsx(
124
+ "circle",
125
+ {
126
+ cx: "15",
127
+ cy: "16",
128
+ r: "3.5",
129
+ fill: `url(#${id}-grad)`,
130
+ mask: `url(#${id})`
131
+ }
132
+ ),
133
+ /* @__PURE__ */ jsxs("defs", { children: [
134
+ /* @__PURE__ */ jsxs("linearGradient", { id: `${id}-grad`, x1: "15", y1: "12.5", x2: "15", y2: "16", children: [
135
+ /* @__PURE__ */ jsx("stop", { stopColor: "#eab308" }),
136
+ /* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#dc2626" })
137
+ ] }),
138
+ /* @__PURE__ */ jsx("mask", { id, children: /* @__PURE__ */ jsx("rect", { x: "0", y: "0", width: "24", height: "16", fill: "white" }) })
139
+ ] })
140
+ ]
141
+ }
142
+ );
143
+ }
144
+ function GitHubIcon() {
145
+ return /* @__PURE__ */ jsx(
146
+ "svg",
147
+ {
148
+ width: "16",
149
+ height: "16",
150
+ viewBox: "0 0 24 24",
151
+ fill: "currentColor",
152
+ "aria-hidden": "true",
153
+ children: /* @__PURE__ */ jsx("path", { d: "M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" })
154
+ }
155
+ );
156
+ }
157
+ function XIcon() {
158
+ return /* @__PURE__ */ jsx(
159
+ "svg",
160
+ {
161
+ width: "14",
162
+ height: "14",
163
+ viewBox: "0 0 24 24",
164
+ fill: "currentColor",
165
+ "aria-hidden": "true",
166
+ children: /* @__PURE__ */ jsx("path", { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" })
167
+ }
168
+ );
169
+ }
170
+ export {
171
+ Footer
172
+ };
@@ -0,0 +1,11 @@
1
+ export { Nav } from './nav.js';
2
+ export { Footer } from './footer.js';
3
+ export { LocaleSwitcher } from './locale-switcher.js';
4
+ export { ThemeToggle } from './theme-toggle.js';
5
+ export { ThemeProvider } from './theme-provider.js';
6
+ export { ThemeToggleIcon } from './theme-toggle-icon.js';
7
+ export { Logo } from './logo.js';
8
+ export { PageTitle, SectionTitle, pageTitleClass, sectionTitleClass } from './typography.js';
9
+ import 'react/jsx-runtime';
10
+ import 'next-themes';
11
+ import 'react';
@@ -0,0 +1,26 @@
1
+ import { Nav } from "./nav.js";
2
+ import { Footer } from "./footer.js";
3
+ import { LocaleSwitcher } from "./locale-switcher.js";
4
+ import { ThemeToggle } from "./theme-toggle.js";
5
+ import { ThemeProvider } from "./theme-provider.js";
6
+ import { ThemeToggleIcon } from "./theme-toggle-icon.js";
7
+ import { Logo } from "./logo.js";
8
+ import {
9
+ PageTitle,
10
+ SectionTitle,
11
+ pageTitleClass,
12
+ sectionTitleClass
13
+ } from "./typography.js";
14
+ export {
15
+ Footer,
16
+ LocaleSwitcher,
17
+ Logo,
18
+ Nav,
19
+ PageTitle,
20
+ SectionTitle,
21
+ ThemeProvider,
22
+ ThemeToggle,
23
+ ThemeToggleIcon,
24
+ pageTitleClass,
25
+ sectionTitleClass
26
+ };
@@ -0,0 +1,17 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface LocaleSwitcherProps {
4
+ /** Available locales */
5
+ locales: Array<{
6
+ code: string;
7
+ short: string;
8
+ full: string;
9
+ }>;
10
+ /** Current locale */
11
+ currentLocale: string;
12
+ /** Called when user selects a new locale */
13
+ onLocaleChange: (locale: string) => void;
14
+ }
15
+ declare function LocaleSwitcher({ locales, currentLocale, onLocaleChange, }: LocaleSwitcherProps): react_jsx_runtime.JSX.Element;
16
+
17
+ export { LocaleSwitcher };