@clarify-labs/renderer 0.6.7 → 0.7.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.
Files changed (76) hide show
  1. package/output/{OpenApiOperation-CxQQyEHK.cjs → OpenApiOperation-C4xZu4i0.cjs} +154 -79
  2. package/output/OpenApiOperation-C4xZu4i0.cjs.map +1 -0
  3. package/output/{OpenApiOperation-CI_PeMSy.js → OpenApiOperation-LIL7bqxW.js} +129 -60
  4. package/output/OpenApiOperation-LIL7bqxW.js.map +1 -0
  5. package/output/{shell-D4tS8Jts.cjs → PageActions-1RDCHcUY.cjs} +597 -160
  6. package/output/PageActions-1RDCHcUY.cjs.map +1 -0
  7. package/output/{shell-DvTfFx6M.js → PageActions-yoDRjkq8.js} +531 -148
  8. package/output/PageActions-yoDRjkq8.js.map +1 -0
  9. package/output/{ThemeRoot-DErmHskn.js → ThemeRoot-CLa0yvRQ.js} +302 -106
  10. package/output/ThemeRoot-CLa0yvRQ.js.map +1 -0
  11. package/output/{ThemeRoot-BhP5M3Hd.cjs → ThemeRoot-DYS-lcK-.cjs} +349 -129
  12. package/output/ThemeRoot-DYS-lcK-.cjs.map +1 -0
  13. package/output/app/AppShell.d.ts +5 -2
  14. package/output/app/PageActions.d.ts +12 -0
  15. package/output/app/PageBanner.d.ts +7 -0
  16. package/output/app/PageFooter.d.ts +5 -1
  17. package/output/app/SectionProvider.d.ts +1 -0
  18. package/output/client.cjs +14 -4
  19. package/output/client.d.ts +4 -1
  20. package/output/client.js +4 -3
  21. package/output/components/LocalizedLink.d.ts +6 -0
  22. package/output/components/WebFrame.d.ts +11 -0
  23. package/output/components/index.d.ts +4 -0
  24. package/output/context.d.ts +1 -1
  25. package/output/core/context.d.ts +5 -5
  26. package/output/core/index.d.ts +1 -1
  27. package/output/core/types.d.ts +74 -59
  28. package/output/index.cjs +57 -28
  29. package/output/index.cjs.map +1 -1
  30. package/output/index.d.ts +9 -7
  31. package/output/index.js +37 -12
  32. package/output/index.js.map +1 -1
  33. package/output/mdx/components.d.ts +2 -0
  34. package/output/mdx/primitives.d.ts +3 -2
  35. package/output/preview.cjs +66 -28
  36. package/output/preview.cjs.map +1 -1
  37. package/output/preview.js +63 -25
  38. package/output/preview.js.map +1 -1
  39. package/output/{render-C_NHO3rz.cjs → render-CRTqZzyY.cjs} +10 -8
  40. package/output/render-CRTqZzyY.cjs.map +1 -0
  41. package/output/{render-HeCAMIGm.js → render-D0ls3d2j.js} +8 -6
  42. package/output/render-D0ls3d2j.js.map +1 -0
  43. package/output/renderer.css +575 -280
  44. package/output/server.cjs +10 -8
  45. package/output/server.cjs.map +1 -1
  46. package/output/server.js +7 -5
  47. package/output/server.js.map +1 -1
  48. package/output/shell/ContentActions.d.ts +0 -1
  49. package/output/shell/Header.d.ts +3 -2
  50. package/output/shell/Search.d.ts +4 -0
  51. package/output/shell/SiteLogo.d.ts +2 -2
  52. package/output/shell/mobile.d.ts +2 -2
  53. package/output/shell/search/Highlight.d.ts +11 -0
  54. package/output/shell/search/SearchDialog.d.ts +13 -0
  55. package/output/shell/search/SearchInput.d.ts +8 -0
  56. package/output/shell/search/SearchResult.d.ts +10 -0
  57. package/output/shell/search/items.d.ts +3 -0
  58. package/output/shell/search/pagefind.d.ts +5 -0
  59. package/output/shell/search/types.d.ts +37 -0
  60. package/output/shell/search/useSearchProps.d.ts +10 -0
  61. package/output/theme/ThemeEditor.d.ts +53 -17
  62. package/output/theme/ThemeProvider.d.ts +2 -1
  63. package/output/theme/ThemeRoot.d.ts +2 -2
  64. package/output/theme/cookies.d.ts +11 -0
  65. package/output/theme/randomTheme.d.ts +2 -2
  66. package/output/theme/variables.d.ts +58 -18
  67. package/output/utils/href.d.ts +3 -3
  68. package/package.json +1 -1
  69. package/output/OpenApiOperation-CI_PeMSy.js.map +0 -1
  70. package/output/OpenApiOperation-CxQQyEHK.cjs.map +0 -1
  71. package/output/ThemeRoot-BhP5M3Hd.cjs.map +0 -1
  72. package/output/ThemeRoot-DErmHskn.js.map +0 -1
  73. package/output/render-C_NHO3rz.cjs.map +0 -1
  74. package/output/render-HeCAMIGm.js.map +0 -1
  75. package/output/shell-D4tS8Jts.cjs.map +0 -1
  76. package/output/shell-DvTfFx6M.js.map +0 -1
