@naeil/ui 0.11.0 → 0.13.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 +38 -2
- package/DESIGN.md +13 -3
- package/README.md +13 -11
- package/THIRD_PARTY_NOTICES.md +4 -2
- package/dist/{chunk-KWEWR46R.js → chunk-5BXZPDHZ.js} +68 -8
- package/dist/{chunk-U3IZCFM4.js → chunk-A2DCQVTP.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 +22 -5
- package/dist/components/ui/index.js +181 -34
- 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.d.ts +4 -2
- package/dist/source/components/ui/dialog.js +10 -6
- package/dist/source/components/ui/index.d.ts +1 -0
- package/dist/source/components/ui/index.js +22 -0
- package/dist/source/components/ui/navigation.d.ts +3 -1
- package/dist/source/components/ui/navigation.js +17 -8
- package/dist/source/components/ui/sheet.d.ts +20 -0
- package/dist/source/components/ui/sheet.js +176 -0
- 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 +4 -1
- package/docs/components/application-layout.md +27 -28
- package/docs/components/avatar.md +1 -1
- package/docs/components/badge.md +5 -1
- package/docs/components/button.md +9 -1
- package/docs/components/card.md +5 -1
- package/docs/components/checkbox.md +1 -1
- package/docs/components/common.md +22 -1
- package/docs/components/dialog.md +14 -4
- package/docs/components/dropdown-menu.md +1 -1
- package/docs/components/input.md +1 -1
- package/docs/components/naeil-footer.md +4 -2
- 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 +50 -0
- 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 +13 -7
- package/docs/package-release.md +24 -8
- package/package.json +11 -10
- package/src/styles/components.css +40 -2
- package/src/styles/globals.css +6 -2
- package/src/styles/theme.css +6 -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
|
@@ -1230,16 +1230,16 @@ import { cva as cva2 } from "class-variance-authority";
|
|
|
1230
1230
|
import { Slot as Slot2 } from "radix-ui";
|
|
1231
1231
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1232
1232
|
var buttonVariants = cva2(
|
|
1233
|
-
"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",
|
|
1233
|
+
"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",
|
|
1234
1234
|
{
|
|
1235
1235
|
variants: {
|
|
1236
1236
|
variant: {
|
|
1237
|
-
default: "bg-primary text-primary-foreground hover:bg-primary-hover",
|
|
1238
|
-
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90 ",
|
|
1239
|
-
outline: "border border-border-strong bg-background hover:bg-surface-subtle",
|
|
1240
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
1241
|
-
ghost: "hover:bg-surface-subtle",
|
|
1242
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
1237
|
+
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)]",
|
|
1238
|
+
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)]",
|
|
1239
|
+
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",
|
|
1240
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-pressed:bg-surface-selected aria-pressed:text-foreground aria-pressed:inset-ring-foreground",
|
|
1241
|
+
ghost: "hover:bg-surface-subtle aria-pressed:bg-surface-selected aria-pressed:text-foreground aria-pressed:inset-ring-foreground",
|
|
1242
|
+
link: "text-primary underline-offset-4 hover:underline aria-pressed:bg-surface-selected aria-pressed:text-foreground aria-pressed:inset-ring-foreground"
|
|
1243
1243
|
},
|
|
1244
1244
|
size: {
|
|
1245
1245
|
default: "px-4 has-[>svg]:px-3",
|
|
@@ -1615,6 +1615,7 @@ function Navigation(_a) {
|
|
|
1615
1615
|
toolbar,
|
|
1616
1616
|
mobileToolbar,
|
|
1617
1617
|
mobileFooter,
|
|
1618
|
+
omitEmptyNavigation = false,
|
|
1618
1619
|
mobileOpen: controlledOpen,
|
|
1619
1620
|
onMobileOpenChange,
|
|
1620
1621
|
containerClassName,
|
|
@@ -1629,6 +1630,7 @@ function Navigation(_a) {
|
|
|
1629
1630
|
"toolbar",
|
|
1630
1631
|
"mobileToolbar",
|
|
1631
1632
|
"mobileFooter",
|
|
1633
|
+
"omitEmptyNavigation",
|
|
1632
1634
|
"mobileOpen",
|
|
1633
1635
|
"onMobileOpenChange",
|
|
1634
1636
|
"containerClassName",
|
|
@@ -1699,7 +1701,8 @@ function Navigation(_a) {
|
|
|
1699
1701
|
setOpenGroup(null);
|
|
1700
1702
|
}, [currentHref, setMobileOpen]);
|
|
1701
1703
|
React.useEffect(() => {
|
|
1702
|
-
|
|
1704
|
+
var _a2, _b2;
|
|
1705
|
+
const element = omitEmptyNavigation && !items.length ? (_b2 = (_a2 = desktop.current) == null ? void 0 : _a2.parentElement) == null ? void 0 : _b2.querySelector(".ui-navigation-toolbar") : desktop.current;
|
|
1703
1706
|
if (!element || typeof ResizeObserver === "undefined") return;
|
|
1704
1707
|
const observer = new ResizeObserver(() => {
|
|
1705
1708
|
if (element.getBoundingClientRect().width > 0) setMobileOpen(false);
|
|
@@ -1707,7 +1710,8 @@ function Navigation(_a) {
|
|
|
1707
1710
|
});
|
|
1708
1711
|
observer.observe(element);
|
|
1709
1712
|
return () => observer.disconnect();
|
|
1710
|
-
}, [setMobileOpen]);
|
|
1713
|
+
}, [setMobileOpen, omitEmptyNavigation, items.length]);
|
|
1714
|
+
const DesktopElement = omitEmptyNavigation && !items.length ? "div" : "nav";
|
|
1711
1715
|
const active = (item) => {
|
|
1712
1716
|
var _a2;
|
|
1713
1717
|
return (_a2 = item.active) != null ? _a2 : !item.external && item.href === currentHref;
|
|
@@ -1756,10 +1760,12 @@ function Navigation(_a) {
|
|
|
1756
1760
|
children: /* @__PURE__ */ jsx6("div", { className: cn("ui-navigation-frame", containerClassName), children: /* @__PURE__ */ jsxs4("div", { className: "ui-navigation-row", children: [
|
|
1757
1761
|
/* @__PURE__ */ jsx6("div", { className: "ui-navigation-brand", children: brand }),
|
|
1758
1762
|
/* @__PURE__ */ jsx6(
|
|
1759
|
-
|
|
1763
|
+
DesktopElement,
|
|
1760
1764
|
{
|
|
1761
|
-
ref:
|
|
1762
|
-
|
|
1765
|
+
ref: (element) => {
|
|
1766
|
+
desktop.current = element;
|
|
1767
|
+
},
|
|
1768
|
+
"aria-label": omitEmptyNavigation && !items.length ? void 0 : labels.navigation,
|
|
1763
1769
|
className: "ui-navigation-desktop",
|
|
1764
1770
|
children: items.map(
|
|
1765
1771
|
(item) => "items" in item ? /* @__PURE__ */ jsx6(
|
|
@@ -1811,7 +1817,7 @@ function Navigation(_a) {
|
|
|
1811
1817
|
className: "ui-navigation-sheet ui-popup",
|
|
1812
1818
|
"aria-describedby": void 0,
|
|
1813
1819
|
onCloseAutoFocus: (event) => {
|
|
1814
|
-
var _a2, _b2;
|
|
1820
|
+
var _a2, _b2, _c, _d;
|
|
1815
1821
|
if (controlledOpen !== void 0 && (!mounted.current || state.current.open)) {
|
|
1816
1822
|
event.preventDefault();
|
|
1817
1823
|
return;
|
|
@@ -1825,7 +1831,10 @@ function Navigation(_a) {
|
|
|
1825
1831
|
}
|
|
1826
1832
|
if (trigger.current && trigger.current.getBoundingClientRect().width === 0) {
|
|
1827
1833
|
event.preventDefault();
|
|
1828
|
-
|
|
1834
|
+
const target = (_a2 = desktop.current) == null ? void 0 : _a2.querySelector("button, a");
|
|
1835
|
+
const toolbar2 = omitEmptyNavigation && !items.length ? (_c = (_b2 = desktop.current) == null ? void 0 : _b2.parentElement) == null ? void 0 : _c.querySelector(".ui-navigation-toolbar") : void 0;
|
|
1836
|
+
const toolbarTarget = !target && toolbar2 ? Array.from(toolbar2.querySelectorAll("button, a[href], input, select, textarea, [tabindex]")).find((element) => element.tabIndex >= 0 && !element.matches(":disabled") && element.getBoundingClientRect().width > 0 && element.getBoundingClientRect().height > 0) : void 0;
|
|
1837
|
+
(_d = target != null ? target : toolbarTarget) == null ? void 0 : _d.focus();
|
|
1829
1838
|
}
|
|
1830
1839
|
},
|
|
1831
1840
|
children: [
|
|
@@ -1840,7 +1849,7 @@ function Navigation(_a) {
|
|
|
1840
1849
|
}
|
|
1841
1850
|
)
|
|
1842
1851
|
] }),
|
|
1843
|
-
/* @__PURE__ */ jsx6(
|
|
1852
|
+
(!omitEmptyNavigation || items.length > 0) && /* @__PURE__ */ jsx6(
|
|
1844
1853
|
"nav",
|
|
1845
1854
|
{
|
|
1846
1855
|
"aria-label": labels.navigation,
|
|
@@ -1886,7 +1895,7 @@ function Navigation(_a) {
|
|
|
1886
1895
|
}
|
|
1887
1896
|
|
|
1888
1897
|
// src/lib/ui-release.ts
|
|
1889
|
-
var uiRelease = { version: "0.
|
|
1898
|
+
var uiRelease = { version: "0.13.0", contractVersion: "1" };
|
|
1890
1899
|
|
|
1891
1900
|
// src/components/naeil-header-data.ts
|
|
1892
1901
|
var headerLocales = ["en", "ko", "ja"];
|
|
@@ -2078,6 +2087,58 @@ function NaeilHeaderAccountControl({ locale, account, Link = NativeLink3 }) {
|
|
|
2078
2087
|
|
|
2079
2088
|
// src/components/naeil-header-core.tsx
|
|
2080
2089
|
import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2090
|
+
var naeilServices = Object.freeze(["abstorm", "home", "estimate", "jev"]);
|
|
2091
|
+
var serviceCompatibilityProps = [
|
|
2092
|
+
"brandSuffix",
|
|
2093
|
+
"statusSlot",
|
|
2094
|
+
"brandSlot",
|
|
2095
|
+
"toolbarSlot",
|
|
2096
|
+
"subNav",
|
|
2097
|
+
"brandLinkComponent",
|
|
2098
|
+
"projects",
|
|
2099
|
+
"projectsExternal",
|
|
2100
|
+
"showProjects",
|
|
2101
|
+
"showBlog",
|
|
2102
|
+
"translations",
|
|
2103
|
+
"className",
|
|
2104
|
+
"containerClassName",
|
|
2105
|
+
"style",
|
|
2106
|
+
"brandLinkProps",
|
|
2107
|
+
"mobileFooter",
|
|
2108
|
+
"omitEmptyNavigation"
|
|
2109
|
+
];
|
|
2110
|
+
var warnedServiceProps = /* @__PURE__ */ new Set();
|
|
2111
|
+
function isDevelopment() {
|
|
2112
|
+
try {
|
|
2113
|
+
return process.env.NODE_ENV === "development";
|
|
2114
|
+
} catch (e) {
|
|
2115
|
+
return false;
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
function warnServiceProp(name, message) {
|
|
2119
|
+
if (!isDevelopment() || warnedServiceProps.has(name)) return;
|
|
2120
|
+
warnedServiceProps.add(name);
|
|
2121
|
+
console.warn(message);
|
|
2122
|
+
}
|
|
2123
|
+
function isNaeilService(value) {
|
|
2124
|
+
return naeilServices.includes(value);
|
|
2125
|
+
}
|
|
2126
|
+
function NaeilHeader(input) {
|
|
2127
|
+
if (input.service === void 0) return /* @__PURE__ */ jsx9(HeaderComposition, __spreadValues({}, input));
|
|
2128
|
+
if (!isNaeilService(input.service)) {
|
|
2129
|
+
warnServiceProp("service", "NaeilHeader: invalid service; rendering the legacy profile.");
|
|
2130
|
+
const legacy = __spreadProps(__spreadValues({}, input), { service: void 0 });
|
|
2131
|
+
delete legacy.service;
|
|
2132
|
+
return /* @__PURE__ */ jsx9(HeaderComposition, __spreadValues({}, legacy));
|
|
2133
|
+
}
|
|
2134
|
+
const props = __spreadValues({}, input);
|
|
2135
|
+
for (const name of Object.keys(props)) {
|
|
2136
|
+
if (!serviceCompatibilityProps.includes(name) && name !== "data-slot" && name !== "data-global-header" && !name.startsWith("data-naeil-")) continue;
|
|
2137
|
+
delete props[name];
|
|
2138
|
+
warnServiceProp(name, `NaeilHeader: service profile ignores ${name}; use the shared service composition.`);
|
|
2139
|
+
}
|
|
2140
|
+
return /* @__PURE__ */ jsx9(HeaderComposition, __spreadProps(__spreadValues({}, props), { service: input.service }));
|
|
2141
|
+
}
|
|
2081
2142
|
var subscribe = () => () => {
|
|
2082
2143
|
};
|
|
2083
2144
|
function NaeilHeaderThemeControl({ locale }) {
|
|
@@ -2114,8 +2175,9 @@ function NaeilHeaderLocaleControl({ locale, onLocaleChange }) {
|
|
|
2114
2175
|
] });
|
|
2115
2176
|
}
|
|
2116
2177
|
var NativeLink4 = (props) => /* @__PURE__ */ jsx9("a", __spreadValues({}, props));
|
|
2117
|
-
function
|
|
2178
|
+
function HeaderComposition(_a) {
|
|
2118
2179
|
var _b = _a, {
|
|
2180
|
+
service,
|
|
2119
2181
|
locale,
|
|
2120
2182
|
resolveHref = (path) => `https://naeil.dev/${locale}${path === "/" ? "" : path}`,
|
|
2121
2183
|
brandHref,
|
|
@@ -2143,6 +2205,7 @@ function NaeilHeader(_a) {
|
|
|
2143
2205
|
className,
|
|
2144
2206
|
containerClassName
|
|
2145
2207
|
} = _b, props = __objRest(_b, [
|
|
2208
|
+
"service",
|
|
2146
2209
|
"locale",
|
|
2147
2210
|
"resolveHref",
|
|
2148
2211
|
"brandHref",
|
|
@@ -2171,6 +2234,11 @@ function NaeilHeader(_a) {
|
|
|
2171
2234
|
"containerClassName"
|
|
2172
2235
|
]);
|
|
2173
2236
|
var _b2, _c;
|
|
2237
|
+
if (service) {
|
|
2238
|
+
brandSuffix = service;
|
|
2239
|
+
showProjects = false;
|
|
2240
|
+
showBlog = false;
|
|
2241
|
+
}
|
|
2174
2242
|
const content = useNaeilMessages(locale).header;
|
|
2175
2243
|
const projectLinks = !showProjects ? [] : projects != null ? projects : headerProjects.map((project) => {
|
|
2176
2244
|
var _a3, _b3, _c2;
|
|
@@ -2189,7 +2257,7 @@ function NaeilHeader(_a) {
|
|
|
2189
2257
|
badge: project.status === "coming" ? /* @__PURE__ */ jsx9(Badge, { variant: "outline", children: (_c2 = translations == null ? void 0 : translations.project("status.coming")) != null ? _c2 : content.projects.status.coming }) : void 0
|
|
2190
2258
|
};
|
|
2191
2259
|
});
|
|
2192
|
-
const brandDestination = brandHref != null ? brandHref : resolveHref("/");
|
|
2260
|
+
const brandDestination = brandHref != null ? brandHref : service ? "/" : resolveHref("/");
|
|
2193
2261
|
const BrandLink = brandLinkComponent != null ? brandLinkComponent : Link;
|
|
2194
2262
|
const _a2 = brandLinkProps != null ? brandLinkProps : {}, { onClick: onBrandClick } = _a2, brandProps = __objRest(_a2, ["onClick"]);
|
|
2195
2263
|
const toolbar = /* @__PURE__ */ jsx9(
|
|
@@ -2215,11 +2283,11 @@ function NaeilHeader(_a) {
|
|
|
2215
2283
|
__spreadProps(__spreadValues({
|
|
2216
2284
|
href: brandDestination,
|
|
2217
2285
|
"data-app-brand": true,
|
|
2218
|
-
"aria-label": brandSlot == null ? ".naeil" : void 0
|
|
2286
|
+
"aria-label": service ? `.naeil ${service}` : brandSlot == null ? ".naeil" : void 0
|
|
2219
2287
|
}, brandProps), {
|
|
2220
2288
|
onClick: (event) => {
|
|
2221
2289
|
onBrandClick == null ? void 0 : onBrandClick(event);
|
|
2222
|
-
onNavigate == null ? void 0 : onNavigate(event, { id: "brand", href: brandDestination, label: ".naeil" });
|
|
2290
|
+
onNavigate == null ? void 0 : onNavigate(event, { id: "brand", href: brandDestination, label: service ? `.naeil ${service}` : ".naeil" });
|
|
2223
2291
|
},
|
|
2224
2292
|
children: brandSlot != null ? brandSlot : brandSuffix ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2225
2293
|
logo,
|
|
@@ -2229,7 +2297,7 @@ function NaeilHeader(_a) {
|
|
|
2229
2297
|
);
|
|
2230
2298
|
return /* @__PURE__ */ jsx9(
|
|
2231
2299
|
Navigation,
|
|
2232
|
-
__spreadProps(__spreadValues({}, props), {
|
|
2300
|
+
__spreadProps(__spreadValues(__spreadValues({}, props), service ? { "data-slot": "navigation", omitEmptyNavigation: true } : {}), {
|
|
2233
2301
|
"data-global-header": true,
|
|
2234
2302
|
"data-naeil-header": true,
|
|
2235
2303
|
"data-naeil-chrome": "",
|
|
@@ -2381,5 +2449,6 @@ export {
|
|
|
2381
2449
|
NaeilHeader,
|
|
2382
2450
|
NaeilHeaderAccountControl,
|
|
2383
2451
|
NaeilHeaderLocaleControl,
|
|
2384
|
-
NaeilHeaderThemeControl
|
|
2452
|
+
NaeilHeaderThemeControl,
|
|
2453
|
+
naeilServices
|
|
2385
2454
|
};
|
|
@@ -6,6 +6,10 @@ import {
|
|
|
6
6
|
// src/naeil-locale/routing.ts
|
|
7
7
|
var naeilLocales = ["en", "ko", "ja"];
|
|
8
8
|
var defaultLocale = "en";
|
|
9
|
+
function escapeRegExp(value) {
|
|
10
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
11
|
+
}
|
|
12
|
+
var localePrefix = new RegExp(`^/(?:${naeilLocales.map(escapeRegExp).join("|")})(?:/|$)`);
|
|
9
13
|
var naeilRouting = {
|
|
10
14
|
locales: naeilLocales,
|
|
11
15
|
defaultLocale,
|
|
@@ -28,7 +32,7 @@ var origins = {
|
|
|
28
32
|
estimate: "https://abestimate.naeil.dev"
|
|
29
33
|
};
|
|
30
34
|
var protocolPrefixes = ["/api", "/auth", "/_next", "/_vercel", "/.well-known", "/health", "/invite", "/return", "/webhook", "/images", "/fonts"];
|
|
31
|
-
var protocolFiles = ["/favicon.ico", "/icon.svg", "/apple-icon.png", "/robots.txt", "/sitemap.xml"];
|
|
35
|
+
var protocolFiles = ["/favicon.ico", "/favicon.svg", "/icon.svg", "/apple-icon.png", "/robots.txt", "/sitemap.xml"];
|
|
32
36
|
function defineLocaleService(service) {
|
|
33
37
|
var _a, _b, _c, _d;
|
|
34
38
|
if (origins[service.id] !== service.origin) throw new Error("Service origin must match the exact owned origin");
|
|
@@ -36,7 +40,7 @@ function defineLocaleService(service) {
|
|
|
36
40
|
if (!paths.length || new Set(paths).size !== paths.length) throw new Error("Route inventory is empty or duplicated");
|
|
37
41
|
for (const path of paths) {
|
|
38
42
|
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}`);
|
|
39
|
-
if (
|
|
43
|
+
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}`);
|
|
40
44
|
}
|
|
41
45
|
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");
|
|
42
46
|
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 : []]) }));
|
|
@@ -72,7 +76,7 @@ function invalid(reason, status = 404, locale) {
|
|
|
72
76
|
return __spreadValues({ kind: "invalid", status, reason }, locale ? { locale } : {});
|
|
73
77
|
}
|
|
74
78
|
function splitInput(input, origin) {
|
|
75
|
-
if (!input || /[\u0000-\u0020\u007f
|
|
79
|
+
if (!input || /[\u0000-\u0020\u007f]/.test(input)) return;
|
|
76
80
|
let path = input;
|
|
77
81
|
if (!path.startsWith("/")) {
|
|
78
82
|
if (!path.startsWith(origin + "/") && path !== origin) return;
|
|
@@ -85,12 +89,14 @@ function splitInput(input, origin) {
|
|
|
85
89
|
const queryAt = withoutHash.indexOf("?");
|
|
86
90
|
return { pathname: queryAt < 0 ? withoutHash : withoutHash.slice(0, queryAt), search: queryAt < 0 ? "" : withoutHash.slice(queryAt), hash };
|
|
87
91
|
}
|
|
88
|
-
function safePath(path) {
|
|
92
|
+
function safePath(path, service) {
|
|
93
|
+
var _a;
|
|
89
94
|
if (!path.startsWith("/") || path.includes("//")) return false;
|
|
95
|
+
const reserved = /* @__PURE__ */ new Set([...naeilLocales, ...[...protocolPrefixes, ...(_a = service.protocolPrefixes) != null ? _a : []].flatMap((prefix) => prefix.split("/").filter(Boolean))]);
|
|
90
96
|
return path.split("/").every((segment) => {
|
|
91
97
|
try {
|
|
92
98
|
const decoded = decodeURIComponent(segment);
|
|
93
|
-
return !/[\u0000-\u001f\u007f/\\%?#]/.test(decoded) && decoded !== "." && decoded !== ".." && (
|
|
99
|
+
return !/[\u0000-\u001f\u007f/\\%?#]/.test(decoded) && decoded !== "." && decoded !== ".." && (!reserved.has(decoded) || decoded === segment);
|
|
94
100
|
} catch (e) {
|
|
95
101
|
return false;
|
|
96
102
|
}
|
|
@@ -113,7 +119,7 @@ function resolveLocaleUrl(inputService, input) {
|
|
|
113
119
|
var _a, _b;
|
|
114
120
|
const service = getLocaleService(inputService);
|
|
115
121
|
const parts = splitInput(input, service.origin);
|
|
116
|
-
if (!parts || !safePath(parts.pathname)) return invalid("Malformed or encoded path");
|
|
122
|
+
if (!parts || !safePath(parts.pathname, service)) return invalid("Malformed or encoded path");
|
|
117
123
|
const rawPathname = parts.pathname;
|
|
118
124
|
const pathname = rawPathname !== "/" && rawPathname.endsWith("/") ? rawPathname.slice(0, -1) : rawPathname;
|
|
119
125
|
if (isProtocolPath(pathname, service) && !((_a = service.uiProtocolExceptions) == null ? void 0 : _a.includes(pathname))) return { kind: "protocol", pathname };
|
|
@@ -121,7 +127,7 @@ function resolveLocaleUrl(inputService, input) {
|
|
|
121
127
|
const explicit = isNaeilLocale(segments[1]);
|
|
122
128
|
const pathLocale = explicit ? segments[1] : void 0;
|
|
123
129
|
const logicalPath = explicit ? "/" + segments.slice(2).join("/") : pathname;
|
|
124
|
-
if (
|
|
130
|
+
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);
|
|
125
131
|
const route = matchRoute(service, logicalPath);
|
|
126
132
|
if (!route) return invalid("Unregistered UI route", 404, pathLocale);
|
|
127
133
|
const legacy = service.id !== "main";
|
|
@@ -137,7 +143,7 @@ function localePath(inputService, unlocalizedRoute, locale) {
|
|
|
137
143
|
assertLocale(locale);
|
|
138
144
|
const service = getLocaleService(inputService);
|
|
139
145
|
const parts = splitInput(unlocalizedRoute, service.origin);
|
|
140
|
-
if (!parts ||
|
|
146
|
+
if (!parts || localePrefix.test(parts.pathname)) throw new Error("localePath requires an unlocalized route");
|
|
141
147
|
const result = resolveLocaleUrl(service, parts.pathname);
|
|
142
148
|
if (result.kind !== "ui") throw new Error("Unregistered UI destination");
|
|
143
149
|
return prefixPath(result.logicalPath, locale) + (service.id === "main" ? parts.search : stripLegacyLang(parts.search)) + parts.hash;
|
|
@@ -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;
|