@naeil/ui 0.1.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.
- package/CHANGELOG.md +18 -0
- package/DESIGN.md +186 -0
- package/LICENSE +21 -0
- package/README.md +85 -22
- package/THIRD_PARTY_NOTICES.md +49 -0
- package/dist/chunk-JBTDRVZ7.js +46 -0
- package/dist/chunk-QKVN6Q6C.js +438 -0
- package/dist/components/index.d.ts +87 -0
- package/dist/components/index.js +832 -0
- package/dist/components/ui/index.d.ts +105 -0
- package/dist/components/ui/index.js +736 -0
- package/dist/lib/utils.d.ts +5 -0
- package/dist/lib/utils.js +7 -0
- package/dist/source/components/footer.d.ts +15 -0
- package/dist/source/components/footer.js +172 -0
- package/dist/source/components/index.d.ts +11 -0
- package/dist/source/components/index.js +26 -0
- package/dist/source/components/locale-switcher.d.ts +17 -0
- package/dist/source/components/locale-switcher.js +66 -0
- package/dist/source/components/logo.d.ts +9 -0
- package/dist/source/components/logo.js +52 -0
- package/dist/source/components/nav.d.ts +39 -0
- package/dist/source/components/nav.js +412 -0
- package/dist/source/components/theme-provider.d.ts +6 -0
- package/dist/source/components/theme-provider.js +45 -0
- package/dist/source/components/theme-toggle-icon.d.ts +5 -0
- package/dist/source/components/theme-toggle-icon.js +62 -0
- package/dist/source/components/theme-toggle.d.ts +5 -0
- package/dist/source/components/theme-toggle.js +34 -0
- package/dist/source/components/typography.d.ts +12 -0
- package/dist/source/components/typography.js +49 -0
- package/dist/source/components/ui/avatar.d.ts +14 -0
- package/dist/source/components/ui/avatar.js +137 -0
- package/dist/source/components/ui/badge.d.ts +13 -0
- package/dist/source/components/ui/badge.js +76 -0
- package/dist/source/components/ui/button.d.ts +14 -0
- package/dist/source/components/ui/button.js +88 -0
- package/dist/source/components/ui/card.d.ts +13 -0
- package/dist/source/components/ui/card.js +135 -0
- package/dist/source/components/ui/checkbox.d.ts +7 -0
- package/dist/source/components/ui/checkbox.js +58 -0
- package/dist/source/components/ui/dialog.d.ts +20 -0
- package/dist/source/components/ui/dialog.js +182 -0
- package/dist/source/components/ui/dropdown-menu.d.ts +28 -0
- package/dist/source/components/ui/dropdown-menu.js +282 -0
- package/dist/source/components/ui/index.d.ts +19 -0
- package/dist/source/components/ui/index.js +131 -0
- package/dist/source/components/ui/input.d.ts +6 -0
- package/dist/source/components/ui/input.js +49 -0
- package/dist/source/components/ui/select.d.ts +16 -0
- package/dist/source/components/ui/select.js +197 -0
- package/dist/source/components/ui/sonner.d.ts +6 -0
- package/dist/source/components/ui/sonner.js +80 -0
- package/dist/source/components/ui/switch.d.ts +7 -0
- package/dist/source/components/ui/switch.js +54 -0
- package/dist/source/components/ui/tabs.d.ts +10 -0
- package/dist/source/components/ui/tabs.js +57 -0
- package/dist/source/components/ui/textarea.d.ts +6 -0
- package/dist/source/components/ui/textarea.js +46 -0
- package/dist/source/i18n/config.d.ts +6 -0
- package/dist/source/i18n/config.js +12 -0
- package/dist/source/i18n/routing.d.ts +371 -0
- package/dist/source/i18n/routing.js +17 -0
- package/dist/source/lib/design/modal-inert.d.ts +6 -0
- package/dist/source/lib/design/modal-inert.js +73 -0
- package/dist/source/lib/utils.d.ts +5 -0
- package/dist/source/lib/utils.js +8 -0
- package/dist/tokens.ts +217 -0
- package/docs/components/README.md +21 -0
- package/docs/components/avatar.md +47 -0
- package/docs/components/badge.md +29 -0
- package/docs/components/button.md +39 -0
- package/docs/components/card.md +32 -0
- package/docs/components/checkbox.md +35 -0
- package/docs/components/common.md +31 -0
- package/docs/components/composition.md +68 -0
- package/docs/components/dialog.md +41 -0
- package/docs/components/dropdown-menu.md +38 -0
- package/docs/components/input.md +32 -0
- package/docs/components/select.md +39 -0
- package/docs/components/sonner.md +37 -0
- package/docs/components/switch.md +33 -0
- package/docs/components/tabs.md +40 -0
- package/docs/components/textarea.md +35 -0
- package/docs/design/component-demand.md +30 -0
- package/docs/design/public-ui-final-verification.md +96 -0
- package/docs/design/public-ui-release-validation.md +86 -0
- package/docs/design/public-ui-stage3-verification.md +98 -0
- package/docs/design/public-ui-stage4-verification.md +129 -0
- package/docs/design/public-ui-support.md +40 -0
- package/docs/design/v2-migration.md +199 -0
- package/docs/package-release.md +89 -0
- package/licenses/Noto-Sans-JP-OFL.txt +93 -0
- package/licenses/Nunito-Sans-OFL.txt +93 -0
- package/licenses/Pretendard-OFL.txt +94 -0
- package/licenses/React-MIT.txt +21 -0
- package/licenses/Storybook-MIT.txt +21 -0
- package/licenses/popper-MIT.txt +25 -0
- package/licenses/react-remove-scroll-bar-MIT.txt +21 -0
- package/licenses/store2-MIT.txt +22 -0
- package/licenses/toggle-selection-MIT.txt +21 -0
- package/package.json +215 -26
- package/src/styles/components.css +276 -0
- package/src/styles/globals.css +18 -0
- package/src/styles/theme.css +293 -0
- package/messages/en.json +0 -221
- package/messages/ja.json +0 -221
- package/messages/ko.json +0 -221
- package/postcss.config.mjs +0 -7
- package/src/app/[locale]/(content)/baby-agent/page.tsx +0 -30
- package/src/app/[locale]/(content)/blog/page.tsx +0 -68
- package/src/app/[locale]/(content)/cc/page.tsx +0 -216
- package/src/app/[locale]/(content)/design/page.tsx +0 -703
- package/src/app/[locale]/(content)/layout.tsx +0 -7
- package/src/app/[locale]/(content)/pkm/page.tsx +0 -31
- package/src/app/[locale]/(content)/projects/page.tsx +0 -100
- package/src/app/[locale]/(content)/sa/page.tsx +0 -179
- package/src/app/[locale]/(landing)/page.tsx +0 -157
- package/src/app/[locale]/layout.tsx +0 -72
- package/src/app/[locale]/login/actions.ts +0 -10
- package/src/app/[locale]/login/oauth-buttons.tsx +0 -78
- package/src/app/[locale]/login/page.tsx +0 -85
- package/src/app/auth/callback/route.ts +0 -78
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +0 -32
- package/src/app/layout.tsx +0 -22
- package/src/app/sitemap.ts +0 -26
- package/src/components/accent-picker.tsx +0 -62
- package/src/components/auth-slot.tsx +0 -96
- package/src/components/footer-wrapper.tsx +0 -8
- package/src/components/footer.tsx +0 -193
- package/src/components/hero-scene.tsx +0 -948
- package/src/components/hero-section.tsx +0 -57
- package/src/components/locale-switcher.tsx +0 -74
- package/src/components/logo.tsx +0 -51
- package/src/components/nav-server-wrapper.tsx +0 -22
- package/src/components/nav-wrapper.tsx +0 -45
- package/src/components/nav.tsx +0 -550
- package/src/components/paraglider-cursor.tsx +0 -112
- package/src/components/project-layout.tsx +0 -194
- package/src/components/theme-provider.tsx +0 -10
- package/src/components/theme-toggle-icon.tsx +0 -62
- package/src/components/theme-toggle.tsx +0 -39
- package/src/components/typography.tsx +0 -27
- package/src/components/ui/avatar.tsx +0 -109
- package/src/components/ui/badge.tsx +0 -47
- package/src/components/ui/button.tsx +0 -65
- package/src/components/ui/card.tsx +0 -106
- package/src/components/ui/dialog.tsx +0 -158
- package/src/components/ui/dropdown-menu.tsx +0 -257
- package/src/components/ui/input.tsx +0 -21
- package/src/components/ui/sonner.tsx +0 -54
- package/src/components/workflow-diagram.tsx +0 -414
- package/src/i18n/config.ts +0 -8
- package/src/i18n/request.ts +0 -16
- package/src/i18n/routing.ts +0 -12
- package/src/lib/supabase/client.ts +0 -18
- package/src/lib/supabase/middleware.ts +0 -42
- package/src/lib/supabase/server.ts +0 -37
- package/src/lib/utils.ts +0 -6
- package/src/proxy.ts +0 -62
- package/src/tokens/.gitkeep +0 -0
- package/src/tokens/color.json +0 -56
- package/src/tokens/radius.json +0 -9
- package/src/tokens/semantic.json +0 -81
- package/src/tokens/shadow.json +0 -7
- package/src/tokens/spacing.json +0 -16
- package/src/tokens/typography.json +0 -34
- package/src/types/i18n.d.ts +0 -6
- package/src/utils/.gitkeep +0 -0
|
@@ -1,703 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useTranslations } from "next-intl";
|
|
4
|
-
import Image from "next/image";
|
|
5
|
-
import { Button } from "@/components/ui/button";
|
|
6
|
-
import { Input } from "@/components/ui/input";
|
|
7
|
-
import {
|
|
8
|
-
Card,
|
|
9
|
-
CardElevated,
|
|
10
|
-
CardHeader,
|
|
11
|
-
CardTitle,
|
|
12
|
-
CardDescription,
|
|
13
|
-
CardContent,
|
|
14
|
-
CardFooter,
|
|
15
|
-
} from "@/components/ui/card";
|
|
16
|
-
import {
|
|
17
|
-
Dialog,
|
|
18
|
-
DialogTrigger,
|
|
19
|
-
DialogContent,
|
|
20
|
-
DialogHeader,
|
|
21
|
-
DialogTitle,
|
|
22
|
-
DialogDescription,
|
|
23
|
-
DialogFooter,
|
|
24
|
-
DialogClose,
|
|
25
|
-
} from "@/components/ui/dialog";
|
|
26
|
-
import {
|
|
27
|
-
DropdownMenu,
|
|
28
|
-
DropdownMenuTrigger,
|
|
29
|
-
DropdownMenuContent,
|
|
30
|
-
DropdownMenuItem,
|
|
31
|
-
DropdownMenuSeparator,
|
|
32
|
-
DropdownMenuLabel,
|
|
33
|
-
} from "@/components/ui/dropdown-menu";
|
|
34
|
-
import { Badge } from "@/components/ui/badge";
|
|
35
|
-
import {
|
|
36
|
-
Avatar,
|
|
37
|
-
AvatarImage,
|
|
38
|
-
AvatarFallback,
|
|
39
|
-
AvatarBadge,
|
|
40
|
-
AvatarGroup,
|
|
41
|
-
AvatarGroupCount,
|
|
42
|
-
} from "@/components/ui/avatar";
|
|
43
|
-
import { AccentPicker } from "@/components/accent-picker";
|
|
44
|
-
import {
|
|
45
|
-
PageTitle,
|
|
46
|
-
SectionTitle,
|
|
47
|
-
pageTitleClass,
|
|
48
|
-
sectionTitleClass,
|
|
49
|
-
} from "@/components/typography";
|
|
50
|
-
import { toast } from "sonner";
|
|
51
|
-
|
|
52
|
-
/* ─── Token Data (for showcase display) ─── */
|
|
53
|
-
|
|
54
|
-
const GRAY_SCALE = [
|
|
55
|
-
{ step: "50", oklch: "oklch(0.985 0 0)" },
|
|
56
|
-
{ step: "100", oklch: "oklch(0.970 0 0)" },
|
|
57
|
-
{ step: "200", oklch: "oklch(0.922 0 0)" },
|
|
58
|
-
{ step: "300", oklch: "oklch(0.870 0 0)" },
|
|
59
|
-
{ step: "400", oklch: "oklch(0.708 0 0)" },
|
|
60
|
-
{ step: "500", oklch: "oklch(0.556 0 0)" },
|
|
61
|
-
{ step: "600", oklch: "oklch(0.439 0 0)" },
|
|
62
|
-
{ step: "700", oklch: "oklch(0.371 0 0)" },
|
|
63
|
-
{ step: "800", oklch: "oklch(0.269 0 0)" },
|
|
64
|
-
{ step: "900", oklch: "oklch(0.205 0 0)" },
|
|
65
|
-
{ step: "950", oklch: "oklch(0.145 0 0)" },
|
|
66
|
-
];
|
|
67
|
-
|
|
68
|
-
const ACCENT_SCALE = [
|
|
69
|
-
{ step: "50", oklch: "oklch(0.970 0.014 254)" },
|
|
70
|
-
{ step: "100", oklch: "oklch(0.932 0.032 255)" },
|
|
71
|
-
{ step: "200", oklch: "oklch(0.882 0.059 254)" },
|
|
72
|
-
{ step: "300", oklch: "oklch(0.809 0.105 254)" },
|
|
73
|
-
{ step: "400", oklch: "oklch(0.707 0.165 254)" },
|
|
74
|
-
{ step: "500", oklch: "oklch(0.623 0.214 259)" },
|
|
75
|
-
{ step: "600", oklch: "oklch(0.546 0.245 263)" },
|
|
76
|
-
{ step: "700", oklch: "oklch(0.488 0.243 264.376)" },
|
|
77
|
-
{ step: "800", oklch: "oklch(0.424 0.199 265)" },
|
|
78
|
-
{ step: "900", oklch: "oklch(0.379 0.146 265)" },
|
|
79
|
-
{ step: "950", oklch: "oklch(0.282 0.091 267)" },
|
|
80
|
-
];
|
|
81
|
-
|
|
82
|
-
const DESTRUCTIVE_SCALE = [
|
|
83
|
-
{ step: "50", oklch: "oklch(0.971 0.013 17)" },
|
|
84
|
-
{ step: "100", oklch: "oklch(0.936 0.032 17)" },
|
|
85
|
-
{ step: "200", oklch: "oklch(0.885 0.062 18)" },
|
|
86
|
-
{ step: "300", oklch: "oklch(0.808 0.114 19)" },
|
|
87
|
-
{ step: "400", oklch: "oklch(0.704 0.191 22.216)" },
|
|
88
|
-
{ step: "500", oklch: "oklch(0.637 0.237 25)" },
|
|
89
|
-
{ step: "600", oklch: "oklch(0.577 0.245 27.325)" },
|
|
90
|
-
{ step: "700", oklch: "oklch(0.505 0.213 27)" },
|
|
91
|
-
{ step: "800", oklch: "oklch(0.444 0.177 26)" },
|
|
92
|
-
{ step: "900", oklch: "oklch(0.396 0.141 25)" },
|
|
93
|
-
{ step: "950", oklch: "oklch(0.258 0.092 26)" },
|
|
94
|
-
];
|
|
95
|
-
|
|
96
|
-
const SEMANTIC_TOKENS = [
|
|
97
|
-
"background",
|
|
98
|
-
"foreground",
|
|
99
|
-
"card",
|
|
100
|
-
"card-foreground",
|
|
101
|
-
"primary",
|
|
102
|
-
"primary-foreground",
|
|
103
|
-
"secondary",
|
|
104
|
-
"secondary-foreground",
|
|
105
|
-
"muted",
|
|
106
|
-
"muted-foreground",
|
|
107
|
-
"accent",
|
|
108
|
-
"accent-foreground",
|
|
109
|
-
"destructive",
|
|
110
|
-
"destructive-foreground",
|
|
111
|
-
"border",
|
|
112
|
-
"border-subtle",
|
|
113
|
-
"border-subtle-hover",
|
|
114
|
-
"surface-subtle",
|
|
115
|
-
"input",
|
|
116
|
-
"ring",
|
|
117
|
-
];
|
|
118
|
-
|
|
119
|
-
const PROJECT_COLORS = [
|
|
120
|
-
{ name: "CC", token: "--project-cc", oklch: "oklch(0.704 0.140 181)" },
|
|
121
|
-
{ name: "SA", token: "--project-sa", oklch: "oklch(0.723 0.219 149)" },
|
|
122
|
-
{ name: "PKM", token: "--project-pkm", oklch: "oklch(0.627 0.265 303)" },
|
|
123
|
-
{ name: "naeil-ui", token: "--project-naeilUi", oklch: "oklch(0.623 0.214 259)" },
|
|
124
|
-
{ name: "Baby Agent", token: "--project-baby", oklch: "oklch(0.769 0.188 70.08)" },
|
|
125
|
-
];
|
|
126
|
-
|
|
127
|
-
const TYPE_SIZES = [
|
|
128
|
-
{ name: "xs", class: "text-xs" },
|
|
129
|
-
{ name: "sm", class: "text-sm" },
|
|
130
|
-
{ name: "base", class: "text-base" },
|
|
131
|
-
{ name: "lg", class: "text-lg" },
|
|
132
|
-
{ name: "xl", class: "text-xl" },
|
|
133
|
-
{ name: "2xl", class: "text-2xl" },
|
|
134
|
-
{ name: "3xl", class: "text-3xl" },
|
|
135
|
-
{ name: "4xl", class: "text-4xl" },
|
|
136
|
-
];
|
|
137
|
-
|
|
138
|
-
const SPACING_STEPS = [
|
|
139
|
-
{ name: "0", px: "0" },
|
|
140
|
-
{ name: "1", px: "4" },
|
|
141
|
-
{ name: "2", px: "8" },
|
|
142
|
-
{ name: "3", px: "12" },
|
|
143
|
-
{ name: "4", px: "16" },
|
|
144
|
-
{ name: "5", px: "20" },
|
|
145
|
-
{ name: "6", px: "24" },
|
|
146
|
-
{ name: "8", px: "32" },
|
|
147
|
-
{ name: "10", px: "40" },
|
|
148
|
-
{ name: "12", px: "48" },
|
|
149
|
-
{ name: "16", px: "64" },
|
|
150
|
-
];
|
|
151
|
-
|
|
152
|
-
/* ─── Helper Components ─── */
|
|
153
|
-
|
|
154
|
-
function SectionHeading({ children }: { children: React.ReactNode }) {
|
|
155
|
-
return <SectionTitle>{children}</SectionTitle>;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function SubHeading({ children }: { children: React.ReactNode }) {
|
|
159
|
-
return (
|
|
160
|
-
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-widest">
|
|
161
|
-
{children}
|
|
162
|
-
</h3>
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function ColorScale({
|
|
167
|
-
name,
|
|
168
|
-
colors,
|
|
169
|
-
}: {
|
|
170
|
-
name: string;
|
|
171
|
-
colors: { step: string; oklch: string }[];
|
|
172
|
-
}) {
|
|
173
|
-
return (
|
|
174
|
-
<div className="flex flex-col gap-2">
|
|
175
|
-
<SubHeading>{name}</SubHeading>
|
|
176
|
-
<div className="flex gap-1">
|
|
177
|
-
{colors.map((c) => (
|
|
178
|
-
<div key={c.step} className="flex flex-col items-center gap-1 flex-1">
|
|
179
|
-
<div
|
|
180
|
-
className="w-full aspect-square rounded-md border border-border"
|
|
181
|
-
style={{ backgroundColor: c.oklch }}
|
|
182
|
-
/>
|
|
183
|
-
<span className="text-[10px] text-muted-foreground font-mono">
|
|
184
|
-
{c.step}
|
|
185
|
-
</span>
|
|
186
|
-
</div>
|
|
187
|
-
))}
|
|
188
|
-
</div>
|
|
189
|
-
</div>
|
|
190
|
-
);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function SemanticTokenGrid() {
|
|
194
|
-
return (
|
|
195
|
-
<div className="grid grid-cols-3 gap-2 sm:grid-cols-4 md:grid-cols-6">
|
|
196
|
-
{SEMANTIC_TOKENS.map((token) => (
|
|
197
|
-
<div key={token} className="flex flex-col items-center gap-1">
|
|
198
|
-
<div
|
|
199
|
-
className="w-full aspect-square rounded-md border border-border"
|
|
200
|
-
style={{ backgroundColor: `var(--${token})` }}
|
|
201
|
-
/>
|
|
202
|
-
<span className="text-[10px] text-muted-foreground font-mono text-center leading-tight">
|
|
203
|
-
{token}
|
|
204
|
-
</span>
|
|
205
|
-
</div>
|
|
206
|
-
))}
|
|
207
|
-
</div>
|
|
208
|
-
);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/* ─── Main Page ─── */
|
|
212
|
-
|
|
213
|
-
export default function Home() {
|
|
214
|
-
const t = useTranslations("design");
|
|
215
|
-
|
|
216
|
-
return (
|
|
217
|
-
<>
|
|
218
|
-
{/* Hero — matches ProjectLayout */}
|
|
219
|
-
<section className="mx-auto max-w-4xl px-6 pb-16">
|
|
220
|
-
<div className="flex flex-col-reverse items-start gap-8 md:flex-row md:items-start md:justify-between">
|
|
221
|
-
<div className="flex-1">
|
|
222
|
-
<PageTitle className="mb-3">{t("title")}</PageTitle>
|
|
223
|
-
<p className="text-muted-foreground mb-5 max-w-lg text-lg leading-relaxed">
|
|
224
|
-
{t("subtitle")}
|
|
225
|
-
</p>
|
|
226
|
-
<div className="mb-6 flex flex-wrap gap-2">
|
|
227
|
-
{["React", "Tailwind v4", "OKLCH", "shadcn/ui"].map((tag) => (
|
|
228
|
-
<span
|
|
229
|
-
key={tag}
|
|
230
|
-
className="rounded-full border border-black/[0.08] px-2.5 py-1 text-[11px] text-zinc-400 dark:border-white/[0.08]"
|
|
231
|
-
>
|
|
232
|
-
{tag}
|
|
233
|
-
</span>
|
|
234
|
-
))}
|
|
235
|
-
</div>
|
|
236
|
-
<div className="flex flex-wrap items-center gap-3">
|
|
237
|
-
<a
|
|
238
|
-
href="https://github.com/naeil-dev/design-system"
|
|
239
|
-
target="_blank"
|
|
240
|
-
rel="noopener noreferrer"
|
|
241
|
-
className="inline-flex items-center gap-2 rounded-lg px-5 py-2.5 text-sm font-medium transition-colors"
|
|
242
|
-
style={{
|
|
243
|
-
background: "oklch(0.623 0.214 259)",
|
|
244
|
-
color: "var(--background)",
|
|
245
|
-
}}
|
|
246
|
-
>
|
|
247
|
-
GitHub →
|
|
248
|
-
</a>
|
|
249
|
-
</div>
|
|
250
|
-
</div>
|
|
251
|
-
<div className="flex-shrink-0">
|
|
252
|
-
<Image
|
|
253
|
-
src="/images/whale.png"
|
|
254
|
-
alt=""
|
|
255
|
-
width={220}
|
|
256
|
-
height={220}
|
|
257
|
-
className="animate-float object-contain"
|
|
258
|
-
style={{
|
|
259
|
-
filter: "drop-shadow(0 4px 12px color-mix(in oklch, oklch(0.623 0.214 259) 15%, transparent))",
|
|
260
|
-
}}
|
|
261
|
-
/>
|
|
262
|
-
</div>
|
|
263
|
-
</div>
|
|
264
|
-
</section>
|
|
265
|
-
|
|
266
|
-
<div className="flex flex-col gap-16 pb-24 max-w-4xl mx-auto px-6">
|
|
267
|
-
|
|
268
|
-
{/* ════════════════════════════════════════════
|
|
269
|
-
T45: Accent Demo
|
|
270
|
-
════════════════════════════════════════════ */}
|
|
271
|
-
<section className="flex flex-col gap-4">
|
|
272
|
-
<SectionHeading>Accent</SectionHeading>
|
|
273
|
-
<p className="text-sm text-muted-foreground">
|
|
274
|
-
프로젝트별 악센트 색상 주입. 아래 프리셋을 선택하면 모든 accent 토큰이 즉시 변경됩니다.
|
|
275
|
-
</p>
|
|
276
|
-
<AccentPicker />
|
|
277
|
-
</section>
|
|
278
|
-
|
|
279
|
-
{/* ════════════════════════════════════════════
|
|
280
|
-
T43: Token Showcase
|
|
281
|
-
════════════════════════════════════════════ */}
|
|
282
|
-
|
|
283
|
-
{/* Colors — Primitive */}
|
|
284
|
-
<section className="flex flex-col gap-6">
|
|
285
|
-
<SectionHeading>Colors — Primitive</SectionHeading>
|
|
286
|
-
<ColorScale name="Gray" colors={GRAY_SCALE} />
|
|
287
|
-
<ColorScale name="Accent (Blue default)" colors={ACCENT_SCALE} />
|
|
288
|
-
<ColorScale name="Destructive" colors={DESTRUCTIVE_SCALE} />
|
|
289
|
-
</section>
|
|
290
|
-
|
|
291
|
-
{/* Colors — Semantic */}
|
|
292
|
-
<section className="flex flex-col gap-4">
|
|
293
|
-
<SectionHeading>Colors — Semantic</SectionHeading>
|
|
294
|
-
<p className="text-sm text-muted-foreground">
|
|
295
|
-
현재 테마(다크/라이트)에 따라 매핑이 변경됩니다.
|
|
296
|
-
</p>
|
|
297
|
-
<SemanticTokenGrid />
|
|
298
|
-
</section>
|
|
299
|
-
|
|
300
|
-
{/* Colors — Project Accents */}
|
|
301
|
-
<section className="flex flex-col gap-4">
|
|
302
|
-
<SectionHeading>Colors — Project</SectionHeading>
|
|
303
|
-
<p className="text-sm text-muted-foreground">
|
|
304
|
-
프로젝트별 악센트 색상. 라이트/다크 동일.
|
|
305
|
-
</p>
|
|
306
|
-
<div className="flex gap-4">
|
|
307
|
-
{PROJECT_COLORS.map((c) => (
|
|
308
|
-
<div key={c.name} className="flex flex-col items-center gap-2 flex-1">
|
|
309
|
-
<div
|
|
310
|
-
className="w-full aspect-square rounded-md border border-border"
|
|
311
|
-
style={{ backgroundColor: c.oklch }}
|
|
312
|
-
/>
|
|
313
|
-
<span className="text-[11px] text-muted-foreground font-mono text-center leading-tight">
|
|
314
|
-
{c.name}
|
|
315
|
-
</span>
|
|
316
|
-
</div>
|
|
317
|
-
))}
|
|
318
|
-
</div>
|
|
319
|
-
</section>
|
|
320
|
-
|
|
321
|
-
{/* Heading Primitives */}
|
|
322
|
-
<section className="flex flex-col gap-4">
|
|
323
|
-
<SectionHeading>Heading Primitives</SectionHeading>
|
|
324
|
-
<p className="text-sm text-muted-foreground">
|
|
325
|
-
공통 헤딩 컴포넌트로 모든 페이지의 제목 스케일을 통합 관리.
|
|
326
|
-
</p>
|
|
327
|
-
|
|
328
|
-
<div className="grid gap-3 sm:grid-cols-2">
|
|
329
|
-
<div className="rounded-xl border border-border-subtle bg-surface-subtle p-5">
|
|
330
|
-
<p className="mb-2 text-xs font-mono text-muted-foreground">PageTitle</p>
|
|
331
|
-
<p className={pageTitleClass}>System-level page heading</p>
|
|
332
|
-
<p className="mt-2 text-xs text-muted-foreground">text-4xl → lg:text-5xl</p>
|
|
333
|
-
</div>
|
|
334
|
-
|
|
335
|
-
<div className="rounded-xl border border-border-subtle bg-surface-subtle p-5">
|
|
336
|
-
<p className="mb-2 text-xs font-mono text-muted-foreground">SectionTitle</p>
|
|
337
|
-
<p className={sectionTitleClass}>Section heading baseline</p>
|
|
338
|
-
<p className="mt-2 text-xs text-muted-foreground">text-lg</p>
|
|
339
|
-
</div>
|
|
340
|
-
</div>
|
|
341
|
-
</section>
|
|
342
|
-
|
|
343
|
-
{/* Typography */}
|
|
344
|
-
<section className="flex flex-col gap-6">
|
|
345
|
-
<SectionHeading>Typography</SectionHeading>
|
|
346
|
-
|
|
347
|
-
<div className="flex flex-col gap-1">
|
|
348
|
-
<SubHeading>Sans (Pretendard)</SubHeading>
|
|
349
|
-
<div className="flex flex-col gap-2">
|
|
350
|
-
{TYPE_SIZES.map((t) => (
|
|
351
|
-
<div key={t.name} className="flex items-baseline gap-4">
|
|
352
|
-
<span className="text-xs text-muted-foreground font-mono w-10 shrink-0 text-right">
|
|
353
|
-
{t.name}
|
|
354
|
-
</span>
|
|
355
|
-
<span className={`${t.class} font-normal`}>
|
|
356
|
-
가나다라 ABCabc 012
|
|
357
|
-
</span>
|
|
358
|
-
</div>
|
|
359
|
-
))}
|
|
360
|
-
</div>
|
|
361
|
-
</div>
|
|
362
|
-
|
|
363
|
-
<div className="flex flex-col gap-1">
|
|
364
|
-
<SubHeading>Mono (JetBrains Mono)</SubHeading>
|
|
365
|
-
<div className="flex flex-col gap-2">
|
|
366
|
-
{TYPE_SIZES.slice(0, 5).map((t) => (
|
|
367
|
-
<div key={t.name} className="flex items-baseline gap-4">
|
|
368
|
-
<span className="text-xs text-muted-foreground font-mono w-10 shrink-0 text-right">
|
|
369
|
-
{t.name}
|
|
370
|
-
</span>
|
|
371
|
-
<span className={`${t.class} font-mono`}>
|
|
372
|
-
const x = 42; // →
|
|
373
|
-
</span>
|
|
374
|
-
</div>
|
|
375
|
-
))}
|
|
376
|
-
</div>
|
|
377
|
-
</div>
|
|
378
|
-
|
|
379
|
-
<div className="flex flex-col gap-1">
|
|
380
|
-
<SubHeading>Weights</SubHeading>
|
|
381
|
-
<div className="flex flex-col gap-2">
|
|
382
|
-
<span className="text-lg font-normal">
|
|
383
|
-
400 Regular — 기본 텍스트 본문
|
|
384
|
-
</span>
|
|
385
|
-
<span className="text-lg font-medium">
|
|
386
|
-
500 Medium — 강조 라벨
|
|
387
|
-
</span>
|
|
388
|
-
<span className="text-lg font-bold">
|
|
389
|
-
700 Bold — 제목 헤딩
|
|
390
|
-
</span>
|
|
391
|
-
</div>
|
|
392
|
-
</div>
|
|
393
|
-
</section>
|
|
394
|
-
|
|
395
|
-
{/* Spacing */}
|
|
396
|
-
<section className="flex flex-col gap-4">
|
|
397
|
-
<SectionHeading>Spacing</SectionHeading>
|
|
398
|
-
<div className="flex flex-col gap-2">
|
|
399
|
-
{SPACING_STEPS.map((s) => (
|
|
400
|
-
<div key={s.name} className="flex items-center gap-3">
|
|
401
|
-
<span className="text-xs text-muted-foreground font-mono w-8 text-right shrink-0">
|
|
402
|
-
{s.name}
|
|
403
|
-
</span>
|
|
404
|
-
<div
|
|
405
|
-
className="h-3 rounded-sm bg-primary"
|
|
406
|
-
style={{ width: `${s.px}px` }}
|
|
407
|
-
/>
|
|
408
|
-
<span className="text-xs text-muted-foreground font-mono">
|
|
409
|
-
{s.px}px
|
|
410
|
-
</span>
|
|
411
|
-
</div>
|
|
412
|
-
))}
|
|
413
|
-
</div>
|
|
414
|
-
</section>
|
|
415
|
-
|
|
416
|
-
{/* Radius */}
|
|
417
|
-
<section className="flex flex-col gap-4">
|
|
418
|
-
<SectionHeading>Radius</SectionHeading>
|
|
419
|
-
<div className="flex gap-6">
|
|
420
|
-
{[
|
|
421
|
-
{ name: "none", class: "rounded-none", px: "0px" },
|
|
422
|
-
{ name: "sm", class: "rounded-sm", px: "2px" },
|
|
423
|
-
{ name: "md", class: "rounded-md", px: "4px" },
|
|
424
|
-
{ name: "lg", class: "rounded-lg", px: "8px" },
|
|
425
|
-
].map((r) => (
|
|
426
|
-
<div key={r.name} className="flex flex-col items-center gap-2">
|
|
427
|
-
<div
|
|
428
|
-
className={`size-16 bg-primary ${r.class}`}
|
|
429
|
-
/>
|
|
430
|
-
<span className="text-xs text-muted-foreground font-mono">
|
|
431
|
-
{r.name} ({r.px})
|
|
432
|
-
</span>
|
|
433
|
-
</div>
|
|
434
|
-
))}
|
|
435
|
-
</div>
|
|
436
|
-
</section>
|
|
437
|
-
|
|
438
|
-
{/* Shadow */}
|
|
439
|
-
<section className="flex flex-col gap-4">
|
|
440
|
-
<SectionHeading>Shadow</SectionHeading>
|
|
441
|
-
<div className="flex gap-6">
|
|
442
|
-
<div className="flex flex-col items-center gap-2">
|
|
443
|
-
<div className="size-24 rounded-md bg-card border border-border shadow-sm" />
|
|
444
|
-
<span className="text-xs text-muted-foreground font-mono">
|
|
445
|
-
shadow-sm
|
|
446
|
-
</span>
|
|
447
|
-
</div>
|
|
448
|
-
<div className="flex flex-col items-center gap-2">
|
|
449
|
-
<div className="size-24 rounded-md bg-card border border-border shadow-md" />
|
|
450
|
-
<span className="text-xs text-muted-foreground font-mono">
|
|
451
|
-
shadow-md
|
|
452
|
-
</span>
|
|
453
|
-
</div>
|
|
454
|
-
</div>
|
|
455
|
-
</section>
|
|
456
|
-
|
|
457
|
-
{/* ════════════════════════════════════════════
|
|
458
|
-
T44: Component Showcase
|
|
459
|
-
════════════════════════════════════════════ */}
|
|
460
|
-
|
|
461
|
-
{/* Button */}
|
|
462
|
-
<section className="flex flex-col gap-4">
|
|
463
|
-
<SectionHeading>Button</SectionHeading>
|
|
464
|
-
<SubHeading>Variants</SubHeading>
|
|
465
|
-
<div className="flex flex-wrap gap-3">
|
|
466
|
-
<Button>Default</Button>
|
|
467
|
-
<Button variant="secondary">Secondary</Button>
|
|
468
|
-
<Button variant="outline">Outline</Button>
|
|
469
|
-
<Button variant="destructive">Destructive</Button>
|
|
470
|
-
<Button variant="ghost">Ghost</Button>
|
|
471
|
-
<Button variant="link">Link</Button>
|
|
472
|
-
</div>
|
|
473
|
-
<SubHeading>Sizes</SubHeading>
|
|
474
|
-
<div className="flex flex-wrap items-center gap-3">
|
|
475
|
-
<Button size="xs">XS</Button>
|
|
476
|
-
<Button size="sm">SM</Button>
|
|
477
|
-
<Button size="default">Default</Button>
|
|
478
|
-
<Button size="lg">LG</Button>
|
|
479
|
-
</div>
|
|
480
|
-
<SubHeading>States</SubHeading>
|
|
481
|
-
<div className="flex flex-wrap gap-3">
|
|
482
|
-
<Button disabled>Disabled</Button>
|
|
483
|
-
<Button variant="outline" disabled>
|
|
484
|
-
Outline Disabled
|
|
485
|
-
</Button>
|
|
486
|
-
</div>
|
|
487
|
-
</section>
|
|
488
|
-
|
|
489
|
-
{/* Input */}
|
|
490
|
-
<section className="flex flex-col gap-4">
|
|
491
|
-
<SectionHeading>Input</SectionHeading>
|
|
492
|
-
<div className="grid gap-3 sm:grid-cols-2">
|
|
493
|
-
<Input placeholder="기본 입력" />
|
|
494
|
-
<Input type="email" placeholder="이메일" />
|
|
495
|
-
<Input disabled placeholder="비활성화" />
|
|
496
|
-
<Input aria-invalid="true" placeholder="에러 상태" />
|
|
497
|
-
</div>
|
|
498
|
-
</section>
|
|
499
|
-
|
|
500
|
-
{/* Card */}
|
|
501
|
-
<section className="flex flex-col gap-4">
|
|
502
|
-
<SectionHeading>Card</SectionHeading>
|
|
503
|
-
<div className="grid gap-4 sm:grid-cols-2">
|
|
504
|
-
<Card>
|
|
505
|
-
<CardHeader>
|
|
506
|
-
<CardTitle>시스템 상태</CardTitle>
|
|
507
|
-
<CardDescription>현재 시스템 운영 정보</CardDescription>
|
|
508
|
-
</CardHeader>
|
|
509
|
-
<CardContent>
|
|
510
|
-
<p className="text-sm">모든 서비스가 정상 운영 중입니다.</p>
|
|
511
|
-
</CardContent>
|
|
512
|
-
<CardFooter>
|
|
513
|
-
<Button variant="outline" size="sm">
|
|
514
|
-
상세 보기
|
|
515
|
-
</Button>
|
|
516
|
-
</CardFooter>
|
|
517
|
-
</Card>
|
|
518
|
-
<Card>
|
|
519
|
-
<CardHeader>
|
|
520
|
-
<CardTitle>배포 로그</CardTitle>
|
|
521
|
-
<CardDescription>최근 배포 히스토리</CardDescription>
|
|
522
|
-
</CardHeader>
|
|
523
|
-
<CardContent>
|
|
524
|
-
<div className="flex flex-col gap-1">
|
|
525
|
-
<p className="text-sm font-mono text-muted-foreground">
|
|
526
|
-
v0.6.0 — Phase 6 Demo
|
|
527
|
-
</p>
|
|
528
|
-
<p className="text-sm font-mono text-muted-foreground">
|
|
529
|
-
v0.5.0 — Core Components
|
|
530
|
-
</p>
|
|
531
|
-
</div>
|
|
532
|
-
</CardContent>
|
|
533
|
-
</Card>
|
|
534
|
-
</div>
|
|
535
|
-
<SubHeading>Elevated</SubHeading>
|
|
536
|
-
<div className="grid gap-4 sm:grid-cols-2">
|
|
537
|
-
<CardElevated>
|
|
538
|
-
<CardHeader>
|
|
539
|
-
<CardTitle>Elevated Card</CardTitle>
|
|
540
|
-
<CardDescription>다크 모드에서 밝기 차이로 elevation 표현</CardDescription>
|
|
541
|
-
</CardHeader>
|
|
542
|
-
<CardContent>
|
|
543
|
-
<p className="text-sm">shadow-sm + 다크 배경 밝기 상승</p>
|
|
544
|
-
</CardContent>
|
|
545
|
-
</CardElevated>
|
|
546
|
-
</div>
|
|
547
|
-
</section>
|
|
548
|
-
|
|
549
|
-
{/* Dialog */}
|
|
550
|
-
<section className="flex flex-col gap-4">
|
|
551
|
-
<SectionHeading>Dialog</SectionHeading>
|
|
552
|
-
<Dialog>
|
|
553
|
-
<DialogTrigger asChild>
|
|
554
|
-
<Button variant="outline">다이얼로그 열기</Button>
|
|
555
|
-
</DialogTrigger>
|
|
556
|
-
<DialogContent>
|
|
557
|
-
<DialogHeader>
|
|
558
|
-
<DialogTitle>확인</DialogTitle>
|
|
559
|
-
<DialogDescription>
|
|
560
|
-
이 작업을 계속 진행하시겠습니까?
|
|
561
|
-
</DialogDescription>
|
|
562
|
-
</DialogHeader>
|
|
563
|
-
<DialogFooter>
|
|
564
|
-
<DialogClose asChild>
|
|
565
|
-
<Button variant="outline">취소</Button>
|
|
566
|
-
</DialogClose>
|
|
567
|
-
<Button>확인</Button>
|
|
568
|
-
</DialogFooter>
|
|
569
|
-
</DialogContent>
|
|
570
|
-
</Dialog>
|
|
571
|
-
</section>
|
|
572
|
-
|
|
573
|
-
{/* Dropdown Menu */}
|
|
574
|
-
<section className="flex flex-col gap-4">
|
|
575
|
-
<SectionHeading>Dropdown Menu</SectionHeading>
|
|
576
|
-
<DropdownMenu>
|
|
577
|
-
<DropdownMenuTrigger asChild>
|
|
578
|
-
<Button variant="outline">메뉴 열기</Button>
|
|
579
|
-
</DropdownMenuTrigger>
|
|
580
|
-
<DropdownMenuContent>
|
|
581
|
-
<DropdownMenuLabel>작업</DropdownMenuLabel>
|
|
582
|
-
<DropdownMenuSeparator />
|
|
583
|
-
<DropdownMenuItem>프로필</DropdownMenuItem>
|
|
584
|
-
<DropdownMenuItem>설정</DropdownMenuItem>
|
|
585
|
-
<DropdownMenuItem>팀 관리</DropdownMenuItem>
|
|
586
|
-
<DropdownMenuSeparator />
|
|
587
|
-
<DropdownMenuItem variant="destructive">
|
|
588
|
-
로그아웃
|
|
589
|
-
</DropdownMenuItem>
|
|
590
|
-
</DropdownMenuContent>
|
|
591
|
-
</DropdownMenu>
|
|
592
|
-
</section>
|
|
593
|
-
|
|
594
|
-
{/* Sonner */}
|
|
595
|
-
<section className="flex flex-col gap-4">
|
|
596
|
-
<SectionHeading>Sonner (Toast)</SectionHeading>
|
|
597
|
-
<div className="flex flex-wrap gap-3">
|
|
598
|
-
<Button
|
|
599
|
-
variant="outline"
|
|
600
|
-
onClick={() => toast.success("배포가 완료되었습니다.")}
|
|
601
|
-
>
|
|
602
|
-
Success
|
|
603
|
-
</Button>
|
|
604
|
-
<Button
|
|
605
|
-
variant="outline"
|
|
606
|
-
onClick={() => toast.error("배포에 실패했습니다.")}
|
|
607
|
-
>
|
|
608
|
-
Error
|
|
609
|
-
</Button>
|
|
610
|
-
<Button
|
|
611
|
-
variant="outline"
|
|
612
|
-
onClick={() => toast.info("새로운 업데이트가 있습니다.")}
|
|
613
|
-
>
|
|
614
|
-
Info
|
|
615
|
-
</Button>
|
|
616
|
-
<Button
|
|
617
|
-
variant="outline"
|
|
618
|
-
onClick={() => toast.warning("디스크 용량이 부족합니다.")}
|
|
619
|
-
>
|
|
620
|
-
Warning
|
|
621
|
-
</Button>
|
|
622
|
-
</div>
|
|
623
|
-
</section>
|
|
624
|
-
|
|
625
|
-
{/* Badge */}
|
|
626
|
-
<section className="flex flex-col gap-4">
|
|
627
|
-
<SectionHeading>Badge</SectionHeading>
|
|
628
|
-
<div className="flex flex-wrap gap-3">
|
|
629
|
-
<Badge>Default</Badge>
|
|
630
|
-
<Badge variant="secondary">Secondary</Badge>
|
|
631
|
-
<Badge variant="outline">Outline</Badge>
|
|
632
|
-
<Badge variant="destructive">Destructive</Badge>
|
|
633
|
-
</div>
|
|
634
|
-
</section>
|
|
635
|
-
|
|
636
|
-
{/* Avatar */}
|
|
637
|
-
<section className="flex flex-col gap-6">
|
|
638
|
-
<SectionHeading>Avatar</SectionHeading>
|
|
639
|
-
|
|
640
|
-
<div>
|
|
641
|
-
<SubHeading>Sizes</SubHeading>
|
|
642
|
-
<div className="flex items-center gap-4 mt-2">
|
|
643
|
-
<Avatar size="sm">
|
|
644
|
-
<AvatarFallback>S</AvatarFallback>
|
|
645
|
-
</Avatar>
|
|
646
|
-
<Avatar>
|
|
647
|
-
<AvatarImage
|
|
648
|
-
src="https://github.com/shadcn.png"
|
|
649
|
-
alt="shadcn"
|
|
650
|
-
/>
|
|
651
|
-
<AvatarFallback>SC</AvatarFallback>
|
|
652
|
-
</Avatar>
|
|
653
|
-
<Avatar size="lg">
|
|
654
|
-
<AvatarFallback>LG</AvatarFallback>
|
|
655
|
-
</Avatar>
|
|
656
|
-
</div>
|
|
657
|
-
</div>
|
|
658
|
-
|
|
659
|
-
<div>
|
|
660
|
-
<SubHeading>With Badge</SubHeading>
|
|
661
|
-
<div className="flex items-center gap-4 mt-2">
|
|
662
|
-
<Avatar>
|
|
663
|
-
<AvatarImage
|
|
664
|
-
src="https://github.com/shadcn.png"
|
|
665
|
-
alt="shadcn"
|
|
666
|
-
/>
|
|
667
|
-
<AvatarFallback>SC</AvatarFallback>
|
|
668
|
-
<AvatarBadge />
|
|
669
|
-
</Avatar>
|
|
670
|
-
<Avatar size="lg">
|
|
671
|
-
<AvatarFallback>JM</AvatarFallback>
|
|
672
|
-
<AvatarBadge />
|
|
673
|
-
</Avatar>
|
|
674
|
-
</div>
|
|
675
|
-
</div>
|
|
676
|
-
|
|
677
|
-
<div>
|
|
678
|
-
<SubHeading>Group</SubHeading>
|
|
679
|
-
<div className="mt-2">
|
|
680
|
-
<AvatarGroup>
|
|
681
|
-
<Avatar>
|
|
682
|
-
<AvatarImage
|
|
683
|
-
src="https://github.com/shadcn.png"
|
|
684
|
-
alt="1"
|
|
685
|
-
/>
|
|
686
|
-
<AvatarFallback>A</AvatarFallback>
|
|
687
|
-
</Avatar>
|
|
688
|
-
<Avatar>
|
|
689
|
-
<AvatarFallback>B</AvatarFallback>
|
|
690
|
-
</Avatar>
|
|
691
|
-
<Avatar>
|
|
692
|
-
<AvatarFallback>C</AvatarFallback>
|
|
693
|
-
</Avatar>
|
|
694
|
-
<AvatarGroupCount>+5</AvatarGroupCount>
|
|
695
|
-
</AvatarGroup>
|
|
696
|
-
</div>
|
|
697
|
-
</div>
|
|
698
|
-
</section>
|
|
699
|
-
|
|
700
|
-
</div>
|
|
701
|
-
</>
|
|
702
|
-
);
|
|
703
|
-
}
|