@naeil/ui 0.8.0 → 0.10.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 +24 -1
- package/DESIGN.md +5 -1
- package/README.md +6 -6
- package/dist/{chunk-ULZPJI5X.js → chunk-F7XM5HJ4.js} +40 -154
- package/dist/{chunk-WA5D7UI2.js → chunk-GQO6NMXK.js} +267 -2
- package/dist/components/index.js +12 -3
- package/dist/components/naeil-footer.d.ts +3 -3
- package/dist/components/naeil-footer.js +14 -11
- package/dist/components/naeil-header.d.ts +7 -9
- package/dist/components/naeil-header.js +2 -2
- package/dist/lib/ui-release.d.ts +1 -1
- package/dist/lib/ui-release.js +1 -1
- package/dist/naeil-locale/checker.d.ts +16 -0
- package/dist/naeil-locale/checker.js +91 -0
- package/dist/naeil-locale/chrome.d.ts +150 -0
- package/dist/naeil-locale/chrome.js +2385 -0
- package/dist/naeil-locale/chunk-D37JHNUN.js +56 -0
- package/dist/naeil-locale/chunk-N3ETBM74.js +24 -0
- package/dist/naeil-locale/chunk-QWHIELL2.js +161 -0
- package/dist/naeil-locale/chunk-YQ5OJWBF.js +53 -0
- package/dist/naeil-locale/client.d.ts +70 -0
- package/dist/naeil-locale/client.js +382 -0
- package/dist/naeil-locale/en-ZC66VDHP.js +86 -0
- package/dist/naeil-locale/index.d.ts +40 -0
- package/dist/naeil-locale/index.js +111 -0
- package/dist/naeil-locale/ja-DKIEQUG7.js +86 -0
- package/dist/naeil-locale/ko-CY6663RZ.js +86 -0
- package/dist/naeil-locale/messages-BQ-fnCAJ.d.ts +166 -0
- package/dist/naeil-locale/messages.d.ts +1 -0
- package/dist/naeil-locale/messages.js +14 -0
- package/dist/naeil-locale/server.d.ts +75 -0
- package/dist/naeil-locale/server.js +172 -0
- package/dist/source/components/naeil-footer-core.d.ts +16 -0
- package/dist/source/components/naeil-footer-core.js +93 -0
- package/dist/source/components/naeil-footer.d.ts +6 -11
- package/dist/source/components/naeil-footer.js +4 -75
- package/dist/source/components/naeil-header-account-core.d.ts +26 -0
- package/dist/source/components/naeil-header-account-core.js +98 -0
- package/dist/source/components/naeil-header-account.d.ts +6 -22
- package/dist/source/components/naeil-header-account.js +5 -81
- package/dist/source/components/naeil-header-content.d.ts +102 -109
- package/dist/source/components/naeil-header-content.js +6 -142
- package/dist/source/components/naeil-header-core.d.ts +59 -0
- package/dist/source/components/naeil-header-core.js +231 -0
- package/dist/source/components/naeil-header-data.d.ts +11 -0
- package/dist/source/components/naeil-header-data.js +14 -0
- package/dist/source/components/naeil-header.d.ts +10 -51
- package/dist/source/components/naeil-header.js +9 -200
- package/dist/source/components/naeil-messages-context.d.ts +94 -0
- package/dist/source/components/naeil-messages-context.js +16 -0
- package/dist/source/components/naeil-standalone-messages.d.ts +11 -0
- package/dist/source/components/naeil-standalone-messages.js +13 -0
- package/dist/source/i18n/routing.d.ts +22 -20
- package/dist/source/lib/ui-release.d.ts +1 -1
- package/dist/source/lib/ui-release.js +1 -1
- package/dist/source/naeil-locale/messages/en.json +78 -0
- package/dist/source/naeil-locale/messages/ja.json +78 -0
- package/dist/source/naeil-locale/messages/ko.json +78 -0
- package/docs/components/README.md +1 -1
- package/docs/components/application-layout.md +24 -6
- package/docs/components/common.md +2 -2
- package/docs/components/naeil-header.md +10 -4
- package/docs/components/naeil-locale.md +46 -0
- package/docs/design/v2-migration.md +8 -4
- package/docs/package-release.md +27 -6
- package/package.json +34 -6
- package/src/styles/components.css +17 -0
- /package/dist/{naeil-header-content-BvISJ4RV.d.ts → naeil-header-data-BvISJ4RV.d.ts} +0 -0
|
@@ -0,0 +1,231 @@
|
|
|
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));
|
|
21
|
+
var __objRest = (source, exclude) => {
|
|
22
|
+
var target = {};
|
|
23
|
+
for (var prop in source)
|
|
24
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
25
|
+
target[prop] = source[prop];
|
|
26
|
+
if (source != null && __getOwnPropSymbols)
|
|
27
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
28
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
29
|
+
target[prop] = source[prop];
|
|
30
|
+
}
|
|
31
|
+
return target;
|
|
32
|
+
};
|
|
33
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
34
|
+
import { useSyncExternalStore } from "react";
|
|
35
|
+
import { useTheme } from "next-themes";
|
|
36
|
+
import { Moon, Sun } from "lucide-react";
|
|
37
|
+
import { Logo } from "./logo.js";
|
|
38
|
+
import { Badge } from "./ui/badge.js";
|
|
39
|
+
import { Button } from "./ui/button.js";
|
|
40
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select.js";
|
|
41
|
+
import { Navigation } from "./ui/navigation.js";
|
|
42
|
+
import { cn } from "../lib/utils.js";
|
|
43
|
+
import { uiRelease } from "../lib/ui-release.js";
|
|
44
|
+
import { headerLocales, headerProjects } from "./naeil-header-data.js";
|
|
45
|
+
import { useNaeilMessages } from "./naeil-messages-context.js";
|
|
46
|
+
import { NaeilHeaderAccountControl } from "./naeil-header-account-core.js";
|
|
47
|
+
const subscribe = () => () => {
|
|
48
|
+
};
|
|
49
|
+
function NaeilHeaderThemeControl({ locale }) {
|
|
50
|
+
const copy = useNaeilMessages(locale);
|
|
51
|
+
const { resolvedTheme, setTheme } = useTheme();
|
|
52
|
+
const mounted = useSyncExternalStore(subscribe, () => true, () => false);
|
|
53
|
+
const dark = mounted && resolvedTheme === "dark";
|
|
54
|
+
return /* @__PURE__ */ jsx(
|
|
55
|
+
Button,
|
|
56
|
+
{
|
|
57
|
+
variant: "ghost",
|
|
58
|
+
size: "icon",
|
|
59
|
+
className: "size-11 shrink-0",
|
|
60
|
+
disabled: !mounted,
|
|
61
|
+
"aria-label": copy.header.theme[dark ? "switchToLight" : "switchToDark"],
|
|
62
|
+
onClick: () => setTheme(dark ? "light" : "dark"),
|
|
63
|
+
children: dark ? /* @__PURE__ */ jsx(Sun, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Moon, { "aria-hidden": "true" })
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
function NaeilHeaderLocaleControl({ locale, onLocaleChange }) {
|
|
68
|
+
const copy = useNaeilMessages(locale);
|
|
69
|
+
return /* @__PURE__ */ jsxs(Select, { value: locale, onValueChange: (value) => onLocaleChange(value), children: [
|
|
70
|
+
/* @__PURE__ */ jsx(
|
|
71
|
+
SelectTrigger,
|
|
72
|
+
{
|
|
73
|
+
"data-naeil-focus-id": "locale-control",
|
|
74
|
+
className: "h-11 w-auto min-w-20 border-transparent bg-transparent px-2",
|
|
75
|
+
"aria-label": copy.header.locale.switchLabel,
|
|
76
|
+
children: /* @__PURE__ */ jsx(SelectValue, { children: locale.toUpperCase() })
|
|
77
|
+
}
|
|
78
|
+
),
|
|
79
|
+
/* @__PURE__ */ jsx(SelectContent, { align: "end", "data-naeil-chrome": "", "data-naeil-locale-menu": "", lang: locale, children: headerLocales.map((value) => /* @__PURE__ */ jsx(SelectItem, { value, className: "min-h-11", lang: value, children: copy.locale.names[value] }, value)) })
|
|
80
|
+
] });
|
|
81
|
+
}
|
|
82
|
+
const NativeLink = (props) => /* @__PURE__ */ jsx("a", __spreadValues({}, props));
|
|
83
|
+
function NaeilHeader(_a) {
|
|
84
|
+
var _b = _a, {
|
|
85
|
+
locale,
|
|
86
|
+
resolveHref = (path) => `https://naeil.dev/${locale}${path === "/" ? "" : path}`,
|
|
87
|
+
brandHref,
|
|
88
|
+
brandSlot,
|
|
89
|
+
brandSuffix,
|
|
90
|
+
statusSlot,
|
|
91
|
+
appNavigation,
|
|
92
|
+
brandLinkProps,
|
|
93
|
+
brandLinkComponent,
|
|
94
|
+
onLocaleChange,
|
|
95
|
+
authSlot,
|
|
96
|
+
toolbarSlot,
|
|
97
|
+
projects,
|
|
98
|
+
projectsExternal = false,
|
|
99
|
+
translations,
|
|
100
|
+
showProjects = true,
|
|
101
|
+
showBlog = true,
|
|
102
|
+
subNav,
|
|
103
|
+
currentProjectKey,
|
|
104
|
+
currentProjectHref,
|
|
105
|
+
labels,
|
|
106
|
+
Link = NativeLink,
|
|
107
|
+
currentHref,
|
|
108
|
+
onNavigate,
|
|
109
|
+
className,
|
|
110
|
+
containerClassName
|
|
111
|
+
} = _b, props = __objRest(_b, [
|
|
112
|
+
"locale",
|
|
113
|
+
"resolveHref",
|
|
114
|
+
"brandHref",
|
|
115
|
+
"brandSlot",
|
|
116
|
+
"brandSuffix",
|
|
117
|
+
"statusSlot",
|
|
118
|
+
"appNavigation",
|
|
119
|
+
"brandLinkProps",
|
|
120
|
+
"brandLinkComponent",
|
|
121
|
+
"onLocaleChange",
|
|
122
|
+
"authSlot",
|
|
123
|
+
"toolbarSlot",
|
|
124
|
+
"projects",
|
|
125
|
+
"projectsExternal",
|
|
126
|
+
"translations",
|
|
127
|
+
"showProjects",
|
|
128
|
+
"showBlog",
|
|
129
|
+
"subNav",
|
|
130
|
+
"currentProjectKey",
|
|
131
|
+
"currentProjectHref",
|
|
132
|
+
"labels",
|
|
133
|
+
"Link",
|
|
134
|
+
"currentHref",
|
|
135
|
+
"onNavigate",
|
|
136
|
+
"className",
|
|
137
|
+
"containerClassName"
|
|
138
|
+
]);
|
|
139
|
+
var _b2, _c;
|
|
140
|
+
const content = useNaeilMessages(locale).header;
|
|
141
|
+
const projectLinks = !showProjects ? [] : projects != null ? projects : headerProjects.map((project) => {
|
|
142
|
+
var _a3, _b3, _c2;
|
|
143
|
+
const current = project.key === currentProjectKey;
|
|
144
|
+
return {
|
|
145
|
+
id: project.key,
|
|
146
|
+
label: (_a3 = translations == null ? void 0 : translations.project(`${project.key}.name`)) != null ? _a3 : content.projects[project.key].name,
|
|
147
|
+
description: (_b3 = translations == null ? void 0 : translations.project(`${project.key}.description`)) != null ? _b3 : content.projects[project.key].description,
|
|
148
|
+
href: current ? currentProjectHref || "/" : resolveHref(project.href),
|
|
149
|
+
external: !current && projectsExternal,
|
|
150
|
+
active: current || currentHref === project.href || (currentHref == null ? void 0 : currentHref.startsWith(`${project.href}/`)) || currentHref === resolveHref(project.href),
|
|
151
|
+
icon: /* @__PURE__ */ jsx("span", { className: "naeil-header-project-icon", style: {
|
|
152
|
+
borderColor: `color-mix(in oklch, ${project.accent} 30%, transparent)`,
|
|
153
|
+
backgroundColor: `color-mix(in oklch, ${project.accent} 8%, transparent)`
|
|
154
|
+
}, children: /* @__PURE__ */ jsx("img", { src: `https://naeil.dev/images/${project.icon}.png`, alt: "", width: 24, height: 24 }) }),
|
|
155
|
+
badge: project.status === "coming" ? /* @__PURE__ */ jsx(Badge, { variant: "outline", children: (_c2 = translations == null ? void 0 : translations.project("status.coming")) != null ? _c2 : content.projects.status.coming }) : void 0
|
|
156
|
+
};
|
|
157
|
+
});
|
|
158
|
+
const brandDestination = brandHref != null ? brandHref : resolveHref("/");
|
|
159
|
+
const BrandLink = brandLinkComponent != null ? brandLinkComponent : Link;
|
|
160
|
+
const _a2 = brandLinkProps != null ? brandLinkProps : {}, { onClick: onBrandClick } = _a2, brandProps = __objRest(_a2, ["onClick"]);
|
|
161
|
+
const toolbar = /* @__PURE__ */ jsx(
|
|
162
|
+
"div",
|
|
163
|
+
{
|
|
164
|
+
"data-app-toolbar": true,
|
|
165
|
+
className: "naeil-header-controls",
|
|
166
|
+
"data-naeil-chrome": toolbarSlot === void 0 ? "" : void 0,
|
|
167
|
+
lang: toolbarSlot === void 0 ? locale : void 0,
|
|
168
|
+
children: toolbarSlot !== void 0 ? toolbarSlot : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
169
|
+
/* @__PURE__ */ jsx(NaeilHeaderThemeControl, { locale }),
|
|
170
|
+
onLocaleChange && /* @__PURE__ */ jsx(NaeilHeaderLocaleControl, { locale, onLocaleChange }),
|
|
171
|
+
authSlot && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
172
|
+
/* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: "naeil-header-separator" }),
|
|
173
|
+
authSlot
|
|
174
|
+
] })
|
|
175
|
+
] })
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
const logo = /* @__PURE__ */ jsx(Logo, { variant: "horizontal", size: 28, className: "block", label: null });
|
|
179
|
+
const brand = /* @__PURE__ */ jsx(
|
|
180
|
+
BrandLink,
|
|
181
|
+
__spreadProps(__spreadValues({
|
|
182
|
+
href: brandDestination,
|
|
183
|
+
"data-app-brand": true,
|
|
184
|
+
"aria-label": brandSlot == null ? ".naeil" : void 0
|
|
185
|
+
}, brandProps), {
|
|
186
|
+
onClick: (event) => {
|
|
187
|
+
onBrandClick == null ? void 0 : onBrandClick(event);
|
|
188
|
+
onNavigate == null ? void 0 : onNavigate(event, { id: "brand", href: brandDestination, label: ".naeil" });
|
|
189
|
+
},
|
|
190
|
+
children: brandSlot != null ? brandSlot : brandSuffix ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
191
|
+
logo,
|
|
192
|
+
/* @__PURE__ */ jsx("span", { className: "naeil-header-brand-suffix", children: brandSuffix })
|
|
193
|
+
] }) : logo
|
|
194
|
+
})
|
|
195
|
+
);
|
|
196
|
+
return /* @__PURE__ */ jsx(
|
|
197
|
+
Navigation,
|
|
198
|
+
__spreadProps(__spreadValues({}, props), {
|
|
199
|
+
"data-global-header": true,
|
|
200
|
+
"data-naeil-header": true,
|
|
201
|
+
"data-naeil-chrome": "",
|
|
202
|
+
lang: locale,
|
|
203
|
+
"data-naeil-ui-version": uiRelease.version,
|
|
204
|
+
"data-naeil-ui-contract": uiRelease.contractVersion,
|
|
205
|
+
Link,
|
|
206
|
+
currentHref,
|
|
207
|
+
onNavigate,
|
|
208
|
+
brand: statusSlot != null ? /* @__PURE__ */ jsxs("div", { className: "naeil-header-brand-row", children: [
|
|
209
|
+
brand,
|
|
210
|
+
statusSlot
|
|
211
|
+
] }) : brand,
|
|
212
|
+
items: [
|
|
213
|
+
...showProjects ? [{ id: "projects", label: (_b2 = translations == null ? void 0 : translations.projects) != null ? _b2 : content.nav.projects, items: projectLinks, columns: projectLinks.length > 1 ? 2 : 1 }] : [],
|
|
214
|
+
...showBlog ? [{ id: "blog", label: (_c = translations == null ? void 0 : translations.blog) != null ? _c : content.nav.blog, href: resolveHref("/blog"), external: projectsExternal }] : [],
|
|
215
|
+
...appNavigation != null ? appNavigation : [],
|
|
216
|
+
...(subNav != null ? subNav : []).map((item) => __spreadProps(__spreadValues({}, item), { id: item.href }))
|
|
217
|
+
],
|
|
218
|
+
labels: labels != null ? labels : { navigation: content.nav.navigation, menu: content.nav.menu, close: content.nav.closeMenu },
|
|
219
|
+
toolbar,
|
|
220
|
+
mobileToolbar: toolbar,
|
|
221
|
+
className: cn("naeil-header fixed top-0 w-full", className),
|
|
222
|
+
containerClassName: cn("naeil-header-frame", containerClassName)
|
|
223
|
+
})
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
export {
|
|
227
|
+
NaeilHeader,
|
|
228
|
+
NaeilHeaderAccountControl,
|
|
229
|
+
NaeilHeaderLocaleControl,
|
|
230
|
+
NaeilHeaderThemeControl
|
|
231
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare const headerLocales: readonly ["en", "ko", "ja"];
|
|
2
|
+
type NaeilHeaderLocale = (typeof headerLocales)[number];
|
|
3
|
+
declare const headerProjects: readonly [{
|
|
4
|
+
readonly key: "naeilUi";
|
|
5
|
+
readonly href: "/design";
|
|
6
|
+
readonly accent: "oklch(0.623 0.214 259)";
|
|
7
|
+
readonly icon: "whale";
|
|
8
|
+
readonly status: "active" | "coming";
|
|
9
|
+
}];
|
|
10
|
+
|
|
11
|
+
export { type NaeilHeaderLocale, headerLocales, headerProjects };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const headerLocales = ["en", "ko", "ja"];
|
|
2
|
+
const headerProjects = [
|
|
3
|
+
{
|
|
4
|
+
"key": "naeilUi",
|
|
5
|
+
"href": "/design",
|
|
6
|
+
"accent": "oklch(0.623 0.214 259)",
|
|
7
|
+
"icon": "whale",
|
|
8
|
+
"status": "active"
|
|
9
|
+
}
|
|
10
|
+
];
|
|
11
|
+
export {
|
|
12
|
+
headerLocales,
|
|
13
|
+
headerProjects
|
|
14
|
+
};
|
|
@@ -1,59 +1,18 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
export { NaeilHeaderAccount,
|
|
2
|
+
import { NaeilHeaderProps } from './naeil-header-core.js';
|
|
3
|
+
import { NaeilHeaderLocale } from './naeil-header-data.js';
|
|
4
|
+
export { NaeilHeaderAccountControl } from './naeil-header-account.js';
|
|
5
|
+
export { NaeilHeaderAccount, NaeilHeaderAccountControlProps } from './naeil-header-account-core.js';
|
|
6
|
+
import 'react';
|
|
7
|
+
import './ui/navigation.js';
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
/** Resolve canonical unlocalized paths. Defaults to the official localized site. */
|
|
10
|
-
resolveHref?: (path: string) => string;
|
|
11
|
-
brandHref?: string;
|
|
12
|
-
brandSlot?: ReactNode;
|
|
13
|
-
/** Ignored when brandSlot replaces the complete brand content. */
|
|
14
|
-
brandSuffix?: string;
|
|
15
|
-
/** After the brand link, outside it; rendered once at every width. */
|
|
16
|
-
statusSlot?: ReactNode;
|
|
17
|
-
/** Product menu data, after catalog/blog and before flat subNav links. */
|
|
18
|
-
appNavigation?: NavigationItem[];
|
|
19
|
-
brandLinkProps?: Omit<NavigationLinkProps, "href" | "children">;
|
|
20
|
-
/** Omit when the application does not support changing its UI language. */
|
|
21
|
-
onLocaleChange?: (locale: NaeilHeaderLocale) => void;
|
|
22
|
-
/** Use NaeilHeaderAccountControl for canonical UI; the app owns auth state/I/O. */
|
|
23
|
-
authSlot?: ReactNode;
|
|
24
|
-
labels?: NavigationProps["labels"];
|
|
25
|
-
projects?: NavigationLink[];
|
|
26
|
-
/** Legacy remote-catalog mode: generated noncurrent project/blog links use native anchors. */
|
|
27
|
-
projectsExternal?: boolean;
|
|
28
|
-
/** Legacy next-intl copy overrides; catalog/artwork/layout remain shared. */
|
|
29
|
-
translations?: {
|
|
30
|
-
projects: string;
|
|
31
|
-
blog: string;
|
|
32
|
-
project: (key: string) => string;
|
|
33
|
-
};
|
|
34
|
-
showProjects?: boolean;
|
|
35
|
-
showBlog?: boolean;
|
|
36
|
-
subNav?: Array<{
|
|
37
|
-
label: string;
|
|
38
|
-
href: string;
|
|
39
|
-
}>;
|
|
40
|
-
currentProjectKey?: string;
|
|
41
|
-
currentProjectHref?: string;
|
|
42
|
-
/** Compatibility escape hatch replacing the default theme/locale/auth toolbar. */
|
|
43
|
-
toolbarSlot?: ReactNode;
|
|
44
|
-
/** Compatibility escape hatch for the legacy native external brand link. */
|
|
45
|
-
brandLinkComponent?: NavigationLinkComponent;
|
|
46
|
-
}
|
|
47
|
-
/** The actual header theme control; reads only the consumer's theme provider. */
|
|
48
|
-
declare function NaeilHeaderThemeControl({ locale }: {
|
|
9
|
+
declare function NaeilHeader(props: NaeilHeaderProps): react_jsx_runtime.JSX.Element;
|
|
10
|
+
declare function NaeilHeaderThemeControl(props: {
|
|
49
11
|
locale: NaeilHeaderLocale;
|
|
50
12
|
}): react_jsx_runtime.JSX.Element;
|
|
51
|
-
|
|
52
|
-
declare function NaeilHeaderLocaleControl({ locale, onLocaleChange }: {
|
|
13
|
+
declare function NaeilHeaderLocaleControl(props: {
|
|
53
14
|
locale: NaeilHeaderLocale;
|
|
54
15
|
onLocaleChange: (locale: NaeilHeaderLocale) => void;
|
|
55
16
|
}): react_jsx_runtime.JSX.Element;
|
|
56
|
-
/** One complete, opt-in branded composition shared by naeil.dev and applications. */
|
|
57
|
-
declare function NaeilHeader({ locale, resolveHref, brandHref, brandSlot, brandSuffix, statusSlot, appNavigation, 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;
|
|
58
17
|
|
|
59
|
-
export { NaeilHeader, NaeilHeaderLocale, NaeilHeaderLocaleControl,
|
|
18
|
+
export { NaeilHeader, NaeilHeaderLocale, NaeilHeaderLocaleControl, NaeilHeaderProps, NaeilHeaderThemeControl };
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
|
-
var __defProps = Object.defineProperties;
|
|
4
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
5
3
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
4
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
5
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -17,207 +15,18 @@ var __spreadValues = (a, b) => {
|
|
|
17
15
|
}
|
|
18
16
|
return a;
|
|
19
17
|
};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
for (var prop in source)
|
|
24
|
-
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
25
|
-
target[prop] = source[prop];
|
|
26
|
-
if (source != null && __getOwnPropSymbols)
|
|
27
|
-
for (var prop of __getOwnPropSymbols(source)) {
|
|
28
|
-
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
29
|
-
target[prop] = source[prop];
|
|
30
|
-
}
|
|
31
|
-
return target;
|
|
32
|
-
};
|
|
33
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
34
|
-
import { useSyncExternalStore } from "react";
|
|
35
|
-
import { useTheme } from "next-themes";
|
|
36
|
-
import { Moon, Sun } from "lucide-react";
|
|
37
|
-
import { Logo } from "./logo.js";
|
|
38
|
-
import { Badge } from "./ui/badge.js";
|
|
39
|
-
import { Button } from "./ui/button.js";
|
|
40
|
-
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select.js";
|
|
41
|
-
import { Navigation } from "./ui/navigation.js";
|
|
42
|
-
import { cn } from "../lib/utils.js";
|
|
43
|
-
import { uiRelease } from "../lib/ui-release.js";
|
|
44
|
-
import { headerContent, headerLocales, headerLocaleNames, headerProjects } from "./naeil-header-content.js";
|
|
18
|
+
import { jsx } from "react/jsx-runtime";
|
|
19
|
+
import { NaeilHeader as Header, NaeilHeaderThemeControl as ThemeControl, NaeilHeaderLocaleControl as LocaleControl } from "./naeil-header-core.js";
|
|
20
|
+
import { NaeilStandaloneMessages } from "./naeil-standalone-messages.js";
|
|
45
21
|
import { NaeilHeaderAccountControl } from "./naeil-header-account.js";
|
|
46
|
-
|
|
47
|
-
};
|
|
48
|
-
function NaeilHeaderThemeControl({ locale }) {
|
|
49
|
-
const { resolvedTheme, setTheme } = useTheme();
|
|
50
|
-
const mounted = useSyncExternalStore(subscribe, () => true, () => false);
|
|
51
|
-
const dark = mounted && resolvedTheme === "dark";
|
|
52
|
-
return /* @__PURE__ */ jsx(
|
|
53
|
-
Button,
|
|
54
|
-
{
|
|
55
|
-
variant: "ghost",
|
|
56
|
-
size: "icon",
|
|
57
|
-
className: "size-11 shrink-0",
|
|
58
|
-
disabled: !mounted,
|
|
59
|
-
"aria-label": headerContent[locale].theme[dark ? "switchToLight" : "switchToDark"],
|
|
60
|
-
onClick: () => setTheme(dark ? "light" : "dark"),
|
|
61
|
-
children: dark ? /* @__PURE__ */ jsx(Sun, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Moon, { "aria-hidden": "true" })
|
|
62
|
-
}
|
|
63
|
-
);
|
|
22
|
+
function NaeilHeader(props) {
|
|
23
|
+
return /* @__PURE__ */ jsx(NaeilStandaloneMessages, { locale: props.locale, children: /* @__PURE__ */ jsx(Header, __spreadValues({}, props)) });
|
|
64
24
|
}
|
|
65
|
-
function
|
|
66
|
-
return /* @__PURE__ */
|
|
67
|
-
/* @__PURE__ */ jsx(
|
|
68
|
-
SelectTrigger,
|
|
69
|
-
{
|
|
70
|
-
className: "h-11 w-auto min-w-20 border-transparent bg-transparent px-2",
|
|
71
|
-
"aria-label": headerContent[locale].locale.switchLabel,
|
|
72
|
-
children: /* @__PURE__ */ jsx(SelectValue, { children: locale.toUpperCase() })
|
|
73
|
-
}
|
|
74
|
-
),
|
|
75
|
-
/* @__PURE__ */ jsx(SelectContent, { align: "end", "data-naeil-chrome": "", "data-naeil-locale-menu": "", lang: locale, children: headerLocales.map((value) => /* @__PURE__ */ jsx(SelectItem, { value, className: "min-h-11", lang: value, children: headerLocaleNames[value] }, value)) })
|
|
76
|
-
] });
|
|
25
|
+
function NaeilHeaderThemeControl(props) {
|
|
26
|
+
return /* @__PURE__ */ jsx(NaeilStandaloneMessages, { locale: props.locale, children: /* @__PURE__ */ jsx(ThemeControl, __spreadValues({}, props)) });
|
|
77
27
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
var _b = _a, {
|
|
81
|
-
locale,
|
|
82
|
-
resolveHref = (path) => `https://naeil.dev/${locale}${path === "/" ? "" : path}`,
|
|
83
|
-
brandHref,
|
|
84
|
-
brandSlot,
|
|
85
|
-
brandSuffix,
|
|
86
|
-
statusSlot,
|
|
87
|
-
appNavigation,
|
|
88
|
-
brandLinkProps,
|
|
89
|
-
brandLinkComponent,
|
|
90
|
-
onLocaleChange,
|
|
91
|
-
authSlot,
|
|
92
|
-
toolbarSlot,
|
|
93
|
-
projects,
|
|
94
|
-
projectsExternal = false,
|
|
95
|
-
translations,
|
|
96
|
-
showProjects = true,
|
|
97
|
-
showBlog = true,
|
|
98
|
-
subNav,
|
|
99
|
-
currentProjectKey,
|
|
100
|
-
currentProjectHref,
|
|
101
|
-
labels,
|
|
102
|
-
Link = NativeLink,
|
|
103
|
-
currentHref,
|
|
104
|
-
onNavigate,
|
|
105
|
-
className,
|
|
106
|
-
containerClassName
|
|
107
|
-
} = _b, props = __objRest(_b, [
|
|
108
|
-
"locale",
|
|
109
|
-
"resolveHref",
|
|
110
|
-
"brandHref",
|
|
111
|
-
"brandSlot",
|
|
112
|
-
"brandSuffix",
|
|
113
|
-
"statusSlot",
|
|
114
|
-
"appNavigation",
|
|
115
|
-
"brandLinkProps",
|
|
116
|
-
"brandLinkComponent",
|
|
117
|
-
"onLocaleChange",
|
|
118
|
-
"authSlot",
|
|
119
|
-
"toolbarSlot",
|
|
120
|
-
"projects",
|
|
121
|
-
"projectsExternal",
|
|
122
|
-
"translations",
|
|
123
|
-
"showProjects",
|
|
124
|
-
"showBlog",
|
|
125
|
-
"subNav",
|
|
126
|
-
"currentProjectKey",
|
|
127
|
-
"currentProjectHref",
|
|
128
|
-
"labels",
|
|
129
|
-
"Link",
|
|
130
|
-
"currentHref",
|
|
131
|
-
"onNavigate",
|
|
132
|
-
"className",
|
|
133
|
-
"containerClassName"
|
|
134
|
-
]);
|
|
135
|
-
var _b2, _c;
|
|
136
|
-
const content = headerContent[locale];
|
|
137
|
-
const projectLinks = !showProjects ? [] : projects != null ? projects : headerProjects.map((project) => {
|
|
138
|
-
var _a3, _b3, _c2;
|
|
139
|
-
const current = project.key === currentProjectKey;
|
|
140
|
-
return {
|
|
141
|
-
id: project.key,
|
|
142
|
-
label: (_a3 = translations == null ? void 0 : translations.project(`${project.key}.name`)) != null ? _a3 : content.projects[project.key].name,
|
|
143
|
-
description: (_b3 = translations == null ? void 0 : translations.project(`${project.key}.description`)) != null ? _b3 : content.projects[project.key].description,
|
|
144
|
-
href: current ? currentProjectHref || "/" : resolveHref(project.href),
|
|
145
|
-
external: !current && projectsExternal,
|
|
146
|
-
active: current || currentHref === project.href || (currentHref == null ? void 0 : currentHref.startsWith(`${project.href}/`)) || currentHref === resolveHref(project.href),
|
|
147
|
-
icon: /* @__PURE__ */ jsx("span", { className: "naeil-header-project-icon", style: {
|
|
148
|
-
borderColor: `color-mix(in oklch, ${project.accent} 30%, transparent)`,
|
|
149
|
-
backgroundColor: `color-mix(in oklch, ${project.accent} 8%, transparent)`
|
|
150
|
-
}, children: /* @__PURE__ */ jsx("img", { src: `https://naeil.dev/images/${project.icon}.png`, alt: "", width: 24, height: 24 }) }),
|
|
151
|
-
badge: project.status === "coming" ? /* @__PURE__ */ jsx(Badge, { variant: "outline", children: (_c2 = translations == null ? void 0 : translations.project("status.coming")) != null ? _c2 : content.projects.status.coming }) : void 0
|
|
152
|
-
};
|
|
153
|
-
});
|
|
154
|
-
const brandDestination = brandHref != null ? brandHref : resolveHref("/");
|
|
155
|
-
const BrandLink = brandLinkComponent != null ? brandLinkComponent : Link;
|
|
156
|
-
const _a2 = brandLinkProps != null ? brandLinkProps : {}, { onClick: onBrandClick } = _a2, brandProps = __objRest(_a2, ["onClick"]);
|
|
157
|
-
const toolbar = /* @__PURE__ */ jsx(
|
|
158
|
-
"div",
|
|
159
|
-
{
|
|
160
|
-
"data-app-toolbar": true,
|
|
161
|
-
className: "naeil-header-controls",
|
|
162
|
-
"data-naeil-chrome": toolbarSlot === void 0 ? "" : void 0,
|
|
163
|
-
lang: toolbarSlot === void 0 ? locale : void 0,
|
|
164
|
-
children: toolbarSlot !== void 0 ? toolbarSlot : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
165
|
-
/* @__PURE__ */ jsx(NaeilHeaderThemeControl, { locale }),
|
|
166
|
-
onLocaleChange && /* @__PURE__ */ jsx(NaeilHeaderLocaleControl, { locale, onLocaleChange }),
|
|
167
|
-
authSlot && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
168
|
-
/* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: "naeil-header-separator" }),
|
|
169
|
-
authSlot
|
|
170
|
-
] })
|
|
171
|
-
] })
|
|
172
|
-
}
|
|
173
|
-
);
|
|
174
|
-
const logo = /* @__PURE__ */ jsx(Logo, { variant: "horizontal", size: 28, className: "block", label: null });
|
|
175
|
-
const brand = /* @__PURE__ */ jsx(
|
|
176
|
-
BrandLink,
|
|
177
|
-
__spreadProps(__spreadValues({
|
|
178
|
-
href: brandDestination,
|
|
179
|
-
"data-app-brand": true,
|
|
180
|
-
"aria-label": brandSlot == null ? ".naeil" : void 0
|
|
181
|
-
}, brandProps), {
|
|
182
|
-
onClick: (event) => {
|
|
183
|
-
onBrandClick == null ? void 0 : onBrandClick(event);
|
|
184
|
-
onNavigate == null ? void 0 : onNavigate(event, { id: "brand", href: brandDestination, label: ".naeil" });
|
|
185
|
-
},
|
|
186
|
-
children: brandSlot != null ? brandSlot : brandSuffix ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
187
|
-
logo,
|
|
188
|
-
/* @__PURE__ */ jsx("span", { className: "naeil-header-brand-suffix", children: brandSuffix })
|
|
189
|
-
] }) : logo
|
|
190
|
-
})
|
|
191
|
-
);
|
|
192
|
-
return /* @__PURE__ */ jsx(
|
|
193
|
-
Navigation,
|
|
194
|
-
__spreadProps(__spreadValues({}, props), {
|
|
195
|
-
"data-global-header": true,
|
|
196
|
-
"data-naeil-header": true,
|
|
197
|
-
"data-naeil-chrome": "",
|
|
198
|
-
lang: locale,
|
|
199
|
-
"data-naeil-ui-version": uiRelease.version,
|
|
200
|
-
"data-naeil-ui-contract": uiRelease.contractVersion,
|
|
201
|
-
Link,
|
|
202
|
-
currentHref,
|
|
203
|
-
onNavigate,
|
|
204
|
-
brand: statusSlot != null ? /* @__PURE__ */ jsxs("div", { className: "naeil-header-brand-row", children: [
|
|
205
|
-
brand,
|
|
206
|
-
statusSlot
|
|
207
|
-
] }) : brand,
|
|
208
|
-
items: [
|
|
209
|
-
...showProjects ? [{ id: "projects", label: (_b2 = translations == null ? void 0 : translations.projects) != null ? _b2 : content.nav.projects, items: projectLinks, columns: projectLinks.length > 1 ? 2 : 1 }] : [],
|
|
210
|
-
...showBlog ? [{ id: "blog", label: (_c = translations == null ? void 0 : translations.blog) != null ? _c : content.nav.blog, href: resolveHref("/blog"), external: projectsExternal }] : [],
|
|
211
|
-
...appNavigation != null ? appNavigation : [],
|
|
212
|
-
...(subNav != null ? subNav : []).map((item) => __spreadProps(__spreadValues({}, item), { id: item.href }))
|
|
213
|
-
],
|
|
214
|
-
labels: labels != null ? labels : { navigation: content.nav.navigation, menu: content.nav.menu, close: content.nav.closeMenu },
|
|
215
|
-
toolbar,
|
|
216
|
-
mobileToolbar: toolbar,
|
|
217
|
-
className: cn("naeil-header fixed top-0 w-full", className),
|
|
218
|
-
containerClassName: cn("naeil-header-frame", containerClassName)
|
|
219
|
-
})
|
|
220
|
-
);
|
|
28
|
+
function NaeilHeaderLocaleControl(props) {
|
|
29
|
+
return /* @__PURE__ */ jsx(NaeilStandaloneMessages, { locale: props.locale, children: /* @__PURE__ */ jsx(LocaleControl, __spreadValues({}, props)) });
|
|
221
30
|
}
|
|
222
31
|
export {
|
|
223
32
|
NaeilHeader,
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { NaeilHeaderLocale } from './naeil-header-data.js';
|
|
4
|
+
|
|
5
|
+
var naeil = {
|
|
6
|
+
header: {
|
|
7
|
+
nav: {
|
|
8
|
+
home: "Home",
|
|
9
|
+
projects: "Projects",
|
|
10
|
+
blog: "Blog",
|
|
11
|
+
navigation: "Main navigation",
|
|
12
|
+
menu: "Menu",
|
|
13
|
+
closeMenu: "Close menu"
|
|
14
|
+
},
|
|
15
|
+
theme: {
|
|
16
|
+
switchToLight: "Switch to light theme",
|
|
17
|
+
switchToDark: "Switch to dark theme"
|
|
18
|
+
},
|
|
19
|
+
locale: {
|
|
20
|
+
switchLabel: "Language"
|
|
21
|
+
},
|
|
22
|
+
projects: {
|
|
23
|
+
cc: {
|
|
24
|
+
name: "Content Collector",
|
|
25
|
+
description: "Automated content collection from RSS, YouTube, Reddit + AI summarization"
|
|
26
|
+
},
|
|
27
|
+
pkm: {
|
|
28
|
+
name: "PKM",
|
|
29
|
+
description: "Personal knowledge management — document parsing, embeddings, semantic search"
|
|
30
|
+
},
|
|
31
|
+
naeilUi: {
|
|
32
|
+
name: "naeil-ui",
|
|
33
|
+
description: "Minimal design system — OKLCH tokens, Tailwind v4, shadcn"
|
|
34
|
+
},
|
|
35
|
+
sa: {
|
|
36
|
+
name: "Sustainability Analyzer",
|
|
37
|
+
description: "AI-powered ESG report analysis — PDF parsing, qualitative assessment, comparison tables"
|
|
38
|
+
},
|
|
39
|
+
babyAgent: {
|
|
40
|
+
name: "Baby Agent",
|
|
41
|
+
description: "Parenting AI agent — LINE-based Q&A, records, reminders"
|
|
42
|
+
},
|
|
43
|
+
status: {
|
|
44
|
+
active: "Active",
|
|
45
|
+
coming: "Coming Soon"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
account: {
|
|
50
|
+
menu: "Account menu",
|
|
51
|
+
account: "Account",
|
|
52
|
+
login: "Log in",
|
|
53
|
+
logout: "Log out",
|
|
54
|
+
busy: "Logging out…"
|
|
55
|
+
},
|
|
56
|
+
footer: {
|
|
57
|
+
navigation: "Navigation",
|
|
58
|
+
projects: "Projects",
|
|
59
|
+
blog: "Blog",
|
|
60
|
+
social: "Social",
|
|
61
|
+
description: "Tomorrow starts here."
|
|
62
|
+
},
|
|
63
|
+
locale: {
|
|
64
|
+
names: {
|
|
65
|
+
en: "English",
|
|
66
|
+
ko: "한국어",
|
|
67
|
+
ja: "日本語"
|
|
68
|
+
},
|
|
69
|
+
pending: "Changing language…",
|
|
70
|
+
failed: "The language could not be changed. Your work is still here.",
|
|
71
|
+
retry: "Try again",
|
|
72
|
+
errors: {
|
|
73
|
+
badRequest: "This address is not valid.",
|
|
74
|
+
notFound: "Page not found.",
|
|
75
|
+
unauthenticated: "Sign in to continue.",
|
|
76
|
+
forbidden: "You do not have access to this page.",
|
|
77
|
+
unavailable: "The service is temporarily unavailable. Please try again."
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
var en = {
|
|
82
|
+
naeil: naeil
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
type NaeilCommonMessages = typeof en.naeil;
|
|
86
|
+
/** React-only bridge: the locale runtime supplies its already selected JSON. */
|
|
87
|
+
declare function NaeilMessagesProvider({ locale, messages, children }: {
|
|
88
|
+
locale: NaeilHeaderLocale;
|
|
89
|
+
messages: NaeilCommonMessages;
|
|
90
|
+
children: ReactNode;
|
|
91
|
+
}): react_jsx_runtime.JSX.Element;
|
|
92
|
+
declare function useNaeilMessages(locale: NaeilHeaderLocale): NaeilCommonMessages;
|
|
93
|
+
|
|
94
|
+
export { type NaeilCommonMessages, NaeilMessagesProvider, useNaeilMessages };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext } from "react";
|
|
4
|
+
const NaeilMessages = createContext(null);
|
|
5
|
+
function NaeilMessagesProvider({ locale, messages, children }) {
|
|
6
|
+
return /* @__PURE__ */ jsx(NaeilMessages.Provider, { value: { locale, messages }, children });
|
|
7
|
+
}
|
|
8
|
+
function useNaeilMessages(locale) {
|
|
9
|
+
const value = useContext(NaeilMessages);
|
|
10
|
+
if (!value || value.locale !== locale) throw new Error("Naeil chrome requires messages for its current locale");
|
|
11
|
+
return value.messages;
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
NaeilMessagesProvider,
|
|
15
|
+
useNaeilMessages
|
|
16
|
+
};
|