@naeil/ui 0.12.0 → 0.13.1
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 +38 -3
- package/DESIGN.md +10 -2
- package/README.md +13 -11
- package/THIRD_PARTY_NOTICES.md +4 -2
- package/dist/{chunk-XLISHUJZ.js → chunk-ESTQITQO.js} +68 -8
- package/dist/{chunk-DBE7R4MR.js → chunk-L25A4OKY.js} +1 -1
- package/dist/{chunk-KPE4KKYM.js → chunk-Y5LW3ADW.js} +24 -15
- package/dist/components/index.d.ts +3 -3
- package/dist/components/index.js +4 -4
- package/dist/components/naeil-footer.d.ts +2 -2
- package/dist/components/naeil-footer.js +1 -1
- package/dist/components/naeil-header.d.ts +23 -8
- package/dist/components/naeil-header.js +7 -5
- package/dist/components/ui/index.d.ts +2 -2
- package/dist/components/ui/index.js +6 -6
- package/dist/lib/ui-release.d.ts +1 -1
- package/dist/lib/ui-release.js +1 -1
- package/dist/lib/utils.js +1 -7
- package/dist/naeil-locale/checker.js +1 -1
- package/dist/naeil-locale/chrome.d.ts +25 -8
- package/dist/naeil-locale/chrome.js +91 -22
- package/dist/naeil-locale/{chunk-4U64K4J3.js → chunk-24IL53QO.js} +1 -1
- package/dist/naeil-locale/{chunk-U65OQHZY.js → chunk-WT6QXR7O.js} +14 -8
- package/dist/naeil-locale/client.js +45 -15
- package/dist/naeil-locale/index.js +1 -1
- package/dist/naeil-locale/messages.js +2 -2
- package/dist/naeil-locale/server.js +6 -6
- package/dist/{navigation-D8N1tMTu.d.ts → navigation-CXZapKac.d.ts} +3 -1
- package/dist/{site-footer-s113FZgC.d.ts → site-footer-C4jgkGDU.d.ts} +1 -1
- package/dist/source/components/naeil-header-core.d.ts +23 -8
- package/dist/source/components/naeil-header-core.js +66 -6
- package/dist/source/components/naeil-header.d.ts +6 -4
- package/dist/source/components/naeil-header.js +4 -2
- package/dist/source/components/typography.d.ts +1 -1
- package/dist/source/components/typography.js +1 -1
- package/dist/source/components/ui/button.js +7 -7
- package/dist/source/components/ui/card.js +1 -1
- package/dist/source/components/ui/dialog.js +2 -2
- package/dist/source/components/ui/navigation.d.ts +3 -1
- package/dist/source/components/ui/navigation.js +17 -8
- package/dist/source/components/ui/sonner.js +2 -2
- package/dist/source/lib/ui-release.d.ts +1 -1
- package/dist/source/lib/ui-release.js +1 -1
- package/docs/components/README.md +3 -1
- package/docs/components/application-layout.md +23 -27
- package/docs/components/avatar.md +1 -1
- package/docs/components/badge.md +3 -1
- package/docs/components/button.md +7 -1
- package/docs/components/card.md +5 -1
- package/docs/components/checkbox.md +1 -1
- package/docs/components/common.md +16 -1
- package/docs/components/dialog.md +6 -2
- package/docs/components/dropdown-menu.md +1 -1
- package/docs/components/input.md +1 -1
- package/docs/components/naeil-footer.md +1 -1
- package/docs/components/naeil-header.md +41 -12
- package/docs/components/naeil-locale.md +36 -0
- package/docs/components/navigation.md +10 -4
- package/docs/components/select.md +1 -1
- package/docs/components/sheet.md +1 -1
- package/docs/components/sonner.md +7 -1
- package/docs/components/switch.md +1 -1
- package/docs/components/tabs.md +1 -1
- package/docs/components/textarea.md +1 -1
- package/docs/design/public-ui-support.md +3 -1
- package/docs/design/v2-migration.md +11 -6
- package/docs/package-release.md +36 -12
- package/package.json +7 -10
- package/src/styles/components.css +29 -0
- package/src/styles/globals.css +6 -2
- package/src/styles/theme.css +5 -0
- package/licenses/Nunito-Sans-OFL.txt +0 -93
- package/licenses/React-MIT.txt +0 -21
- package/licenses/Storybook-MIT.txt +0 -21
- package/licenses/popper-MIT.txt +0 -25
- package/licenses/store2-MIT.txt +0 -22
- package/licenses/toggle-selection-MIT.txt +0 -21
|
@@ -13,6 +13,10 @@ import { NextIntlClientProvider } from "next-intl";
|
|
|
13
13
|
|
|
14
14
|
// src/naeil-locale/routing.ts
|
|
15
15
|
var naeilLocales = ["en", "ko", "ja"];
|
|
16
|
+
function escapeRegExp(value) {
|
|
17
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
18
|
+
}
|
|
19
|
+
var localePrefix = new RegExp(`^/(?:${naeilLocales.map(escapeRegExp).join("|")})(?:/|$)`);
|
|
16
20
|
function isNaeilLocale(value) {
|
|
17
21
|
return typeof value === "string" && naeilLocales.includes(value);
|
|
18
22
|
}
|
|
@@ -27,7 +31,7 @@ var origins = {
|
|
|
27
31
|
estimate: "https://abestimate.naeil.dev"
|
|
28
32
|
};
|
|
29
33
|
var protocolPrefixes = ["/api", "/auth", "/_next", "/_vercel", "/.well-known", "/health", "/invite", "/return", "/webhook", "/images", "/fonts"];
|
|
30
|
-
var protocolFiles = ["/favicon.ico", "/icon.svg", "/apple-icon.png", "/robots.txt", "/sitemap.xml"];
|
|
34
|
+
var protocolFiles = ["/favicon.ico", "/favicon.svg", "/icon.svg", "/apple-icon.png", "/robots.txt", "/sitemap.xml"];
|
|
31
35
|
function defineLocaleService(service) {
|
|
32
36
|
var _a, _b, _c, _d;
|
|
33
37
|
if (origins[service.id] !== service.origin) throw new Error("Service origin must match the exact owned origin");
|
|
@@ -35,7 +39,7 @@ function defineLocaleService(service) {
|
|
|
35
39
|
if (!paths.length || new Set(paths).size !== paths.length) throw new Error("Route inventory is empty or duplicated");
|
|
36
40
|
for (const path of paths) {
|
|
37
41
|
if (!/^\/(?:[A-Za-z0-9._~-]+|\[[A-Za-z][A-Za-z0-9_]*\])(?:\/(?:[A-Za-z0-9._~-]+|\[[A-Za-z][A-Za-z0-9_]*\]))*$/.test(path) && path !== "/") throw new Error(`Invalid registered route: ${path}`);
|
|
38
|
-
if (
|
|
42
|
+
if (localePrefix.test(path) || isProtocolPath(path, service) && !((_a = service.uiProtocolExceptions) == null ? void 0 : _a.includes(path)) || path.split("/").some((segment) => segment === "." || segment === "..")) throw new Error(`Locale/protocol path cannot be a UI route: ${path}`);
|
|
39
43
|
}
|
|
40
44
|
for (const exception of (_b = service.uiProtocolExceptions) != null ? _b : []) if (exception.includes("[") || !paths.includes(exception)) throw new Error("Protocol UI exceptions must be exact registered routes");
|
|
41
45
|
return Object.freeze(__spreadProps(__spreadValues({}, service), { routes: Object.freeze(service.routes.map((route) => typeof route === "string" ? route : Object.freeze(__spreadValues({}, route)))), protocolPrefixes: Object.freeze([...(_c = service.protocolPrefixes) != null ? _c : []]), uiProtocolExceptions: Object.freeze([...(_d = service.uiProtocolExceptions) != null ? _d : []]) }));
|
|
@@ -71,7 +75,7 @@ function invalid(reason, status = 404, locale) {
|
|
|
71
75
|
return __spreadValues({ kind: "invalid", status, reason }, locale ? { locale } : {});
|
|
72
76
|
}
|
|
73
77
|
function splitInput(input, origin) {
|
|
74
|
-
if (!input || /[\u0000-\u0020\u007f
|
|
78
|
+
if (!input || /[\u0000-\u0020\u007f]/.test(input)) return;
|
|
75
79
|
let path = input;
|
|
76
80
|
if (!path.startsWith("/")) {
|
|
77
81
|
if (!path.startsWith(origin + "/") && path !== origin) return;
|
|
@@ -84,12 +88,14 @@ function splitInput(input, origin) {
|
|
|
84
88
|
const queryAt = withoutHash.indexOf("?");
|
|
85
89
|
return { pathname: queryAt < 0 ? withoutHash : withoutHash.slice(0, queryAt), search: queryAt < 0 ? "" : withoutHash.slice(queryAt), hash };
|
|
86
90
|
}
|
|
87
|
-
function safePath(path) {
|
|
91
|
+
function safePath(path, service) {
|
|
92
|
+
var _a;
|
|
88
93
|
if (!path.startsWith("/") || path.includes("//")) return false;
|
|
94
|
+
const reserved = /* @__PURE__ */ new Set([...naeilLocales, ...[...protocolPrefixes, ...(_a = service.protocolPrefixes) != null ? _a : []].flatMap((prefix) => prefix.split("/").filter(Boolean))]);
|
|
89
95
|
return path.split("/").every((segment) => {
|
|
90
96
|
try {
|
|
91
97
|
const decoded = decodeURIComponent(segment);
|
|
92
|
-
return !/[\u0000-\u001f\u007f/\\%?#]/.test(decoded) && decoded !== "." && decoded !== ".." && (
|
|
98
|
+
return !/[\u0000-\u001f\u007f/\\%?#]/.test(decoded) && decoded !== "." && decoded !== ".." && (!reserved.has(decoded) || decoded === segment);
|
|
93
99
|
} catch (e) {
|
|
94
100
|
return false;
|
|
95
101
|
}
|
|
@@ -112,7 +118,7 @@ function resolveLocaleUrl(inputService, input) {
|
|
|
112
118
|
var _a, _b;
|
|
113
119
|
const service = getLocaleService(inputService);
|
|
114
120
|
const parts = splitInput(input, service.origin);
|
|
115
|
-
if (!parts || !safePath(parts.pathname)) return invalid("Malformed or encoded path");
|
|
121
|
+
if (!parts || !safePath(parts.pathname, service)) return invalid("Malformed or encoded path");
|
|
116
122
|
const rawPathname = parts.pathname;
|
|
117
123
|
const pathname = rawPathname !== "/" && rawPathname.endsWith("/") ? rawPathname.slice(0, -1) : rawPathname;
|
|
118
124
|
if (isProtocolPath(pathname, service) && !((_a = service.uiProtocolExceptions) == null ? void 0 : _a.includes(pathname))) return { kind: "protocol", pathname };
|
|
@@ -120,7 +126,7 @@ function resolveLocaleUrl(inputService, input) {
|
|
|
120
126
|
const explicit = isNaeilLocale(segments[1]);
|
|
121
127
|
const pathLocale = explicit ? segments[1] : void 0;
|
|
122
128
|
const logicalPath = explicit ? "/" + segments.slice(2).join("/") : pathname;
|
|
123
|
-
if (
|
|
129
|
+
if (localePrefix.test(logicalPath) || isProtocolPath(logicalPath, service) && !((_b = service.uiProtocolExceptions) == null ? void 0 : _b.includes(logicalPath))) return invalid("Nested locale or localized protocol path", 404, pathLocale);
|
|
124
130
|
const route = matchRoute(service, logicalPath);
|
|
125
131
|
if (!route) return invalid("Unregistered UI route", 404, pathLocale);
|
|
126
132
|
const legacy = service.id !== "main";
|
|
@@ -136,7 +142,7 @@ function localePath(inputService, unlocalizedRoute, locale) {
|
|
|
136
142
|
assertLocale(locale);
|
|
137
143
|
const service = getLocaleService(inputService);
|
|
138
144
|
const parts = splitInput(unlocalizedRoute, service.origin);
|
|
139
|
-
if (!parts ||
|
|
145
|
+
if (!parts || localePrefix.test(parts.pathname)) throw new Error("localePath requires an unlocalized route");
|
|
140
146
|
const result = resolveLocaleUrl(service, parts.pathname);
|
|
141
147
|
if (result.kind !== "ui") throw new Error("Unregistered UI destination");
|
|
142
148
|
return prefixPath(result.logicalPath, locale) + (service.id === "main" ? parts.search : stripLegacyLang(parts.search)) + parts.hash;
|
|
@@ -236,6 +242,7 @@ function NaeilLocaleController({ service, children, preferenceWritesEnabled = fa
|
|
|
236
242
|
const [intent, setIntent] = useState();
|
|
237
243
|
const [error, setError] = useState();
|
|
238
244
|
const lastRequest = useRef(void 0);
|
|
245
|
+
const timedOutIntent = useRef(void 0);
|
|
239
246
|
const focus = useRef(void 0);
|
|
240
247
|
const timer = useRef(void 0);
|
|
241
248
|
const guards = useRef(/* @__PURE__ */ new Set());
|
|
@@ -245,6 +252,7 @@ function NaeilLocaleController({ service, children, preferenceWritesEnabled = fa
|
|
|
245
252
|
}, []);
|
|
246
253
|
const cancel = useCallback(() => {
|
|
247
254
|
gate.cancel();
|
|
255
|
+
timedOutIntent.current = void 0;
|
|
248
256
|
clearTimer();
|
|
249
257
|
setIntent(void 0);
|
|
250
258
|
setError(void 0);
|
|
@@ -253,6 +261,8 @@ function NaeilLocaleController({ service, children, preferenceWritesEnabled = fa
|
|
|
253
261
|
const fail = useCallback((token, reason) => {
|
|
254
262
|
var _a;
|
|
255
263
|
if (((_a = gate.current()) == null ? void 0 : _a.token) !== token) return;
|
|
264
|
+
timedOutIntent.current = reason === "timeout" ? gate.current() : void 0;
|
|
265
|
+
focus.current = void 0;
|
|
256
266
|
gate.cancel(token);
|
|
257
267
|
clearTimer();
|
|
258
268
|
setIntent(void 0);
|
|
@@ -262,12 +272,17 @@ function NaeilLocaleController({ service, children, preferenceWritesEnabled = fa
|
|
|
262
272
|
var _a;
|
|
263
273
|
const locale = assertLocale(language);
|
|
264
274
|
if (gate.current()) return false;
|
|
275
|
+
lastRequest.current = { locale, options: options ? __spreadValues({}, options) : void 0 };
|
|
276
|
+
timedOutIntent.current = void 0;
|
|
265
277
|
const current = resolveLocaleUrl(service, browserHref());
|
|
266
278
|
if (current.kind !== "ui") {
|
|
267
279
|
setError("unsupported-route");
|
|
268
280
|
return false;
|
|
269
281
|
}
|
|
270
|
-
if (current.locale === locale && !(options == null ? void 0 : options.route) && !(options == null ? void 0 : options.href))
|
|
282
|
+
if (current.locale === locale && !(options == null ? void 0 : options.route) && !(options == null ? void 0 : options.href)) {
|
|
283
|
+
setError(void 0);
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
271
286
|
const suffix = current.canonicalPath.slice(localePath(service, current.logicalPath, current.locale).length);
|
|
272
287
|
let href;
|
|
273
288
|
try {
|
|
@@ -283,7 +298,6 @@ function NaeilLocaleController({ service, children, preferenceWritesEnabled = fa
|
|
|
283
298
|
}
|
|
284
299
|
const request = gate.begin(href, locale);
|
|
285
300
|
if (!request) return false;
|
|
286
|
-
lastRequest.current = { locale, options };
|
|
287
301
|
focus.current = captureFocus();
|
|
288
302
|
setIntent(request);
|
|
289
303
|
setError(void 0);
|
|
@@ -296,11 +310,26 @@ function NaeilLocaleController({ service, children, preferenceWritesEnabled = fa
|
|
|
296
310
|
return false;
|
|
297
311
|
}
|
|
298
312
|
}, [service, gate, router, fail, transitionTimeoutMs]);
|
|
299
|
-
const retry = useCallback(() =>
|
|
313
|
+
const retry = useCallback(() => {
|
|
314
|
+
const request = lastRequest.current;
|
|
315
|
+
if (!request || gate.current()) return false;
|
|
316
|
+
const current = resolveLocaleUrl(service, browserHref());
|
|
317
|
+
if (current.kind === "ui" && current.locale === request.locale) {
|
|
318
|
+
setError(void 0);
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
return changeLocale(request.locale, request.options);
|
|
322
|
+
}, [service, gate, changeLocale]);
|
|
300
323
|
const arrive = useCallback((token, locale, committedPathname) => {
|
|
301
|
-
if (
|
|
302
|
-
|
|
324
|
+
if (committedPathname !== window.location.pathname) return;
|
|
325
|
+
let committed = token === void 0 ? void 0 : gate.arrive(token, browserHref(), locale);
|
|
326
|
+
const late = timedOutIntent.current;
|
|
327
|
+
if (!committed && !gate.current() && late && (token === void 0 || token === late.token)) {
|
|
328
|
+
const current = resolveLocaleUrl(service, browserHref());
|
|
329
|
+
if (late.locale === locale && current.kind === "ui" && !current.alias && current.locale === locale && current.canonicalPath === late.href) committed = late;
|
|
330
|
+
}
|
|
303
331
|
if (!committed) return;
|
|
332
|
+
timedOutIntent.current = void 0;
|
|
304
333
|
clearTimer();
|
|
305
334
|
setIntent(void 0);
|
|
306
335
|
setError(void 0);
|
|
@@ -310,7 +339,7 @@ function NaeilLocaleController({ service, children, preferenceWritesEnabled = fa
|
|
|
310
339
|
const savedFocus = focus.current;
|
|
311
340
|
focus.current = void 0;
|
|
312
341
|
requestAnimationFrame(() => restoreFocus(savedFocus));
|
|
313
|
-
}, [gate, clearTimer, preferenceWritesEnabled]);
|
|
342
|
+
}, [service, gate, clearTimer, preferenceWritesEnabled]);
|
|
314
343
|
const registerDepartureGuard = useCallback((guard) => {
|
|
315
344
|
guards.current.add(guard);
|
|
316
345
|
return () => {
|
|
@@ -341,7 +370,8 @@ function NaeilLocaleController({ service, children, preferenceWritesEnabled = fa
|
|
|
341
370
|
};
|
|
342
371
|
}, [cancel, gate, clearTimer]);
|
|
343
372
|
useEffect(() => {
|
|
344
|
-
|
|
373
|
+
var _a;
|
|
374
|
+
const pending = (_a = gate.current()) != null ? _a : timedOutIntent.current;
|
|
345
375
|
if (!pending) return;
|
|
346
376
|
const target = pending.href.split(/[?#]/, 1)[0];
|
|
347
377
|
const current = resolveLocaleUrl(service, pathname != null ? pathname : "/");
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
loadSharedMessages,
|
|
4
4
|
mergeLocaleMessages,
|
|
5
5
|
recoverMissingMessages
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-24IL53QO.js";
|
|
7
|
+
import "./chunk-WT6QXR7O.js";
|
|
8
8
|
import "./chunk-N3ETBM74.js";
|
|
9
9
|
export {
|
|
10
10
|
createLocaleMessageLoader,
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
createLocaleMessageLoader,
|
|
3
3
|
loadSharedMessages,
|
|
4
4
|
recoverMissingMessages
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-24IL53QO.js";
|
|
6
6
|
import {
|
|
7
7
|
assertLocale,
|
|
8
8
|
getLocaleService,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
naeilLocales,
|
|
12
12
|
naeilRouting,
|
|
13
13
|
resolveLocaleUrl
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-WT6QXR7O.js";
|
|
15
15
|
import "./chunk-N3ETBM74.js";
|
|
16
16
|
|
|
17
17
|
// src/naeil-locale/server.ts
|
|
@@ -62,10 +62,10 @@ function stripMarkers(headers) {
|
|
|
62
62
|
return sanitized;
|
|
63
63
|
}
|
|
64
64
|
function sanitizeProtocolPassThrough(response, requestHeaders) {
|
|
65
|
-
var _a;
|
|
66
65
|
if (response.headers.get("x-middleware-next") !== "1" && !response.headers.has("x-middleware-rewrite")) return response;
|
|
67
|
-
const
|
|
68
|
-
|
|
66
|
+
const overrides = response.headers.get("x-middleware-override-headers");
|
|
67
|
+
const forwarded = new Headers(overrides === null ? requestHeaders : void 0);
|
|
68
|
+
for (const key of (overrides != null ? overrides : "").split(",").map((name) => name.trim())) {
|
|
69
69
|
if (!key) continue;
|
|
70
70
|
const value = response.headers.get(`x-middleware-request-${key}`);
|
|
71
71
|
if (value !== null) forwarded.set(key, value);
|
|
@@ -79,7 +79,7 @@ function sanitizeProtocolPassThrough(response, requestHeaders) {
|
|
|
79
79
|
names.push(key);
|
|
80
80
|
response.headers.set(`x-middleware-request-${key}`, value);
|
|
81
81
|
}
|
|
82
|
-
response.headers.set("x-middleware-override-headers", names.join(","));
|
|
82
|
+
response.headers.set("x-middleware-override-headers", [...names, ...privateHeaders].join(","));
|
|
83
83
|
return response;
|
|
84
84
|
}
|
|
85
85
|
function markPrivate(response) {
|
|
@@ -25,6 +25,8 @@ interface NavigationGroup {
|
|
|
25
25
|
}
|
|
26
26
|
type NavigationItem = NavigationLink | NavigationGroup;
|
|
27
27
|
interface NavigationProps extends Omit<React.ComponentPropsWithoutRef<"header">, "children" | "onSelect"> {
|
|
28
|
+
/** Omit empty landmarks and dismiss toolbar-only sheets on desktop crossing. */
|
|
29
|
+
omitEmptyNavigation?: boolean;
|
|
28
30
|
brand: React.ReactNode;
|
|
29
31
|
items: NavigationItem[];
|
|
30
32
|
/** Translated landmark/dialog/close labels are supplied by the application. */
|
|
@@ -45,6 +47,6 @@ interface NavigationProps extends Omit<React.ComponentPropsWithoutRef<"header">,
|
|
|
45
47
|
/** Preserve modified clicks; applications may preventDefault for client routing/guards. */
|
|
46
48
|
onNavigate?: (event: React.MouseEvent<HTMLAnchorElement>, item: NavigationLink) => void;
|
|
47
49
|
}
|
|
48
|
-
declare function Navigation({ brand, items, labels, Link, currentHref, toolbar, mobileToolbar, mobileFooter, mobileOpen: controlledOpen, onMobileOpenChange, containerClassName, onNavigate, className, ...props }: NavigationProps): react_jsx_runtime.JSX.Element;
|
|
50
|
+
declare function Navigation({ brand, items, labels, Link, currentHref, toolbar, mobileToolbar, mobileFooter, omitEmptyNavigation, mobileOpen: controlledOpen, onMobileOpenChange, containerClassName, onNavigate, className, ...props }: NavigationProps): react_jsx_runtime.JSX.Element;
|
|
49
51
|
|
|
50
52
|
export { type NavigationLink as N, type NavigationProps as a, type NavigationLinkComponent as b, type NavigationItem as c, type NavigationLinkProps as d, Navigation as e, type NavigationGroup as f };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import { N as NavigationLink, b as NavigationLinkComponent, a as NavigationProps } from './navigation-
|
|
3
|
+
import { N as NavigationLink, b as NavigationLinkComponent, a as NavigationProps } from './navigation-CXZapKac.js';
|
|
4
4
|
|
|
5
5
|
interface SiteFooterProps extends React.ComponentPropsWithoutRef<"footer"> {
|
|
6
6
|
brand?: React.ReactNode;
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ReactNode } from 'react';
|
|
2
|
+
import { ReactNode, JSX } from 'react';
|
|
3
3
|
import { NavigationProps, NavigationItem, NavigationLinkProps, NavigationLink, NavigationLinkComponent } from './ui/navigation.js';
|
|
4
4
|
import { NaeilHeaderLocale } from './naeil-header-data.js';
|
|
5
5
|
export { NaeilHeaderAccount, NaeilHeaderAccountControl, NaeilHeaderAccountControlProps } from './naeil-header-account-core.js';
|
|
6
6
|
|
|
7
7
|
interface NaeilHeaderProps extends Omit<NavigationProps, "brand" | "items" | "toolbar" | "mobileToolbar" | "labels"> {
|
|
8
|
+
service?: undefined;
|
|
8
9
|
locale: NaeilHeaderLocale;
|
|
9
10
|
/** Resolve canonical unlocalized paths. Defaults to the official localized site. */
|
|
10
11
|
resolveHref?: (path: string) => string;
|
|
11
12
|
brandHref?: string;
|
|
13
|
+
/** @deprecated Owned services must use service; retained for compatibility. */
|
|
12
14
|
brandSlot?: ReactNode;
|
|
13
|
-
/**
|
|
15
|
+
/** @deprecated Owned services must use service; retained for compatibility. Ignored with brandSlot. */
|
|
14
16
|
brandSuffix?: string;
|
|
15
|
-
/**
|
|
17
|
+
/** @deprecated Owned services must use service with no indicator; retained for compatibility. */
|
|
16
18
|
statusSlot?: ReactNode;
|
|
17
19
|
/** Product menu data, after catalog/blog and before flat subNav links. */
|
|
18
20
|
appNavigation?: NavigationItem[];
|
|
@@ -33,17 +35,32 @@ interface NaeilHeaderProps extends Omit<NavigationProps, "brand" | "items" | "to
|
|
|
33
35
|
};
|
|
34
36
|
showProjects?: boolean;
|
|
35
37
|
showBlog?: boolean;
|
|
38
|
+
/** @deprecated Owned services must use service and appNavigation; retained for compatibility. */
|
|
36
39
|
subNav?: Array<{
|
|
37
40
|
label: string;
|
|
38
41
|
href: string;
|
|
39
42
|
}>;
|
|
40
43
|
currentProjectKey?: string;
|
|
41
44
|
currentProjectHref?: string;
|
|
42
|
-
/**
|
|
45
|
+
/** @deprecated Owned services must use service and authSlot; retained for compatibility. */
|
|
43
46
|
toolbarSlot?: ReactNode;
|
|
44
|
-
/**
|
|
47
|
+
/** @deprecated Owned services must use service and Link; retained for compatibility. */
|
|
45
48
|
brandLinkComponent?: NavigationLinkComponent;
|
|
46
49
|
}
|
|
50
|
+
/** Canonical owned-service identifiers; their spelling is the visible brand suffix. */
|
|
51
|
+
declare const naeilServices: readonly ["abstorm", "home", "estimate", "jev"];
|
|
52
|
+
type NaeilService = typeof naeilServices[number];
|
|
53
|
+
declare const serviceCompatibilityProps: readonly ["brandSuffix", "statusSlot", "brandSlot", "toolbarSlot", "subNav", "brandLinkComponent", "projects", "projectsExternal", "showProjects", "showBlog", "translations", "className", "containerClassName", "style", "brandLinkProps", "mobileFooter", "omitEmptyNavigation"];
|
|
54
|
+
type ServiceCompatibilityProp = typeof serviceCompatibilityProps[number];
|
|
55
|
+
/** Strict owned-service props; the legacy interface remains independently extensible. */
|
|
56
|
+
type NaeilServiceHeaderProps = Omit<NaeilHeaderProps, ServiceCompatibilityProp | "service"> & {
|
|
57
|
+
service: NaeilService;
|
|
58
|
+
} & {
|
|
59
|
+
[Prop in ServiceCompatibilityProp]?: never;
|
|
60
|
+
};
|
|
61
|
+
/** Opt into the owned-service contract without changing the legacy composition. */
|
|
62
|
+
declare function NaeilHeader(props: NaeilServiceHeaderProps): JSX.Element;
|
|
63
|
+
declare function NaeilHeader(props: NaeilHeaderProps): JSX.Element;
|
|
47
64
|
/** The actual header theme control; reads only the consumer's theme provider. */
|
|
48
65
|
declare function NaeilHeaderThemeControl({ locale }: {
|
|
49
66
|
locale: NaeilHeaderLocale;
|
|
@@ -53,7 +70,5 @@ declare function NaeilHeaderLocaleControl({ locale, onLocaleChange }: {
|
|
|
53
70
|
locale: NaeilHeaderLocale;
|
|
54
71
|
onLocaleChange: (locale: NaeilHeaderLocale) => void;
|
|
55
72
|
}): 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
73
|
|
|
59
|
-
export { NaeilHeader, NaeilHeaderLocale, NaeilHeaderLocaleControl, type NaeilHeaderProps, NaeilHeaderThemeControl };
|
|
74
|
+
export { NaeilHeader, NaeilHeaderLocale, NaeilHeaderLocaleControl, type NaeilHeaderProps, NaeilHeaderThemeControl, type NaeilService, type NaeilServiceHeaderProps, naeilServices };
|
|
@@ -44,6 +44,58 @@ import { uiRelease } from "../lib/ui-release.js";
|
|
|
44
44
|
import { headerLocales, headerProjects } from "./naeil-header-data.js";
|
|
45
45
|
import { useNaeilMessages } from "./naeil-messages-context.js";
|
|
46
46
|
import { NaeilHeaderAccountControl } from "./naeil-header-account-core.js";
|
|
47
|
+
const naeilServices = Object.freeze(["abstorm", "home", "estimate", "jev"]);
|
|
48
|
+
const serviceCompatibilityProps = [
|
|
49
|
+
"brandSuffix",
|
|
50
|
+
"statusSlot",
|
|
51
|
+
"brandSlot",
|
|
52
|
+
"toolbarSlot",
|
|
53
|
+
"subNav",
|
|
54
|
+
"brandLinkComponent",
|
|
55
|
+
"projects",
|
|
56
|
+
"projectsExternal",
|
|
57
|
+
"showProjects",
|
|
58
|
+
"showBlog",
|
|
59
|
+
"translations",
|
|
60
|
+
"className",
|
|
61
|
+
"containerClassName",
|
|
62
|
+
"style",
|
|
63
|
+
"brandLinkProps",
|
|
64
|
+
"mobileFooter",
|
|
65
|
+
"omitEmptyNavigation"
|
|
66
|
+
];
|
|
67
|
+
const warnedServiceProps = /* @__PURE__ */ new Set();
|
|
68
|
+
function isDevelopment() {
|
|
69
|
+
try {
|
|
70
|
+
return process.env.NODE_ENV === "development";
|
|
71
|
+
} catch (e) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function warnServiceProp(name, message) {
|
|
76
|
+
if (!isDevelopment() || warnedServiceProps.has(name)) return;
|
|
77
|
+
warnedServiceProps.add(name);
|
|
78
|
+
console.warn(message);
|
|
79
|
+
}
|
|
80
|
+
function isNaeilService(value) {
|
|
81
|
+
return naeilServices.includes(value);
|
|
82
|
+
}
|
|
83
|
+
function NaeilHeader(input) {
|
|
84
|
+
if (input.service === void 0) return /* @__PURE__ */ jsx(HeaderComposition, __spreadValues({}, input));
|
|
85
|
+
if (!isNaeilService(input.service)) {
|
|
86
|
+
warnServiceProp("service", "NaeilHeader: invalid service; rendering the legacy profile.");
|
|
87
|
+
const legacy = __spreadProps(__spreadValues({}, input), { service: void 0 });
|
|
88
|
+
delete legacy.service;
|
|
89
|
+
return /* @__PURE__ */ jsx(HeaderComposition, __spreadValues({}, legacy));
|
|
90
|
+
}
|
|
91
|
+
const props = __spreadValues({}, input);
|
|
92
|
+
for (const name of Object.keys(props)) {
|
|
93
|
+
if (!serviceCompatibilityProps.includes(name) && name !== "data-slot" && name !== "data-global-header" && !name.startsWith("data-naeil-")) continue;
|
|
94
|
+
delete props[name];
|
|
95
|
+
warnServiceProp(name, `NaeilHeader: service profile ignores ${name}; use the shared service composition.`);
|
|
96
|
+
}
|
|
97
|
+
return /* @__PURE__ */ jsx(HeaderComposition, __spreadProps(__spreadValues({}, props), { service: input.service }));
|
|
98
|
+
}
|
|
47
99
|
const subscribe = () => () => {
|
|
48
100
|
};
|
|
49
101
|
function NaeilHeaderThemeControl({ locale }) {
|
|
@@ -80,8 +132,9 @@ function NaeilHeaderLocaleControl({ locale, onLocaleChange }) {
|
|
|
80
132
|
] });
|
|
81
133
|
}
|
|
82
134
|
const NativeLink = (props) => /* @__PURE__ */ jsx("a", __spreadValues({}, props));
|
|
83
|
-
function
|
|
135
|
+
function HeaderComposition(_a) {
|
|
84
136
|
var _b = _a, {
|
|
137
|
+
service,
|
|
85
138
|
locale,
|
|
86
139
|
resolveHref = (path) => `https://naeil.dev/${locale}${path === "/" ? "" : path}`,
|
|
87
140
|
brandHref,
|
|
@@ -109,6 +162,7 @@ function NaeilHeader(_a) {
|
|
|
109
162
|
className,
|
|
110
163
|
containerClassName
|
|
111
164
|
} = _b, props = __objRest(_b, [
|
|
165
|
+
"service",
|
|
112
166
|
"locale",
|
|
113
167
|
"resolveHref",
|
|
114
168
|
"brandHref",
|
|
@@ -137,6 +191,11 @@ function NaeilHeader(_a) {
|
|
|
137
191
|
"containerClassName"
|
|
138
192
|
]);
|
|
139
193
|
var _b2, _c;
|
|
194
|
+
if (service) {
|
|
195
|
+
brandSuffix = service;
|
|
196
|
+
showProjects = false;
|
|
197
|
+
showBlog = false;
|
|
198
|
+
}
|
|
140
199
|
const content = useNaeilMessages(locale).header;
|
|
141
200
|
const projectLinks = !showProjects ? [] : projects != null ? projects : headerProjects.map((project) => {
|
|
142
201
|
var _a3, _b3, _c2;
|
|
@@ -155,7 +214,7 @@ function NaeilHeader(_a) {
|
|
|
155
214
|
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
215
|
};
|
|
157
216
|
});
|
|
158
|
-
const brandDestination = brandHref != null ? brandHref : resolveHref("/");
|
|
217
|
+
const brandDestination = brandHref != null ? brandHref : service ? "/" : resolveHref("/");
|
|
159
218
|
const BrandLink = brandLinkComponent != null ? brandLinkComponent : Link;
|
|
160
219
|
const _a2 = brandLinkProps != null ? brandLinkProps : {}, { onClick: onBrandClick } = _a2, brandProps = __objRest(_a2, ["onClick"]);
|
|
161
220
|
const toolbar = /* @__PURE__ */ jsx(
|
|
@@ -181,11 +240,11 @@ function NaeilHeader(_a) {
|
|
|
181
240
|
__spreadProps(__spreadValues({
|
|
182
241
|
href: brandDestination,
|
|
183
242
|
"data-app-brand": true,
|
|
184
|
-
"aria-label": brandSlot == null ? ".naeil" : void 0
|
|
243
|
+
"aria-label": service ? `.naeil ${service}` : brandSlot == null ? ".naeil" : void 0
|
|
185
244
|
}, brandProps), {
|
|
186
245
|
onClick: (event) => {
|
|
187
246
|
onBrandClick == null ? void 0 : onBrandClick(event);
|
|
188
|
-
onNavigate == null ? void 0 : onNavigate(event, { id: "brand", href: brandDestination, label: ".naeil" });
|
|
247
|
+
onNavigate == null ? void 0 : onNavigate(event, { id: "brand", href: brandDestination, label: service ? `.naeil ${service}` : ".naeil" });
|
|
189
248
|
},
|
|
190
249
|
children: brandSlot != null ? brandSlot : brandSuffix ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
191
250
|
logo,
|
|
@@ -195,7 +254,7 @@ function NaeilHeader(_a) {
|
|
|
195
254
|
);
|
|
196
255
|
return /* @__PURE__ */ jsx(
|
|
197
256
|
Navigation,
|
|
198
|
-
__spreadProps(__spreadValues({}, props), {
|
|
257
|
+
__spreadProps(__spreadValues(__spreadValues({}, props), service ? { "data-slot": "navigation", omitEmptyNavigation: true } : {}), {
|
|
199
258
|
"data-global-header": true,
|
|
200
259
|
"data-naeil-header": true,
|
|
201
260
|
"data-naeil-chrome": "",
|
|
@@ -227,5 +286,6 @@ export {
|
|
|
227
286
|
NaeilHeader,
|
|
228
287
|
NaeilHeaderAccountControl,
|
|
229
288
|
NaeilHeaderLocaleControl,
|
|
230
|
-
NaeilHeaderThemeControl
|
|
289
|
+
NaeilHeaderThemeControl,
|
|
290
|
+
naeilServices
|
|
231
291
|
};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import { JSX } from 'react';
|
|
3
|
+
import { NaeilServiceHeaderProps, NaeilHeaderProps } from './naeil-header-core.js';
|
|
4
|
+
export { NaeilService, naeilServices } from './naeil-header-core.js';
|
|
3
5
|
import { NaeilHeaderLocale } from './naeil-header-data.js';
|
|
4
6
|
export { NaeilHeaderAccountControl } from './naeil-header-account.js';
|
|
5
7
|
export { NaeilHeaderAccount, NaeilHeaderAccountControlProps } from './naeil-header-account-core.js';
|
|
6
|
-
import 'react';
|
|
7
8
|
import './ui/navigation.js';
|
|
8
9
|
|
|
9
|
-
declare function NaeilHeader(props:
|
|
10
|
+
declare function NaeilHeader(props: NaeilServiceHeaderProps): JSX.Element;
|
|
11
|
+
declare function NaeilHeader(props: NaeilHeaderProps): JSX.Element;
|
|
10
12
|
declare function NaeilHeaderThemeControl(props: {
|
|
11
13
|
locale: NaeilHeaderLocale;
|
|
12
14
|
}): react_jsx_runtime.JSX.Element;
|
|
@@ -15,4 +17,4 @@ declare function NaeilHeaderLocaleControl(props: {
|
|
|
15
17
|
onLocaleChange: (locale: NaeilHeaderLocale) => void;
|
|
16
18
|
}): react_jsx_runtime.JSX.Element;
|
|
17
19
|
|
|
18
|
-
export { NaeilHeader, NaeilHeaderLocale, NaeilHeaderLocaleControl, NaeilHeaderProps, NaeilHeaderThemeControl };
|
|
20
|
+
export { NaeilHeader, NaeilHeaderLocale, NaeilHeaderLocaleControl, NaeilHeaderProps, NaeilHeaderThemeControl, NaeilServiceHeaderProps };
|
|
@@ -18,9 +18,10 @@ var __spreadValues = (a, b) => {
|
|
|
18
18
|
import { jsx } from "react/jsx-runtime";
|
|
19
19
|
import { NaeilHeader as Header, NaeilHeaderThemeControl as ThemeControl, NaeilHeaderLocaleControl as LocaleControl } from "./naeil-header-core.js";
|
|
20
20
|
import { NaeilStandaloneMessages } from "./naeil-standalone-messages.js";
|
|
21
|
+
import { naeilServices } from "./naeil-header-core.js";
|
|
21
22
|
import { NaeilHeaderAccountControl } from "./naeil-header-account.js";
|
|
22
23
|
function NaeilHeader(props) {
|
|
23
|
-
return /* @__PURE__ */ jsx(NaeilStandaloneMessages, { locale: props.locale, children: /* @__PURE__ */ jsx(Header, __spreadValues({}, props)) });
|
|
24
|
+
return /* @__PURE__ */ jsx(NaeilStandaloneMessages, { locale: props.locale, children: props.service === void 0 ? /* @__PURE__ */ jsx(Header, __spreadValues({}, props)) : /* @__PURE__ */ jsx(Header, __spreadValues({}, props)) });
|
|
24
25
|
}
|
|
25
26
|
function NaeilHeaderThemeControl(props) {
|
|
26
27
|
return /* @__PURE__ */ jsx(NaeilStandaloneMessages, { locale: props.locale, children: /* @__PURE__ */ jsx(ThemeControl, __spreadValues({}, props)) });
|
|
@@ -32,5 +33,6 @@ export {
|
|
|
32
33
|
NaeilHeader,
|
|
33
34
|
NaeilHeaderAccountControl,
|
|
34
35
|
NaeilHeaderLocaleControl,
|
|
35
|
-
NaeilHeaderThemeControl
|
|
36
|
+
NaeilHeaderThemeControl,
|
|
37
|
+
naeilServices
|
|
36
38
|
};
|
|
@@ -4,7 +4,7 @@ import * as react from 'react';
|
|
|
4
4
|
type HeadingProps = react.HTMLAttributes<HTMLHeadingElement> & {
|
|
5
5
|
children: react.ReactNode;
|
|
6
6
|
};
|
|
7
|
-
declare const pageTitleClass = "text-foreground text-3xl font-semibold
|
|
7
|
+
declare const pageTitleClass = "text-foreground text-3xl font-semibold";
|
|
8
8
|
declare const sectionTitleClass = "text-foreground text-xl font-semibold";
|
|
9
9
|
declare function PageTitle({ className, children, ...props }: HeadingProps): react_jsx_runtime.JSX.Element;
|
|
10
10
|
declare function SectionTitle({ className, children, ...props }: HeadingProps): react_jsx_runtime.JSX.Element;
|
|
@@ -31,7 +31,7 @@ var __objRest = (source, exclude) => {
|
|
|
31
31
|
};
|
|
32
32
|
import { jsx } from "react/jsx-runtime";
|
|
33
33
|
import { cn } from "../lib/utils.js";
|
|
34
|
-
const pageTitleClass = "text-foreground text-3xl font-semibold
|
|
34
|
+
const pageTitleClass = "text-foreground text-3xl font-semibold";
|
|
35
35
|
const sectionTitleClass = "text-foreground text-xl font-semibold";
|
|
36
36
|
function PageTitle(_a) {
|
|
37
37
|
var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
|
|
@@ -31,16 +31,16 @@ import { cva } from "class-variance-authority";
|
|
|
31
31
|
import { Slot } from "radix-ui";
|
|
32
32
|
import { cn } from "../../lib/utils.js";
|
|
33
33
|
const buttonVariants = cva(
|
|
34
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap ui-control ui-focus rounded-md text-base font-medium transition-colors duration-(--ui-motion-fast) cursor-pointer disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 ui-focus aria-invalid:border-error",
|
|
34
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap ui-control ui-focus rounded-md text-base font-medium transition-colors duration-(--ui-motion-fast) cursor-pointer disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 ui-focus aria-invalid:border-error aria-pressed:inset-ring-2",
|
|
35
35
|
{
|
|
36
36
|
variants: {
|
|
37
37
|
variant: {
|
|
38
|
-
default: "bg-primary text-primary-foreground hover:bg-primary-hover",
|
|
39
|
-
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90 ",
|
|
40
|
-
outline: "border border-border-strong bg-background hover:bg-surface-subtle",
|
|
41
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
42
|
-
ghost: "hover:bg-surface-subtle",
|
|
43
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
38
|
+
default: "bg-primary text-primary-foreground hover:bg-primary-hover aria-pressed:bg-primary-hover aria-pressed:inset-ring-4 aria-pressed:inset-ring-primary-foreground aria-pressed:inset-shadow-[0_0_0_2px_var(--primary-hover)]",
|
|
39
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90 aria-pressed:inset-ring-4 aria-pressed:inset-ring-destructive-foreground aria-pressed:inset-shadow-[0_0_0_2px_var(--destructive)]",
|
|
40
|
+
outline: "border border-border-strong bg-background hover:bg-surface-subtle aria-pressed:bg-surface-selected aria-pressed:text-foreground aria-pressed:inset-ring-foreground",
|
|
41
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-pressed:bg-surface-selected aria-pressed:text-foreground aria-pressed:inset-ring-foreground",
|
|
42
|
+
ghost: "hover:bg-surface-subtle aria-pressed:bg-surface-selected aria-pressed:text-foreground aria-pressed:inset-ring-foreground",
|
|
43
|
+
link: "text-primary underline-offset-4 hover:underline aria-pressed:bg-surface-selected aria-pressed:text-foreground aria-pressed:inset-ring-foreground"
|
|
44
44
|
},
|
|
45
45
|
size: {
|
|
46
46
|
default: "px-4 has-[>svg]:px-3",
|
|
@@ -84,7 +84,7 @@ function DialogContent(_g) {
|
|
|
84
84
|
__spreadProps(__spreadValues({
|
|
85
85
|
"data-slot": "dialog-content",
|
|
86
86
|
className: cn(
|
|
87
|
-
"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",
|
|
87
|
+
"bg-popover ui-popup fixed top-[50%] left-[50%] z-50 grid w-full max-h-[min(calc(100%-2rem),calc(100dvh-2rem))] overflow-y-auto 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",
|
|
88
88
|
className
|
|
89
89
|
)
|
|
90
90
|
}, props), {
|
|
@@ -154,7 +154,7 @@ function DialogTitle(_m) {
|
|
|
154
154
|
DialogPrimitive.Title,
|
|
155
155
|
__spreadValues({
|
|
156
156
|
"data-slot": "dialog-title",
|
|
157
|
-
className: cn("text-xl
|
|
157
|
+
className: cn("text-xl font-semibold", className)
|
|
158
158
|
}, props)
|
|
159
159
|
);
|
|
160
160
|
}
|
|
@@ -25,6 +25,8 @@ interface NavigationGroup {
|
|
|
25
25
|
}
|
|
26
26
|
type NavigationItem = NavigationLink | NavigationGroup;
|
|
27
27
|
interface NavigationProps extends Omit<react.ComponentPropsWithoutRef<"header">, "children" | "onSelect"> {
|
|
28
|
+
/** Omit empty landmarks and dismiss toolbar-only sheets on desktop crossing. */
|
|
29
|
+
omitEmptyNavigation?: boolean;
|
|
28
30
|
brand: react.ReactNode;
|
|
29
31
|
items: NavigationItem[];
|
|
30
32
|
/** Translated landmark/dialog/close labels are supplied by the application. */
|
|
@@ -49,6 +51,6 @@ declare const NavigationSheetAction: react.Context<((action: () => void) => {
|
|
|
49
51
|
menuClosed: () => void;
|
|
50
52
|
cancel: () => void;
|
|
51
53
|
}) | undefined>;
|
|
52
|
-
declare function Navigation({ brand, items, labels, Link, currentHref, toolbar, mobileToolbar, mobileFooter, mobileOpen: controlledOpen, onMobileOpenChange, containerClassName, onNavigate, className, ...props }: NavigationProps): react_jsx_runtime.JSX.Element;
|
|
54
|
+
declare function Navigation({ brand, items, labels, Link, currentHref, toolbar, mobileToolbar, mobileFooter, omitEmptyNavigation, mobileOpen: controlledOpen, onMobileOpenChange, containerClassName, onNavigate, className, ...props }: NavigationProps): react_jsx_runtime.JSX.Element;
|
|
53
55
|
|
|
54
56
|
export { Navigation, type NavigationGroup, type NavigationItem, type NavigationLink, type NavigationLinkComponent, type NavigationLinkProps, type NavigationProps, NavigationSheetAction };
|