@@ -3,19 +3,22 @@ import { Fragment, Suspense, createContext, forwardRef, useContext, useEffect, u
3
3
  import { Link, useLocation, useNavigate } from "react-router-dom";
4
4
  import { CloseButton, Dialog, DialogBackdrop, DialogPanel, Menu, MenuButton, MenuItem, MenuItems, TransitionChild } from "@headlessui/react";
5
5
  import * as LucideIcons from "lucide-react";
6
- import { Check, ChevronDown, Copy, ExternalLink, FileText, Globe2, Link2, Menu as Menu$1, Moon, MoreHorizontal, PencilLine, Search, SearchX, Sun, X } from "lucide-react";
6
+ import { Check, ChevronDown, Copy, ExternalLink, FileText, Globe2, Link2, LoaderCircle, Menu as Menu$1, Moon, MoreHorizontal, PencilLine, Search, SearchX, Sun, X } from "lucide-react";
7
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
8
  import { AnimatePresence, motion, useIsPresent, useScroll, useTransform } from "framer-motion";
9
9
  import { create, createStore, useStore } from "zustand";
10
10
  //#region source/core/context.tsx
11
- var ClarifyConfigContext = createContext(null);
12
- var ClarifyLocaleContext = createContext(void 0);
11
+ var ConfigContext = createContext(null);
12
+ var LocaleContext = createContext(void 0);
13
13
  var OpenApisContext = createContext({});
14
- function useClarifyConfig() {
15
- const config = useContext(ClarifyConfigContext);
16
- if (!config) throw new Error("[clarify] useClarifyConfig must be used within a ClarifyConfigContext.Provider");
14
+ function useConfig() {
15
+ const config = useContext(ConfigContext);
16
+ if (!config) throw new Error("[clarify] useConfig must be used within a ConfigContext.Provider");
17
17
  return config;
18
18
  }
19
+ function useLocale() {
20
+ return useContext(LocaleContext);
21
+ }
19
22
  function useOpenApis() {
20
23
  return useContext(OpenApisContext);
21
24
  }
@@ -214,8 +217,8 @@ function translateBuiltInText(locale, key, replacements = {}) {
214
217
  return value;
215
218
  }
216
219
  function useBuiltInText(locale) {
217
- const config = useContext(ClarifyConfigContext);
218
- const currentLocale = useContext(ClarifyLocaleContext);
220
+ const config = useContext(ConfigContext);
221
+ const currentLocale = useContext(LocaleContext);
219
222
  const resolvedLocale = locale ?? currentLocale ?? config?.i18n?.defaultLocale;
220
223
  return (key, replacements) => translateBuiltInText(resolvedLocale, key, replacements);
221
224
  }
@@ -277,7 +280,7 @@ function getAbsoluteUrl(path) {
277
280
  return new URL(path, window.location.href).href;
278
281
  }
279
282
  function ContentActions(arg0) {
280
- const { hasTabs = false, route, routePrefix } = arg0;
283
+ const { route, routePrefix } = arg0;
281
284
  const t = useBuiltInText();
282
285
  const [copied, setCopied] = useState("idle");
283
286
  if (!route?.contentArtifactUrl && !route?.sourceUrl) return null;
@@ -328,29 +331,36 @@ function ContentActions(arg0) {
328
331
  const primaryAction = actions[0];
329
332
  const PrimaryIcon = primaryAction && copied === primaryAction.key ? Check : primaryAction?.icon ?? PencilLine;
330
333
  return /* @__PURE__ */ jsx("div", {
331
- className: `clarify-content-actions sticky z-20 flex justify-end py-4 ${hasTabs ? "top-16 lg:top-30" : "top-16"}`,
334
+ className: "clarify-content-actions not-prose flex shrink-0 justify-start sm:justify-end",
332
335
  children: /* @__PURE__ */ jsxs(Menu, {
333
336
  as: "div",
334
- className: "clarify-content-actions-menu relative inline-flex text-sm font-medium",
337
+ className: "clarify-content-actions-menu relative inline-flex min-w-0 text-sm font-medium",
335
338
  children: [/* @__PURE__ */ jsxs("div", {
336
- className: "clarify-content-actions-group inline-flex overflow-hidden rounded-full border border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-surface)/90 shadow-sm shadow-zinc-900/5 backdrop-blur",
339
+ className: "clarify-content-actions-group inline-flex min-w-0 overflow-hidden rounded-full border border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-surface) shadow-sm shadow-zinc-900/5",
337
340
  children: [primaryAction ? /* @__PURE__ */ jsxs("button", {
338
341
  type: "button",
339
342
  onClick: primaryAction.run,
340
- className: "clarify-content-actions-primary clarify-ui-control inline-flex h-8 items-center gap-1.5 px-3 transition",
341
- children: [/* @__PURE__ */ jsx(PrimaryIcon, { className: "h-3.5 w-3.5" }), copied === primaryAction.key ? t("actions.copied") : primaryAction.label]
343
+ className: "clarify-content-actions-primary clarify-ui-control inline-flex h-8 min-w-0 items-center gap-1.5 px-2.5 transition sm:px-3",
344
+ children: [/* @__PURE__ */ jsx(PrimaryIcon, { className: "h-3.5 w-3.5 shrink-0" }), /* @__PURE__ */ jsx("span", {
345
+ className: "truncate",
346
+ children: copied === primaryAction.key ? t("actions.copied") : primaryAction.label
347
+ })]
342
348
  }) : /* @__PURE__ */ jsxs("a", {
343
349
  href: route.sourceUrl,
344
350
  target: "_blank",
345
351
  rel: "noreferrer",
346
- className: "clarify-content-actions-primary clarify-ui-control inline-flex h-8 items-center gap-1.5 px-3 no-underline transition",
347
- children: [/* @__PURE__ */ jsx(PrimaryIcon, { className: "h-3.5 w-3.5" }), t("contentActions.editPage")]
352
+ className: "clarify-content-actions-primary clarify-ui-control inline-flex h-8 min-w-0 items-center gap-1.5 px-2.5 no-underline transition sm:px-3",
353
+ children: [/* @__PURE__ */ jsx(PrimaryIcon, { className: "h-3.5 w-3.5 shrink-0" }), /* @__PURE__ */ jsx("span", {
354
+ className: "truncate",
355
+ children: t("contentActions.editPage")
356
+ })]
348
357
  }), /* @__PURE__ */ jsx(MenuButton, {
349
358
  className: "clarify-content-actions-trigger clarify-ui-control inline-flex h-8 w-8 items-center justify-center border-l border-(--clarify-theme-tokens-colors-border) transition",
350
359
  "aria-label": t("contentActions.copyOptions"),
351
360
  children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5" })
352
361
  })]
353
362
  }), /* @__PURE__ */ jsxs(MenuItems, {
363
+ modal: false,
354
364
  anchor: "bottom end",
355
365
  className: "clarify-content-actions-list clarify-ui-menu z-30 mt-2 w-(--clarify-ui-action-menu-width) origin-top-right rounded-(--clarify-theme-tokens-radius-xl) border border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-surface) p-1.5 shadow-xl shadow-zinc-900/5 transition [--anchor-gap:--spacing(2)] focus:outline-none data-closed:scale-95 data-closed:opacity-0",
356
366
  children: [
@@ -480,27 +490,116 @@ function ContentActions(arg0) {
480
490
  });
481
491
  }
482
492
  //#endregion
493
+ //#region source/theme/cookies.ts
494
+ var themeCookieName = "clarify-theme";
495
+ var localeCookieName = "clarify-locale";
496
+ var preferenceCookieMaxAge = 3600 * 24 * 365;
497
+ var cookiePath = "/";
498
+ function isThemePreference(value) {
499
+ return value === "light" || value === "dark" || value === "system";
500
+ }
501
+ function readThemeCookie() {
502
+ if (typeof document === "undefined") return null;
503
+ const value = readCookieValue(themeCookieName);
504
+ return isThemePreference(value) ? value : null;
505
+ }
506
+ function getStoredThemePreference() {
507
+ return readThemeCookie() ?? "system";
508
+ }
509
+ function storeThemePreference(theme) {
510
+ storeSharedPreferenceCookie(themeCookieName, theme);
511
+ }
512
+ function readLocaleCookie() {
513
+ if (typeof document === "undefined") return null;
514
+ return readCookieValue(localeCookieName);
515
+ }
516
+ function getStoredLocalePreference(locales) {
517
+ const locale = readLocaleCookie();
518
+ if (!locale) return null;
519
+ return locales && !locales.includes(locale) ? null : locale;
520
+ }
521
+ function storeLocalePreference(locale) {
522
+ storeSharedPreferenceCookie(localeCookieName, locale);
523
+ }
524
+ function storeSharedPreferenceCookie(name, value) {
525
+ if (typeof document === "undefined") return;
526
+ const domains = resolveSharedCookieDomains();
527
+ const domain = resolveWritableSharedCookieDomain(domains, name);
528
+ deleteCookie(name);
529
+ for (const candidateDomain of domains) deleteCookie(name, { domain: candidateDomain });
530
+ writeCookie(name, value, {
531
+ domain: domain ?? void 0,
532
+ maxAge: preferenceCookieMaxAge
533
+ });
534
+ }
535
+ function resolveSharedCookieDomains(hostname = typeof window !== "undefined" ? window.location.hostname : "") {
536
+ const normalizedHostname = hostname.toLowerCase().replace(/\.$/, "");
537
+ if (!normalizedHostname || normalizedHostname === "localhost" || normalizedHostname.endsWith(".localhost") || isIpAddress(normalizedHostname)) return [];
538
+ const parts = normalizedHostname.split(".");
539
+ if (parts.length < 2) return [];
540
+ const domains = [];
541
+ for (let index = parts.length - 2; index >= 0; index -= 1) domains.push(parts.slice(index).join("."));
542
+ return domains;
543
+ }
544
+ function resolveWritableSharedCookieDomain(domains, probePrefix = themeCookieName) {
545
+ for (const domain of domains) {
546
+ const probeName = `${probePrefix}-probe-${Date.now()}-${Math.random().toString(36).slice(2)}`;
547
+ const probeValue = "1";
548
+ writeCookie(probeName, probeValue, {
549
+ domain,
550
+ maxAge: 60
551
+ });
552
+ const isWritable = readCookieValue(probeName) === probeValue;
553
+ deleteCookie(probeName, { domain });
554
+ if (isWritable) return domain;
555
+ }
556
+ return null;
557
+ }
558
+ function readCookieValue(cookieName) {
559
+ const cookies = document.cookie ? document.cookie.split("; ") : [];
560
+ for (const cookie of cookies) {
561
+ const separatorIndex = cookie.indexOf("=");
562
+ const name = separatorIndex === -1 ? cookie : cookie.slice(0, separatorIndex);
563
+ if (decodeURIComponent(name) !== cookieName) continue;
564
+ return separatorIndex === -1 ? "" : decodeURIComponent(cookie.slice(separatorIndex + 1));
565
+ }
566
+ return null;
567
+ }
568
+ function deleteCookie(name, options = {}) {
569
+ writeCookie(name, "", {
570
+ domain: options.domain,
571
+ maxAge: 0
572
+ });
573
+ }
574
+ function writeCookie(name, value, options) {
575
+ const attributes = [
576
+ `${encodeURIComponent(name)}=${encodeURIComponent(value)}`,
577
+ `Path=${cookiePath}`,
578
+ `Max-Age=${options.maxAge}`,
579
+ "SameSite=Lax"
580
+ ];
581
+ if (options.domain) attributes.push(`Domain=.${options.domain}`);
582
+ if (typeof window !== "undefined" && window.location.protocol === "https:") attributes.push("Secure");
583
+ try {
584
+ document.cookie = attributes.join("; ");
585
+ } catch {}
586
+ }
587
+ function isIpAddress(hostname) {
588
+ return /^\d{1,3}(?:\.\d{1,3}){3}$/.test(hostname) || hostname.includes(":");
589
+ }
590
+ //#endregion
483
591
  //#region source/theme/ThemeProvider.tsx
484
592
  var ThemeContext = createContext(null);
485
- var storageKey = "clarify:theme";
486
593
  function getSystemTheme() {
487
594
  if (typeof window === "undefined") return "light";
488
595
  return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
489
596
  }
490
597
  function getStoredTheme() {
491
598
  if (typeof window === "undefined") return "system";
492
- try {
493
- const storedTheme = window.localStorage.getItem(storageKey);
494
- return storedTheme === "light" || storedTheme === "dark" || storedTheme === "system" ? storedTheme : "system";
495
- } catch {
496
- return "system";
497
- }
599
+ return getStoredThemePreference();
498
600
  }
499
601
  function storeTheme(theme) {
500
- if (typeof window === "undefined") return;
501
- try {
502
- window.localStorage.setItem(storageKey, theme);
503
- } catch {}
602
+ storeThemePreference(theme);
504
603
  }
505
604
  function applyTheme(resolvedTheme) {
506
605
  if (typeof document === "undefined") return;
@@ -737,7 +836,7 @@ function SectionBadge(arg0) {
737
836
  });
738
837
  }
739
838
  function NavLink(arg0) {
740
- const { href, children, badge, icon, active = false, isAnchorLink = false } = arg0;
839
+ const { href, children, badge, icon, active = false, isAnchorLink = false, level } = arg0;
741
840
  function handleClick() {
742
841
  if (!isAnchorLink) return;
743
842
  const hashIndex = href.indexOf("#");
@@ -755,7 +854,8 @@ function NavLink(arg0) {
755
854
  to: href,
756
855
  "aria-current": active ? "page" : void 0,
757
856
  onClick: handleClick,
758
- className: clsx("clarify-navigation-link flex h-8 items-center justify-between gap-2 pr-3 transition", isAnchorLink ? "clarify-navigation-anchor-link pl-7" : "pl-4"),
857
+ className: clsx("clarify-navigation-link flex h-8 items-center justify-between gap-2 pr-3 transition", isAnchorLink ? "clarify-navigation-anchor-link" : "pl-4"),
858
+ style: isAnchorLink ? { paddingLeft: `${1.75 + Math.max(0, (level ?? 2) - 2) * .75}rem` } : void 0,
759
859
  children: /* @__PURE__ */ jsxs("span", {
760
860
  className: "flex min-w-0 flex-1 items-center gap-2",
761
861
  children: [
@@ -844,7 +944,7 @@ function NavigationGroup(arg0) {
844
944
  const [pathname, sections] = useInitialValue([normalizeRoutePath(useLocation().pathname), useSectionStore((s) => s.sections)], isInsideMobileNavigation);
845
945
  const isActiveGroup = group.links.findIndex((link) => isSameRoutePath(link.href, pathname)) !== -1;
846
946
  return /* @__PURE__ */ jsxs("li", {
847
- className: clsx("clarify-navigation-group relative mt-6", className),
947
+ className: clsx("clarify-navigation-group relative mb-6", className),
848
948
  children: [/* @__PURE__ */ jsxs("h2", {
849
949
  className: "clarify-navigation-group-title flex items-center gap-2",
850
950
  children: [/* @__PURE__ */ jsx(NavigationIcon, {
@@ -899,6 +999,7 @@ function NavigationGroup(arg0) {
899
999
  badge: section.badge,
900
1000
  tags: section.tags,
901
1001
  isAnchorLink: true,
1002
+ level: section.level,
902
1003
  children: section.title
903
1004
  }) }, section.id))
904
1005
  }) : null
@@ -1043,7 +1144,7 @@ function MobileNavigation(arg0) {
1043
1144
  });
1044
1145
  }
1045
1146
  //#endregion
1046
- //#region source/shell/Search.tsx
1147
+ //#region source/shell/search/items.ts
1047
1148
  function routeGroupTitles(navigation) {
1048
1149
  const titles = /* @__PURE__ */ new Map();
1049
1150
  for (const node of navigation) if (node.children?.length) for (const child of node.children) titles.set(child.path, node.title);
@@ -1080,53 +1181,85 @@ function buildSearchItems(routes, navigation) {
1080
1181
  })) ?? []];
1081
1182
  });
1082
1183
  }
1083
- function escapeRegExp(value) {
1084
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1085
- }
1086
- function HighlightQuery(arg0) {
1087
- const { text, query } = arg0;
1088
- if (!query) return text;
1089
- return /* @__PURE__ */ jsx(Fragment$1, { children: text.split(new RegExp(`(${escapeRegExp(query)})`, "ig")).map((part, index) => part.toLowerCase() === query.toLowerCase() ? /* @__PURE__ */ jsx("mark", {
1090
- className: "bg-transparent text-(--clarify-theme-tokens-colors-primary) underline",
1091
- children: part
1092
- }, index) : /* @__PURE__ */ jsx(Fragment, { children: part }, index)) });
1184
+ //#endregion
1185
+ //#region source/shell/search/pagefind.ts
1186
+ var pagefindPromises = /* @__PURE__ */ new Map();
1187
+ function pagefindCacheKey(routePrefix, locale) {
1188
+ return `${routePrefix || "/"}:${locale || "default"}`;
1093
1189
  }
1094
- function SearchResult(arg0) {
1095
- const { result, query, active, onSelect } = arg0;
1096
- const id = useId();
1097
- const hierarchy = [result.sectionTitle, result.pageTitle].filter((value) => typeof value === "string");
1098
- return /* @__PURE__ */ jsxs("li", {
1099
- id,
1100
- className: clsx("clarify-search-result group block cursor-default px-4 py-3", active && "clarify-search-result-active"),
1101
- "aria-selected": active,
1102
- onMouseDown: (event) => {
1103
- event.preventDefault();
1104
- onSelect();
1105
- },
1106
- children: [/* @__PURE__ */ jsx("div", {
1107
- className: "clarify-search-result-title",
1108
- children: /* @__PURE__ */ jsx(HighlightQuery, {
1109
- text: result.title,
1110
- query
1111
- })
1112
- }), hierarchy.length > 0 ? /* @__PURE__ */ jsx("div", {
1113
- className: "clarify-search-result-hierarchy mt-1 truncate whitespace-nowrap",
1114
- children: hierarchy.map((item, itemIndex, items) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(HighlightQuery, {
1115
- text: item,
1116
- query
1117
- }), /* @__PURE__ */ jsx("span", {
1118
- className: itemIndex === items.length - 1 ? "sr-only" : "clarify-search-result-separator mx-2",
1119
- children: "/"
1120
- })] }, `${item}-${itemIndex}`))
1121
- }) : null]
1190
+ function logSearchDebug(message, data) {
1191
+ if (typeof window === "undefined") return;
1192
+ console.info(`[clarify:search] ${message}`, data ?? "");
1193
+ }
1194
+ function loadPagefind(routePrefix, locale) {
1195
+ if (typeof window === "undefined") return Promise.resolve(null);
1196
+ const language = locale ?? document.documentElement.lang;
1197
+ const cacheKey = pagefindCacheKey(routePrefix, language);
1198
+ const cachedPagefind = pagefindPromises.get(cacheKey);
1199
+ if (cachedPagefind) {
1200
+ logSearchDebug("reuse Pagefind instance promise", {
1201
+ cacheKey,
1202
+ language,
1203
+ routePrefix
1204
+ });
1205
+ return cachedPagefind;
1206
+ }
1207
+ const pagefindUrl = prefixHref("/pagefind/pagefind.js", routePrefix);
1208
+ logSearchDebug("create Pagefind instance promise", {
1209
+ cacheKey,
1210
+ language,
1211
+ pagefindUrl,
1212
+ routePrefix
1213
+ });
1214
+ const pagefindPromise = import(
1215
+ /* @vite-ignore */
1216
+ pagefindUrl
1217
+ ).then(async (module) => {
1218
+ const previousLanguage = document.documentElement.lang;
1219
+ if (language) document.documentElement.lang = language;
1220
+ logSearchDebug("create Pagefind instance", {
1221
+ cacheKey,
1222
+ detectedLanguage: document.documentElement.lang,
1223
+ previousLanguage
1224
+ });
1225
+ const pagefind = module.createInstance();
1226
+ if (previousLanguage && previousLanguage !== language) document.documentElement.lang = previousLanguage;
1227
+ await pagefind.init?.();
1228
+ logSearchDebug("Pagefind instance ready", {
1229
+ cacheKey,
1230
+ language
1231
+ });
1232
+ return pagefind;
1233
+ }).catch((error) => {
1234
+ pagefindPromises.delete(cacheKey);
1235
+ console.warn("[clarify:search] Pagefind instance failed", {
1236
+ cacheKey,
1237
+ language,
1238
+ error
1239
+ });
1240
+ return null;
1122
1241
  });
1242
+ pagefindPromises.set(cacheKey, pagefindPromise);
1243
+ return pagefindPromise;
1123
1244
  }
1245
+ function normalizePagefindUrl(url, routePrefix) {
1246
+ const parsedUrl = new URL(url, window.location.origin);
1247
+ let pathname = parsedUrl.pathname;
1248
+ const prefix = routePrefix && routePrefix !== "/" ? `/${routePrefix.replace(/^\/+|\/+$/g, "")}` : "";
1249
+ if (prefix && (pathname === prefix || pathname.startsWith(`${prefix}/`))) pathname = pathname.slice(prefix.length) || "/";
1250
+ return `${pathname}${parsedUrl.search}${parsedUrl.hash}`;
1251
+ }
1252
+ //#endregion
1253
+ //#region source/shell/search/SearchInput.tsx
1124
1254
  var SearchInput = forwardRef(function SearchInput(arg0, inputRef) {
1125
- const { query, setQuery, onClose, onSubmit, activeDescendantId } = arg0;
1255
+ const { query, setQuery, onClose, onSubmit, activeDescendantId, loading = false } = arg0;
1126
1256
  const t = useBuiltInText();
1127
1257
  return /* @__PURE__ */ jsxs("div", {
1128
1258
  className: "clarify-search-input group relative flex h-12",
1129
- children: [/* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute top-0 left-3 h-full w-5 stroke-(--clarify-theme-tokens-colors-muted)" }), /* @__PURE__ */ jsx("input", {
1259
+ children: [/* @__PURE__ */ jsx(loading ? LoaderCircle : Search, {
1260
+ "aria-hidden": "true",
1261
+ className: clsx("pointer-events-none absolute top-0 left-3 h-full w-5 stroke-(--clarify-theme-tokens-colors-muted)", loading && "animate-spin")
1262
+ }), /* @__PURE__ */ jsx("input", {
1130
1263
  ref: inputRef,
1131
1264
  "data-autofocus": true,
1132
1265
  role: "combobox",
@@ -1148,20 +1281,120 @@ var SearchInput = forwardRef(function SearchInput(arg0, inputRef) {
1148
1281
  })]
1149
1282
  });
1150
1283
  });
1284
+ //#endregion
1285
+ //#region source/shell/search/Highlight.tsx
1286
+ function stripHtml(value) {
1287
+ if (typeof document === "undefined") return value.replace(/<[^>]*>/g, "");
1288
+ const template = document.createElement("template");
1289
+ template.innerHTML = value;
1290
+ return template.content.textContent ?? "";
1291
+ }
1292
+ function escapeRegExp(value) {
1293
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1294
+ }
1295
+ function HighlightQuery(arg0) {
1296
+ const { text, query } = arg0;
1297
+ if (!query) return text;
1298
+ return /* @__PURE__ */ jsx(Fragment$1, { children: text.split(new RegExp(`(${escapeRegExp(query)})`, "ig")).map((part, index) => part.toLowerCase() === query.toLowerCase() ? /* @__PURE__ */ jsx("mark", {
1299
+ className: "bg-transparent text-(--clarify-theme-tokens-colors-primary) underline",
1300
+ children: part
1301
+ }, index) : /* @__PURE__ */ jsx(Fragment, { children: part }, index)) });
1302
+ }
1303
+ function renderExcerptNode(node, key) {
1304
+ if (node.nodeType === Node.TEXT_NODE) return node.textContent;
1305
+ if (node.nodeType !== Node.ELEMENT_NODE) return null;
1306
+ const element = node;
1307
+ const children = Array.from(element.childNodes).map((child, index) => renderExcerptNode(child, `${key}-${index}`));
1308
+ if (element.tagName.toLowerCase() === "mark") return /* @__PURE__ */ jsx("mark", {
1309
+ className: "bg-transparent text-(--clarify-theme-tokens-colors-primary) underline",
1310
+ children
1311
+ }, key);
1312
+ return /* @__PURE__ */ jsx(Fragment, { children }, key);
1313
+ }
1314
+ function HighlightExcerpt(arg0) {
1315
+ const { excerpt, query } = arg0;
1316
+ if (typeof document === "undefined" || !excerpt.includes("<mark")) return /* @__PURE__ */ jsx(HighlightQuery, {
1317
+ text: stripHtml(excerpt),
1318
+ query
1319
+ });
1320
+ const template = document.createElement("template");
1321
+ template.innerHTML = excerpt;
1322
+ return /* @__PURE__ */ jsx(Fragment$1, { children: Array.from(template.content.childNodes).map((node, index) => renderExcerptNode(node, String(index))) });
1323
+ }
1324
+ //#endregion
1325
+ //#region source/shell/search/SearchResult.tsx
1326
+ function SearchResult(arg0) {
1327
+ const { result, query, active, onActive, onSelect } = arg0;
1328
+ const id = useId();
1329
+ const hierarchy = result.type === "quick" ? [result.sectionTitle, result.pageTitle].filter((value) => typeof value === "string") : [];
1330
+ return /* @__PURE__ */ jsxs("li", {
1331
+ id,
1332
+ className: clsx("clarify-search-result group block cursor-pointer px-4 py-3", active && "clarify-search-result-active"),
1333
+ "aria-selected": active,
1334
+ onMouseEnter: onActive,
1335
+ onMouseMove: onActive,
1336
+ onMouseDown: (event) => {
1337
+ event.preventDefault();
1338
+ onSelect();
1339
+ },
1340
+ children: [
1341
+ /* @__PURE__ */ jsx("div", {
1342
+ className: "clarify-search-result-title",
1343
+ children: /* @__PURE__ */ jsx(HighlightQuery, {
1344
+ text: result.title,
1345
+ query
1346
+ })
1347
+ }),
1348
+ hierarchy.length > 0 ? /* @__PURE__ */ jsx("div", {
1349
+ className: "clarify-search-result-hierarchy mt-1 truncate whitespace-nowrap",
1350
+ children: hierarchy.map((item, itemIndex, items) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(HighlightQuery, {
1351
+ text: item,
1352
+ query
1353
+ }), /* @__PURE__ */ jsx("span", {
1354
+ className: itemIndex === items.length - 1 ? "sr-only" : "clarify-search-result-separator mx-2",
1355
+ children: "/"
1356
+ })] }, `${item}-${itemIndex}`))
1357
+ }) : null,
1358
+ result.type === "full-text" && result.excerpt ? /* @__PURE__ */ jsx("p", {
1359
+ className: "clarify-search-result-excerpt mt-1 line-clamp-2 text-xs leading-5 text-(--clarify-theme-tokens-colors-muted)",
1360
+ children: /* @__PURE__ */ jsx(HighlightExcerpt, {
1361
+ excerpt: result.excerpt,
1362
+ query
1363
+ })
1364
+ }) : null
1365
+ ]
1366
+ });
1367
+ }
1368
+ //#endregion
1369
+ //#region source/shell/search/SearchDialog.tsx
1151
1370
  function SearchDialog(arg0) {
1152
- const { open, setOpen, routes, navigation, className, onNavigate = () => {} } = arg0;
1371
+ const { open, setOpen, routes, navigation, routePrefix = "/", currentLocale, className, onNavigate = () => {} } = arg0;
1153
1372
  const t = useBuiltInText();
1154
1373
  const navigate = useNavigate();
1155
1374
  const location = useLocation();
1156
1375
  const inputRef = useRef(null);
1157
1376
  const [query, setQuery] = useState("");
1158
1377
  const [activeIndex, setActiveIndex] = useState(0);
1378
+ const [fullTextState, setFullTextState] = useState(null);
1379
+ const [pagefindState, setPagefindState] = useState(null);
1159
1380
  const searchItems = useMemo(() => buildSearchItems(routes, navigation), [navigation, routes]);
1160
- const results = useMemo(() => {
1381
+ const quickResults = useMemo(() => {
1161
1382
  const normalizedQuery = query.trim().toLowerCase();
1162
1383
  if (!normalizedQuery) return [];
1163
- return searchItems.filter((item) => item.keywords.includes(normalizedQuery)).slice(0, 8);
1384
+ return searchItems.filter((item) => item.keywords.includes(normalizedQuery)).slice(0, 8).map((item) => ({
1385
+ ...item,
1386
+ type: "quick"
1387
+ }));
1164
1388
  }, [query, searchItems]);
1389
+ const pagefindKey = pagefindCacheKey(routePrefix, currentLocale);
1390
+ const activePagefindState = pagefindState?.key === pagefindKey ? pagefindState : null;
1391
+ const pagefind = activePagefindState?.pagefind ?? null;
1392
+ const pagefindAvailable = activePagefindState?.available ?? null;
1393
+ const trimmedQuery = query.trim();
1394
+ const fullTextKey = `${pagefindKey}:${trimmedQuery}`;
1395
+ const results = (fullTextState?.key === fullTextKey ? fullTextState.results : null) ?? quickResults;
1396
+ const searchInputLoading = pagefindAvailable === null || Boolean(trimmedQuery && pagefind && fullTextState?.key !== fullTextKey);
1397
+ const showNoResults = query && results.length === 0 && pagefindAvailable !== null;
1165
1398
  useEffect(() => {
1166
1399
  setOpen(false);
1167
1400
  }, [
@@ -1170,6 +1403,98 @@ function SearchDialog(arg0) {
1170
1403
  location.hash,
1171
1404
  setOpen
1172
1405
  ]);
1406
+ useEffect(() => {
1407
+ let cancelled = false;
1408
+ logSearchDebug("locale or route prefix changed; reload Pagefind", {
1409
+ currentLocale,
1410
+ routePrefix,
1411
+ documentLanguage: document.documentElement.lang
1412
+ });
1413
+ loadPagefind(routePrefix, currentLocale).then((loadedPagefind) => {
1414
+ if (cancelled) {
1415
+ logSearchDebug("ignore stale Pagefind load", {
1416
+ currentLocale,
1417
+ routePrefix
1418
+ });
1419
+ return;
1420
+ }
1421
+ logSearchDebug("Pagefind load applied", {
1422
+ currentLocale,
1423
+ routePrefix,
1424
+ available: Boolean(loadedPagefind)
1425
+ });
1426
+ setPagefindState({
1427
+ key: pagefindKey,
1428
+ pagefind: loadedPagefind,
1429
+ available: Boolean(loadedPagefind)
1430
+ });
1431
+ });
1432
+ return () => {
1433
+ cancelled = true;
1434
+ logSearchDebug("cancel Pagefind load effect", {
1435
+ currentLocale,
1436
+ routePrefix
1437
+ });
1438
+ };
1439
+ }, [
1440
+ currentLocale,
1441
+ pagefindKey,
1442
+ routePrefix
1443
+ ]);
1444
+ useEffect(() => {
1445
+ let cancelled = false;
1446
+ if (!trimmedQuery || !pagefind) return void 0;
1447
+ Promise.resolve().then(async () => {
1448
+ if (cancelled) return;
1449
+ try {
1450
+ logSearchDebug("run Pagefind search", {
1451
+ currentLocale,
1452
+ query: trimmedQuery,
1453
+ routePrefix
1454
+ });
1455
+ const search = await pagefind.search(trimmedQuery, { limit: 8 });
1456
+ const data = await Promise.all(search.results.map(async (result) => ({
1457
+ id: result.id,
1458
+ data: await result.data()
1459
+ })));
1460
+ if (cancelled) return;
1461
+ logSearchDebug("Pagefind search results", {
1462
+ currentLocale,
1463
+ query: trimmedQuery,
1464
+ count: data.length
1465
+ });
1466
+ setFullTextState({
1467
+ key: fullTextKey,
1468
+ results: data.map(({ id, data }) => ({
1469
+ type: "full-text",
1470
+ id,
1471
+ title: data.meta.title || data.url,
1472
+ url: normalizePagefindUrl(data.url, routePrefix),
1473
+ excerpt: data.excerpt
1474
+ }))
1475
+ });
1476
+ } catch (error) {
1477
+ console.warn("[clarify:search] Pagefind search failed", {
1478
+ currentLocale,
1479
+ query: trimmedQuery,
1480
+ error
1481
+ });
1482
+ if (!cancelled) setFullTextState({
1483
+ key: fullTextKey,
1484
+ results: null
1485
+ });
1486
+ }
1487
+ });
1488
+ return () => {
1489
+ cancelled = true;
1490
+ };
1491
+ }, [
1492
+ currentLocale,
1493
+ fullTextKey,
1494
+ pagefind,
1495
+ routePrefix,
1496
+ trimmedQuery
1497
+ ]);
1173
1498
  useEffect(() => {
1174
1499
  if (open) return void 0;
1175
1500
  function onKeyDown(event) {
@@ -1222,10 +1547,11 @@ function SearchDialog(arg0) {
1222
1547
  query,
1223
1548
  setQuery: updateQuery,
1224
1549
  onClose: closeDialog,
1225
- onSubmit: () => selectResult()
1550
+ onSubmit: () => selectResult(),
1551
+ loading: searchInputLoading
1226
1552
  }), /* @__PURE__ */ jsxs("div", {
1227
1553
  className: "border-t border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-background) empty:hidden dark:border-zinc-100/5 dark:bg-white/2.5",
1228
- children: [query && results.length === 0 ? /* @__PURE__ */ jsxs("div", {
1554
+ children: [showNoResults ? /* @__PURE__ */ jsxs("div", {
1229
1555
  className: "p-6 text-center",
1230
1556
  children: [/* @__PURE__ */ jsx(SearchX, { className: "mx-auto h-5 w-5 stroke-(--clarify-theme-tokens-colors-foreground) dark:stroke-zinc-600" }), /* @__PURE__ */ jsx("p", {
1231
1557
  className: "mt-2 text-xs text-(--clarify-theme-tokens-colors-muted) dark:text-zinc-400",
@@ -1239,14 +1565,17 @@ function SearchDialog(arg0) {
1239
1565
  result,
1240
1566
  query,
1241
1567
  active: resultIndex === activeIndex,
1568
+ onActive: () => setActiveIndex(resultIndex),
1242
1569
  onSelect: () => selectResult(result)
1243
- }, result.url))
1570
+ }, result.type === "full-text" ? result.id : result.url))
1244
1571
  }) : null]
1245
1572
  })]
1246
1573
  })
1247
1574
  })]
1248
1575
  });
1249
1576
  }
1577
+ //#endregion
1578
+ //#region source/shell/search/useSearchProps.ts
1250
1579
  function useSearchProps() {
1251
1580
  const buttonRef = useRef(null);
1252
1581
  const [open, setOpen] = useState(false);
@@ -1263,12 +1592,14 @@ function useSearchProps() {
1263
1592
  }
1264
1593
  };
1265
1594
  }
1595
+ //#endregion
1596
+ //#region source/shell/Search.tsx
1266
1597
  function getModifierKey() {
1267
1598
  if (typeof navigator === "undefined") return "Ctrl ";
1268
1599
  return /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform) ? "⌘" : "Ctrl ";
1269
1600
  }
1270
1601
  function Search$1(arg0) {
1271
- const { routes, navigation } = arg0;
1602
+ const { routes, navigation, routePrefix, currentLocale } = arg0;
1272
1603
  const t = useBuiltInText();
1273
1604
  const modifierKey = getModifierKey();
1274
1605
  const { buttonProps, dialogProps } = useSearchProps();
@@ -1298,13 +1629,15 @@ function Search$1(arg0) {
1298
1629
  className: "hidden lg:block",
1299
1630
  routes,
1300
1631
  navigation,
1632
+ routePrefix,
1633
+ currentLocale,
1301
1634
  ...dialogProps
1302
1635
  })
1303
1636
  })]
1304
1637
  });
1305
1638
  }
1306
1639
  function MobileSearch(arg0) {
1307
- const { routes, navigation, onNavigate } = arg0;
1640
+ const { routes, navigation, routePrefix, currentLocale, onNavigate } = arg0;
1308
1641
  const t = useBuiltInText();
1309
1642
  const { buttonProps, dialogProps } = useSearchProps();
1310
1643
  return /* @__PURE__ */ jsxs("div", {
@@ -1321,6 +1654,8 @@ function MobileSearch(arg0) {
1321
1654
  className: "lg:hidden",
1322
1655
  routes,
1323
1656
  navigation,
1657
+ routePrefix,
1658
+ currentLocale,
1324
1659
  onNavigate,
1325
1660
  ...dialogProps
1326
1661
  })
@@ -1399,6 +1734,7 @@ function LanguageSwitcher(arg0) {
1399
1734
  const selected = locale.code === selectedLocale;
1400
1735
  return [/* @__PURE__ */ jsx(MenuItem, { children: ({ focus }) => /* @__PURE__ */ jsxs(Link, {
1401
1736
  to: `${localizedPath}${suffix}`,
1737
+ onClick: () => storeLocalePreference(locale.code),
1402
1738
  className: clsx("clarify-language-switcher-item clarify-ui-menu-item flex items-center justify-between rounded-(--clarify-theme-tokens-radius-lg) px-3 py-2 no-underline transition", focus && "clarify-ui-menu-item-focus", selected && "clarify-ui-menu-item-active"),
1403
1739
  "aria-current": selected ? "true" : void 0,
1404
1740
  lang: locale.code,
@@ -1427,6 +1763,10 @@ function TopLevelNavItem(arg0) {
1427
1763
  children
1428
1764
  }) });
1429
1765
  }
1766
+ function resolveHomeHref(config, currentLocale) {
1767
+ const homeUrl = config.homeUrl ?? "/";
1768
+ return isExternalHref(homeUrl) ? homeUrl : localizeHref(homeUrl, config, currentLocale);
1769
+ }
1430
1770
  function MobileNavbarMenu(arg0) {
1431
1771
  const { links, config, currentLocale } = arg0;
1432
1772
  const t = useBuiltInText();
@@ -1508,94 +1848,137 @@ function ProductTabs(arg0) {
1508
1848
  });
1509
1849
  }
1510
1850
  var Header = forwardRef(function Header(arg0, ref) {
1511
- const { config, navigation, tabs, routes, currentLocale, currentRoute, className, ...props } = arg0;
1851
+ const { config, navigation, tabs, routes, currentLocale, currentRoute, banner, className, ...props } = arg0;
1512
1852
  const t = useBuiltInText();
1513
1853
  const { isOpen: mobileNavIsOpen } = useMobileNavigationStore();
1514
1854
  const isInsideMobileNavigation = useIsInsideMobileNavigation();
1855
+ const homeHref = resolveHomeHref(config, currentLocale);
1856
+ const homeExternal = isExternalHref(homeHref);
1515
1857
  const { scrollY } = useScroll();
1516
1858
  const bgOpacityLight = useTransform(scrollY, [0, 72], ["70%", "95%"]);
1517
1859
  const bgOpacityDark = useTransform(scrollY, [0, 72], ["60%", "92%"]);
1518
1860
  return /* @__PURE__ */ jsxs(motion.header, {
1519
1861
  ...props,
1520
1862
  ref,
1863
+ "data-pagefind-ignore": true,
1521
1864
  className: clsx(className, "clarify-header fixed inset-x-0 top-0 z-50 border-b border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-background)/(--bg-opacity-light) backdrop-blur-xs transition dark:border-white/10 dark:bg-zinc-950/(--bg-opacity-dark) dark:backdrop-blur-sm", isInsideMobileNavigation && "bg-(--clarify-theme-tokens-colors-background) dark:bg-zinc-950"),
1522
1865
  style: {
1523
1866
  "--bg-opacity-light": bgOpacityLight,
1524
1867
  "--bg-opacity-dark": bgOpacityDark
1525
1868
  },
1526
- children: [/* @__PURE__ */ jsxs("div", {
1527
- className: clsx("clarify-header-main relative mx-auto flex h-14 w-full max-w-(--clarify-theme-layout-max-width) items-center justify-between gap-6 px-4 sm:px-6 lg:px-5", (isInsideMobileNavigation || !mobileNavIsOpen) && "shadow-none"),
1528
- children: [
1529
- /* @__PURE__ */ jsxs("div", {
1530
- className: "clarify-header-left flex min-w-0 items-center gap-5",
1531
- children: [/* @__PURE__ */ jsx("div", {
1532
- className: "clarify-mobile-brand flex items-center gap-5 lg:hidden",
1533
- children: /* @__PURE__ */ jsx(MobileNavigation, {
1534
- config,
1535
- navigation,
1536
- tabs,
1537
- routes,
1538
- currentLocale,
1539
- currentRoute
1540
- })
1541
- }), /* @__PURE__ */ jsxs(CloseButton, {
1542
- as: Link,
1543
- to: localizeHref("/", config, currentLocale),
1544
- "aria-label": t("navbar.home"),
1545
- className: "clarify-brand flex min-w-0 items-center gap-2 no-underline",
1546
- children: [/* @__PURE__ */ jsx(SiteLogo, {
1547
- logo: config.logo,
1548
- className: "h-6 w-6 shrink-0"
1549
- }), /* @__PURE__ */ jsx("span", {
1550
- className: "clarify-brand-title truncate font-semibold",
1551
- children: config.title
1552
- })]
1553
- })]
1554
- }),
1555
- /* @__PURE__ */ jsx("div", {
1556
- className: "clarify-header-center absolute left-1/2 hidden -translate-x-1/2 lg:block",
1557
- children: /* @__PURE__ */ jsx(Search$1, {
1558
- routes,
1559
- navigation
1560
- })
1561
- }),
1562
- /* @__PURE__ */ jsxs("div", {
1563
- className: "clarify-header-actions flex shrink-0 items-center gap-5",
1564
- children: [
1565
- config.navbar?.links?.length ? /* @__PURE__ */ jsx("nav", {
1566
- className: "clarify-top-nav hidden md:block",
1567
- children: /* @__PURE__ */ jsx("ul", {
1568
- role: "list",
1569
- className: "flex items-center gap-8",
1570
- children: config.navbar.links.map((link) => /* @__PURE__ */ jsx(TopLevelNavItem, {
1571
- href: localizeHref(link.href, config, currentLocale),
1572
- children: resolveLocalizedText(link.label, currentLocale, config.i18n?.defaultLocale)
1573
- }, link.href))
1869
+ children: [
1870
+ /* @__PURE__ */ jsxs("div", {
1871
+ className: clsx("clarify-header-main relative mx-auto flex h-14 w-full max-w-(--clarify-theme-layout-max-width) items-center justify-between gap-6 px-4 sm:px-6 lg:px-5", (isInsideMobileNavigation || !mobileNavIsOpen) && "shadow-none"),
1872
+ children: [
1873
+ /* @__PURE__ */ jsxs("div", {
1874
+ className: "clarify-header-left flex min-w-0 items-center gap-5",
1875
+ children: [/* @__PURE__ */ jsx("div", {
1876
+ className: "clarify-mobile-brand flex items-center gap-5 lg:hidden",
1877
+ children: /* @__PURE__ */ jsx(MobileNavigation, {
1878
+ config,
1879
+ navigation,
1880
+ tabs,
1881
+ routes,
1882
+ currentLocale,
1883
+ currentRoute
1574
1884
  })
1575
- }) : null,
1576
- config.navbar?.links?.length ? /* @__PURE__ */ jsx("div", { className: "hidden md:block md:h-5 md:w-px md:bg-(--clarify-theme-tokens-colors-border) md:dark:bg-white/15" }) : null,
1577
- /* @__PURE__ */ jsx(MobileSearch, {
1885
+ }), homeExternal ? /* @__PURE__ */ jsxs(CloseButton, {
1886
+ as: "a",
1887
+ href: homeHref,
1888
+ "aria-label": t("navbar.home"),
1889
+ className: "clarify-brand flex min-w-0 items-center gap-2 no-underline",
1890
+ children: [/* @__PURE__ */ jsx(SiteLogo, {
1891
+ logo: config.logo,
1892
+ className: "h-6 w-auto shrink-0 object-contain"
1893
+ }), /* @__PURE__ */ jsx("span", {
1894
+ className: "clarify-brand-title truncate font-semibold",
1895
+ children: config.title
1896
+ })]
1897
+ }) : /* @__PURE__ */ jsxs(CloseButton, {
1898
+ as: Link,
1899
+ to: homeHref,
1900
+ "aria-label": t("navbar.home"),
1901
+ className: "clarify-brand flex min-w-0 items-center gap-2 no-underline",
1902
+ children: [/* @__PURE__ */ jsx(SiteLogo, {
1903
+ logo: config.logo,
1904
+ className: "h-6 w-auto shrink-0 object-contain"
1905
+ }), /* @__PURE__ */ jsx("span", {
1906
+ className: "clarify-brand-title truncate font-semibold",
1907
+ children: config.title
1908
+ })]
1909
+ })]
1910
+ }),
1911
+ /* @__PURE__ */ jsx("div", {
1912
+ className: "clarify-header-center absolute left-1/2 hidden -translate-x-1/2 lg:block",
1913
+ children: /* @__PURE__ */ jsx(Search$1, {
1578
1914
  routes,
1579
- navigation
1580
- }),
1581
- /* @__PURE__ */ jsx(LanguageSwitcher, {
1582
- config,
1583
- currentLocale,
1584
- currentRoute
1585
- }),
1586
- /* @__PURE__ */ jsx(ThemeToggle, {}),
1587
- /* @__PURE__ */ jsx(MobileNavbarMenu, {
1588
- links: config.navbar?.links,
1589
- config,
1915
+ navigation,
1916
+ routePrefix: config.routePrefix,
1590
1917
  currentLocale
1591
1918
  })
1592
- ]
1593
- })
1594
- ]
1595
- }), /* @__PURE__ */ jsx(ProductTabs, { tabs })]
1919
+ }),
1920
+ /* @__PURE__ */ jsxs("div", {
1921
+ className: "clarify-header-actions flex shrink-0 items-center gap-5",
1922
+ children: [
1923
+ config.navbar?.links?.length ? /* @__PURE__ */ jsx("nav", {
1924
+ className: "clarify-top-nav hidden md:block",
1925
+ children: /* @__PURE__ */ jsx("ul", {
1926
+ role: "list",
1927
+ className: "flex items-center gap-8",
1928
+ children: config.navbar.links.map((link) => /* @__PURE__ */ jsx(TopLevelNavItem, {
1929
+ href: localizeHref(link.href, config, currentLocale),
1930
+ children: resolveLocalizedText(link.label, currentLocale, config.i18n?.defaultLocale)
1931
+ }, link.href))
1932
+ })
1933
+ }) : null,
1934
+ config.navbar?.links?.length ? /* @__PURE__ */ jsx("div", { className: "hidden md:block md:h-5 md:w-px md:bg-(--clarify-theme-tokens-colors-border) md:dark:bg-white/15" }) : null,
1935
+ /* @__PURE__ */ jsx(MobileSearch, {
1936
+ routes,
1937
+ navigation,
1938
+ routePrefix: config.routePrefix,
1939
+ currentLocale
1940
+ }),
1941
+ /* @__PURE__ */ jsx(LanguageSwitcher, {
1942
+ config,
1943
+ currentLocale,
1944
+ currentRoute
1945
+ }),
1946
+ /* @__PURE__ */ jsx(ThemeToggle, {}),
1947
+ /* @__PURE__ */ jsx(MobileNavbarMenu, {
1948
+ links: config.navbar?.links,
1949
+ config,
1950
+ currentLocale
1951
+ })
1952
+ ]
1953
+ })
1954
+ ]
1955
+ }),
1956
+ banner,
1957
+ /* @__PURE__ */ jsx(ProductTabs, { tabs })
1958
+ ]
1596
1959
  });
1597
1960
  });
1598
1961
  //#endregion
1599
- export { useClarifyConfig as C, OpenApisContext as S, prefixHref as _, useSectionStore as a, ClarifyConfigContext as b, resolveLucideIconName as c, ThemeToggle as d, ThemeProvider as f, localizeHref as g, isExternalHref as h, SectionProvider as i, isSameRoutePath as l, ContentActions as m, Navigation as n, remToPx as o, useTheme as p, safeDecodeURIComponent as r, lucideIconRegistry as s, Header as t, normalizeRoutePath as u, copyTextToClipboard as v, useOpenApis as w, ClarifyLocaleContext as x, useBuiltInText as y };
1962
+ //#region source/app/PageActions.tsx
1963
+ var PageActionsContext = createContext({});
1964
+ function PageActionsProvider(props) {
1965
+ const { children, route, routePrefix } = props;
1966
+ return /* @__PURE__ */ jsx(PageActionsContext.Provider, {
1967
+ value: {
1968
+ route,
1969
+ routePrefix
1970
+ },
1971
+ children
1972
+ });
1973
+ }
1974
+ function PageTitleActions() {
1975
+ const { route, routePrefix } = useContext(PageActionsContext);
1976
+ return /* @__PURE__ */ jsx(ContentActions, {
1977
+ route,
1978
+ routePrefix
1979
+ });
1980
+ }
1981
+ //#endregion
1982
+ export { OpenApisContext as A, isExternalHref as C, useBuiltInText as D, copyTextToClipboard as E, useLocale as M, useOpenApis as N, ConfigContext as O, themeCookieName as S, prefixHref as T, getStoredThemePreference as _, safeDecodeURIComponent as a, storeLocalePreference as b, remToPx as c, isSameRoutePath as d, normalizeRoutePath as f, getStoredLocalePreference as g, useTheme as h, Navigation as i, useConfig as j, LocaleContext as k, lucideIconRegistry as l, ThemeProvider as m, PageTitleActions as n, SectionProvider as o, ThemeToggle as p, Header as r, useSectionStore as s, PageActionsProvider as t, resolveLucideIconName as u, localeCookieName as v, localizeHref as w, storeThemePreference as x, readLocaleCookie as y };
1600
1983
 
1601
- //# sourceMappingURL=shell-DvTfFx6M.js.map
1984
+ //# sourceMappingURL=PageActions-yoDRjkq8.js.map