@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
@@ -1,7 +1,7 @@
1
- import { C as useClarifyConfig, g as localizeHref, h as isExternalHref, i as SectionProvider, l as isSameRoutePath, m as ContentActions, n as Navigation, p as useTheme, r as safeDecodeURIComponent, t as Header, u as normalizeRoutePath, v as copyTextToClipboard, x as ClarifyLocaleContext, y as useBuiltInText } from "./shell-DvTfFx6M.js";
1
+ import { C as isExternalHref, D as useBuiltInText, E as copyTextToClipboard, S as themeCookieName, a as safeDecodeURIComponent, b as storeLocalePreference, d as isSameRoutePath, f as normalizeRoutePath, g as getStoredLocalePreference, h as useTheme, i as Navigation, j as useConfig, k as LocaleContext, o as SectionProvider, r as Header, t as PageActionsProvider, w as localizeHref } from "./PageActions-yoDRjkq8.js";
2
2
  import clsx from "clsx";
3
3
  import { Component, Suspense, lazy, useEffect, useMemo, useState } from "react";
4
- import { Link, Route, Routes, useLocation } from "react-router-dom";
4
+ import { Link, Route, Routes, useLocation, useNavigate } from "react-router-dom";
5
5
  import { ChevronDown, ChevronLeft, ChevronRight, Settings, WandSparkles, X } from "lucide-react";
6
6
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
7
  //#region source/app/ErrorBoundary.tsx
@@ -147,6 +147,86 @@ var PageErrorBoundary = class extends Component {
147
147
  }
148
148
  };
149
149
  //#endregion
150
+ //#region source/app/PageBanner.tsx
151
+ function resolveLocalizedText$1(text, locale, fallbackLocale) {
152
+ if (typeof text === "string") return text;
153
+ return (locale ? text[locale] : void 0) ?? (fallbackLocale ? text[fallbackLocale] : void 0) ?? Object.values(text)[0] ?? "";
154
+ }
155
+ function bannerStorageKey(config, content) {
156
+ return `clarify:banner:dismissed:${config.title}:${content}`;
157
+ }
158
+ function PageBannerLink(props) {
159
+ const { href, label, external: externalProp, config, locale } = props;
160
+ const external = externalProp ?? isExternalHref(href);
161
+ const resolvedHref = external ? href : localizeHref(href, config, locale);
162
+ const className = "clarify-banner-link shrink-0 rounded-full bg-(--clarify-theme-tokens-colors-primary) px-3 py-1 text-xs/5 font-semibold text-white no-underline transition hover:opacity-90";
163
+ if (external) return /* @__PURE__ */ jsx("a", {
164
+ href: resolvedHref,
165
+ target: "_blank",
166
+ rel: "noreferrer",
167
+ className,
168
+ children: label
169
+ });
170
+ return /* @__PURE__ */ jsx(Link, {
171
+ to: resolvedHref,
172
+ className,
173
+ children: label
174
+ });
175
+ }
176
+ function PageBanner(props) {
177
+ const { component: CustomBanner, currentLocale, onDismiss } = props;
178
+ const config = useConfig();
179
+ const banner = config.banner;
180
+ const builtInBanner = banner && typeof banner === "object" ? banner : void 0;
181
+ const content = builtInBanner ? resolveLocalizedText$1(builtInBanner.content, currentLocale, config.i18n?.defaultLocale) : "";
182
+ const link = builtInBanner?.link;
183
+ const linkLabel = link ? resolveLocalizedText$1(link.label, currentLocale, config.i18n?.defaultLocale) : "";
184
+ const storageKey = useMemo(() => content ? bannerStorageKey(config, content) : "", [config, content]);
185
+ const [dismissed, setDismissed] = useState(() => {
186
+ if (!storageKey || !builtInBanner?.dismissible || typeof window === "undefined") return false;
187
+ return window.localStorage.getItem(storageKey) === "1";
188
+ });
189
+ useEffect(() => {
190
+ if (dismissed) onDismiss?.();
191
+ }, [dismissed, onDismiss]);
192
+ if (CustomBanner) return /* @__PURE__ */ jsx("div", {
193
+ className: "clarify-banner clarify-banner-custom flex min-h-12 items-center border-b border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-background) px-4 text-sm text-(--clarify-theme-tokens-colors-foreground) dark:border-white/10 dark:bg-zinc-950",
194
+ children: /* @__PURE__ */ jsx("div", {
195
+ className: "mx-auto w-full max-w-(--clarify-theme-layout-max-width)",
196
+ children: /* @__PURE__ */ jsx(CustomBanner, {})
197
+ })
198
+ });
199
+ if (!builtInBanner || !content || dismissed) return null;
200
+ return /* @__PURE__ */ jsxs("div", {
201
+ className: "clarify-banner relative flex min-h-12 items-center border-b border-(--clarify-ui-accent-border) bg-(--clarify-ui-accent-background) px-4 text-sm text-(--clarify-ui-text) dark:border-white/10",
202
+ children: [/* @__PURE__ */ jsxs("div", {
203
+ className: "mx-auto flex w-full max-w-(--clarify-theme-layout-max-width) items-center justify-center gap-3 pr-8 sm:pr-0",
204
+ children: [/* @__PURE__ */ jsx("p", {
205
+ className: "clarify-banner-content m-0 text-center font-medium",
206
+ children: content
207
+ }), link ? /* @__PURE__ */ jsx(PageBannerLink, {
208
+ href: link.href,
209
+ label: linkLabel,
210
+ external: link.external,
211
+ config,
212
+ locale: currentLocale
213
+ }) : null]
214
+ }), builtInBanner.dismissible ? /* @__PURE__ */ jsx("button", {
215
+ type: "button",
216
+ className: "clarify-banner-dismiss absolute right-3 inline-flex size-8 items-center justify-center rounded-full text-(--clarify-ui-text-soft) transition hover:bg-(--clarify-ui-hover-background) hover:text-(--clarify-ui-text-strong)",
217
+ "aria-label": "Dismiss announcement",
218
+ onClick: () => {
219
+ if (storageKey) window.localStorage.setItem(storageKey, "1");
220
+ setDismissed(true);
221
+ },
222
+ children: /* @__PURE__ */ jsx(X, {
223
+ className: "size-4",
224
+ "aria-hidden": "true"
225
+ })
226
+ }) : null]
227
+ });
228
+ }
229
+ //#endregion
150
230
  //#region source/assets/clarify.svg?url
151
231
  var clarify_default = "data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='UTF-8'?%3e%3csvg%20width='279px'%20height='200px'%20viewBox='0%200%20279%20200'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20xmlns:xlink='http://www.w3.org/1999/xlink'%3e%3ctitle%3eclarify%3c/title%3e%3cg%20id='页面-1'%20stroke='none'%20stroke-width='1'%20fill='none'%20fill-rule='evenodd'%3e%3cg%20id='clarify'%20transform='translate(-0,%200.0054)'%3e%3cpath%20d='M44.867217,0.0054376148%20C130.715579,1.00591567%20200,70.9091172%20200,156.994562%20L199.986321,155.127494%20C199.384888,180.009127%20179.026368,199.994562%20154,199.994562%20L46,199.994562%20C20.5949015,199.994562%200,179.399661%200,153.994562%20L0,45.9945624%20C0,21.0975659%2019.7793434,0.820282524%2044.4815926,0.0191499894%20Z'%20fill='%2300D492'%3e%3c/path%3e%3cpath%20d='M123.867217,0.0054376148%20C209.715579,1.00591567%20279,70.9091172%20279,156.994562%20L278.986321,155.127494%20C278.384888,180.009127%20258.026368,199.994562%20233,199.994562%20L125,199.994562%20C99.5949015,199.994562%2079,179.399661%2079,153.994562%20L79,45.9945624%20C79,21.0975659%2098.7793434,0.820282524%20123.481593,0.0191499894%20Z'%20id='clarify-right'%20fill-opacity='0.6'%20fill='%2300F6C9'%20transform='translate(179,%20100)%20rotate(-90)%20translate(-179,%20-100)'%3e%3c/path%3e%3cpath%20d='M199.979267,154.416906%20L199.984438,155.157125%20L199.962366,155.872459%20C198.977251,180.406837%20178.776104,199.994562%20154,199.994562%20L124.372438,199.994125%20L124.249053,199.994081%20C99.6939678,199.603921%2079.8122712,179.973634%2079.01915,155.518407%20L79.0054376,155.132783%20C79.5830823,105.566626%20103.129768,61.5221348%20139.498462,33.1463428%20C175.69419,61.3871018%20199.186123,105.143863%20199.979267,154.416906%20Z'%20id='形状结合'%20fill='%2300F692'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
152
232
  //#endregion
@@ -164,7 +244,7 @@ function BuiltWithClarify() {
164
244
  /* @__PURE__ */ jsx("img", {
165
245
  src: clarify_default,
166
246
  alt: "",
167
- className: "clarify-built-with-logo h-3.5 w-5 flex-none"
247
+ className: "clarify-built-with-logo h-3.5 w-auto flex-none object-contain"
168
248
  }),
169
249
  /* @__PURE__ */ jsx("span", {
170
250
  className: "clarify-built-with-brand font-semibold",
@@ -179,7 +259,7 @@ function resolveLocalizedText(text, locale, fallbackLocale) {
179
259
  if (typeof text === "string") return text;
180
260
  return (locale ? text[locale] : void 0) ?? (fallbackLocale ? text[fallbackLocale] : void 0) ?? Object.values(text)[0] ?? "";
181
261
  }
182
- function localeForPath$1(config, pathname) {
262
+ function localeForPath(config, pathname) {
183
263
  const i18n = config.i18n;
184
264
  if (!i18n) return void 0;
185
265
  const firstSegment = pathname.split("/").filter(Boolean)[0];
@@ -214,18 +294,23 @@ function SocialLink(arg0) {
214
294
  children: name
215
295
  });
216
296
  }
217
- function PageFooter() {
218
- const config = useClarifyConfig();
219
- const locale = localeForPath$1(config, useLocation().pathname);
297
+ function PageFooter(props = {}) {
298
+ const config = useConfig();
299
+ const locale = localeForPath(config, useLocation().pathname);
220
300
  const footer = config.footer;
221
- const links = footer?.links ?? [];
222
- const socials = Object.entries(footer?.socials ?? {});
223
- const copyright = footer?.copyright ? resolveLocalizedText(footer.copyright, locale, config.i18n?.defaultLocale) : void 0;
224
- const hasCustomFooter = Boolean(copyright || links.length > 0 || socials.length > 0);
301
+ const builtInFooter = footer && typeof footer === "object" ? footer : void 0;
302
+ const CustomFooter = props.component;
303
+ const links = builtInFooter?.links ?? [];
304
+ const socials = Object.entries(builtInFooter?.socials ?? {});
305
+ const copyright = builtInFooter?.copyright ? resolveLocalizedText(builtInFooter.copyright, locale, config.i18n?.defaultLocale) : void 0;
306
+ const hasBuiltInFooter = Boolean(copyright || links.length > 0 || socials.length > 0);
225
307
  return /* @__PURE__ */ jsxs("footer", {
226
- className: clsx("clarify-page-footer mx-auto flex w-full max-w-(--clarify-theme-layout-max-width) flex-col items-end gap-4 border-t border-(--clarify-theme-tokens-colors-border) px-4 py-8 sm:px-6 lg:mt-24 lg:px-5", hasCustomFooter && "sm:flex-row sm:items-center sm:justify-between"),
227
- children: [hasCustomFooter ? /* @__PURE__ */ jsxs("div", {
228
- className: "clarify-footer-content flex flex-col gap-3 text-right sm:text-left",
308
+ className: "clarify-page-footer mt-16 flex w-full flex-col gap-4 border-t border-(--clarify-theme-tokens-colors-border) py-8 lg:mt-24",
309
+ children: [CustomFooter ? /* @__PURE__ */ jsx("div", {
310
+ className: "clarify-footer-custom w-full",
311
+ children: /* @__PURE__ */ jsx(CustomFooter, {})
312
+ }) : hasBuiltInFooter ? /* @__PURE__ */ jsxs("div", {
313
+ className: clsx("clarify-footer-content flex flex-col items-end gap-3 text-right", hasBuiltInFooter && "sm:items-start sm:text-left"),
229
314
  children: [copyright ? /* @__PURE__ */ jsx("p", {
230
315
  className: "clarify-footer-copyright m-0",
231
316
  children: copyright
@@ -241,7 +326,7 @@ function PageFooter() {
241
326
  }, name))]
242
327
  }) : null]
243
328
  }) : null, /* @__PURE__ */ jsx("div", {
244
- className: "clarify-footer-brand flex justify-end",
329
+ className: "clarify-footer-brand flex justify-end self-end",
245
330
  children: /* @__PURE__ */ jsx(BuiltWithClarify, {})
246
331
  })]
247
332
  });
@@ -414,6 +499,7 @@ function sectionsForRoute(route) {
414
499
  return route?.sections?.map((section) => ({
415
500
  id: section.id,
416
501
  title: section.title,
502
+ level: section.level,
417
503
  badge: section.badge,
418
504
  tags: section.tags
419
505
  })) ?? [];
@@ -432,12 +518,20 @@ function scrollToHash(hash) {
432
518
  });
433
519
  });
434
520
  }
435
- function localeForPath(config, pathname, route) {
436
- if (route?.locale) return route.locale;
521
+ function explicitLocaleForPath(config, pathname) {
437
522
  const i18n = config.i18n;
438
523
  if (!i18n) return void 0;
439
524
  const firstSegment = pathname.split("/").filter(Boolean)[0];
440
- return i18n.locales.find((locale) => locale.code === firstSegment)?.code ?? i18n.defaultLocale;
525
+ return i18n.locales.find((locale) => locale.code === firstSegment)?.code;
526
+ }
527
+ function fallbackLocale(config) {
528
+ return config.i18n?.defaultLocale;
529
+ }
530
+ function storedLocaleForConfig(config) {
531
+ return getStoredLocalePreference(config.i18n?.locales.map((locale) => locale.code));
532
+ }
533
+ function isDefaultLocale(config, locale) {
534
+ return Boolean(locale && config.i18n?.defaultLocale === locale);
441
535
  }
442
536
  function isTabbedNavigation(navigation) {
443
537
  return !Array.isArray(navigation) && "tabs" in navigation;
@@ -516,22 +610,46 @@ function NotFoundRouteElement(props) {
516
610
  return /* @__PURE__ */ jsx(RouteComponent, {});
517
611
  }
518
612
  function AppShell(arg0) {
519
- const { config, routes, navigation } = arg0;
613
+ const { config, routes, navigation, bannerComponent, footerComponent } = arg0;
520
614
  const location = useLocation();
615
+ const navigate = useNavigate();
521
616
  const pathname = normalizeRoutePath(location.pathname);
522
617
  const currentRoute = routeForPath(routes, pathname);
523
- const currentLocale = localeForPath(config, pathname, currentRoute);
618
+ const explicitLocale = explicitLocaleForPath(config, pathname);
619
+ const [storedLocale] = useState(() => storedLocaleForConfig(config));
620
+ const currentLocale = explicitLocale ?? storedLocale ?? fallbackLocale(config);
524
621
  const currentLocaleConfig = config.i18n?.locales.find((locale) => locale.code === currentLocale);
525
622
  const notFoundRoute = currentRoute ? void 0 : notFoundRouteForPath(routes, pathname, currentLocale);
526
623
  const text = useBuiltInText(currentLocale);
527
624
  const currentNavigation = navigationForLocale(navigation, currentLocale, pathname);
528
625
  const sections = sectionsForRoute(currentRoute);
626
+ const [dismissedBannerKey, setDismissedBannerKey] = useState();
627
+ const activeBannerKey = config.banner ? JSON.stringify(config.banner) : void 0;
628
+ const hasBanner = Boolean(config.banner) && dismissedBannerKey !== activeBannerKey;
529
629
  const hasTabs = Boolean(currentNavigation.tabs?.length);
530
630
  const renderRoutes = useMemo(() => routes.map((route) => ({
531
631
  ...route,
532
632
  component: resolveRouteComponent(route)
533
633
  })), [routes]);
534
634
  const NotFoundRouteComponent = notFoundRoute ? renderRoutes.find((route) => isSameRoutePath(route.path, notFoundRoute.path))?.component : void 0;
635
+ useEffect(() => {
636
+ if (explicitLocale) storeLocalePreference(explicitLocale);
637
+ }, [explicitLocale]);
638
+ useEffect(() => {
639
+ if (explicitLocale || !storedLocale || isDefaultLocale(config, storedLocale)) return;
640
+ const localizedPath = currentRoute?.alternates?.[storedLocale];
641
+ if (!localizedPath || isSameRoutePath(localizedPath, pathname)) return;
642
+ navigate(`${localizedPath}${location.search}${location.hash}`, { replace: true });
643
+ }, [
644
+ config,
645
+ currentRoute,
646
+ explicitLocale,
647
+ location.hash,
648
+ location.search,
649
+ navigate,
650
+ pathname,
651
+ storedLocale
652
+ ]);
535
653
  useEffect(() => {
536
654
  if (location.hash) {
537
655
  scrollToHash(location.hash);
@@ -558,34 +676,40 @@ function AppShell(arg0) {
558
676
  currentRoute,
559
677
  notFoundRoute
560
678
  ]);
561
- return /* @__PURE__ */ jsx(ClarifyLocaleContext.Provider, {
679
+ return /* @__PURE__ */ jsx(LocaleContext.Provider, {
562
680
  value: currentLocale,
563
681
  children: /* @__PURE__ */ jsxs(SectionProvider, {
564
682
  sections,
565
- children: [
566
- /* @__PURE__ */ jsx(Header, {
567
- config,
568
- navigation: currentNavigation.items,
569
- tabs: currentNavigation.tabs,
570
- routes,
683
+ children: [/* @__PURE__ */ jsx(Header, {
684
+ config,
685
+ navigation: currentNavigation.items,
686
+ tabs: currentNavigation.tabs,
687
+ routes,
688
+ currentLocale,
689
+ currentRoute,
690
+ banner: hasBanner ? /* @__PURE__ */ jsx(PageBanner, {
691
+ component: bannerComponent,
571
692
  currentLocale,
572
- currentRoute
573
- }),
574
- /* @__PURE__ */ jsxs("div", {
575
- className: "clarify-layout pb-12 mx-auto grid w-full max-w-(--clarify-theme-layout-max-width) grid-cols-1 lg:grid-cols-(--clarify-layout-sidebar-grid) xl:grid-cols-(--clarify-layout-sidebar-grid-wide)",
576
- children: [/* @__PURE__ */ jsx("aside", {
577
- className: clsx("clarify-sidebar hidden lg:sticky lg:z-30 lg:block lg:h-(--clarify-sidebar-height) lg:self-start lg:overflow-y-auto lg:bg-(--clarify-theme-tokens-colors-background) lg:px-5 lg:pb-8 xl:px-6", hasTabs ? "lg:top-28 lg:h-(--clarify-sidebar-height-with-tabs) lg:pt-6" : "lg:top-14 lg:pt-6"),
693
+ onDismiss: () => setDismissedBannerKey(activeBannerKey)
694
+ }) : void 0
695
+ }), /* @__PURE__ */ jsxs("div", {
696
+ className: "clarify-layout mx-auto grid w-full max-w-(--clarify-theme-layout-max-width) grid-cols-1 lg:grid-cols-(--clarify-layout-sidebar-grid) xl:grid-cols-(--clarify-layout-sidebar-grid-wide)",
697
+ children: [/* @__PURE__ */ jsx("aside", {
698
+ "data-pagefind-ignore": true,
699
+ className: "clarify-sidebar hidden lg:block lg:self-stretch lg:bg-(--clarify-theme-tokens-colors-background) lg:px-5 xl:px-6",
700
+ children: /* @__PURE__ */ jsx("div", {
701
+ className: clsx("clarify-sidebar-scroll lg:sticky lg:z-30 lg:overflow-y-auto lg:pb-8", hasTabs && hasBanner && "lg:top-40 lg:h-(--clarify-sidebar-height-with-tabs-and-banner) lg:pt-10", hasTabs && !hasBanner && "lg:top-28 lg:h-(--clarify-sidebar-height-with-tabs) lg:pt-10", !hasTabs && hasBanner && "lg:top-[6.5rem] lg:h-(--clarify-sidebar-height-with-banner) lg:pt-10", !hasTabs && !hasBanner && "lg:top-14 lg:h-(--clarify-sidebar-height) lg:pt-10"),
578
702
  children: /* @__PURE__ */ jsx(Navigation, { navigation: currentNavigation.items })
579
- }), /* @__PURE__ */ jsxs("div", {
580
- className: clsx("clarify-content @container relative flex min-h-screen min-w-0 flex-col px-4 sm:px-6 lg:px-8 xl:px-10", hasTabs ? "pt-14 lg:pt-28" : "pt-14"),
703
+ })
704
+ }), /* @__PURE__ */ jsx("div", {
705
+ className: clsx("clarify-content @container relative flex min-h-screen min-w-0 flex-col px-4 pb-12 sm:px-6 lg:px-8 xl:px-10", hasTabs && hasBanner && "pt-[6.5rem] lg:pt-40", hasTabs && !hasBanner && "pt-14 lg:pt-28", !hasTabs && hasBanner && "pt-[6.5rem]", !hasTabs && !hasBanner && "pt-14"),
706
+ children: /* @__PURE__ */ jsxs(PageActionsProvider, {
707
+ route: currentRoute,
708
+ routePrefix: config.routePrefix,
581
709
  children: [
582
- /* @__PURE__ */ jsx(ContentActions, {
583
- hasTabs,
584
- route: currentRoute,
585
- routePrefix: config.routePrefix
586
- }),
587
710
  /* @__PURE__ */ jsx("main", {
588
711
  className: "clarify-main min-w-0 flex-auto",
712
+ "data-pagefind-body": true,
589
713
  children: /* @__PURE__ */ jsx(PageErrorBoundary, {
590
714
  title: text("renderError.title"),
591
715
  description: text("renderError.description"),
@@ -615,12 +739,12 @@ function AppShell(arg0) {
615
739
  /* @__PURE__ */ jsx(PageNavigation, {
616
740
  navigation: currentNavigation.items,
617
741
  currentRoute
618
- })
742
+ }),
743
+ /* @__PURE__ */ jsx(PageFooter, { component: footerComponent })
619
744
  ]
620
- })]
621
- }),
622
- /* @__PURE__ */ jsx(PageFooter, {})
623
- ]
745
+ })
746
+ })]
747
+ })]
624
748
  })
625
749
  });
626
750
  }
@@ -1278,19 +1402,38 @@ function createRandomTheme() {
1278
1402
  }
1279
1403
  //#endregion
1280
1404
  //#region source/theme/variables.ts
1281
- var clarifyThemePresets = {
1405
+ var themeStorageKey = themeCookieName;
1406
+ var themePresets = {
1282
1407
  default: {
1283
1408
  preset: "default",
1284
1409
  tokens: {
1285
1410
  colors: {
1286
1411
  primary: "#047857",
1287
1412
  accent: "#0D9488",
1288
- background: "#ffffff",
1289
- foreground: "#111827",
1290
- surface: "#ffffff",
1291
- muted: "#64748b",
1292
- border: "rgb(15 23 42 / 0.12)",
1293
- codeBackground: "#f6fbf8"
1413
+ background: {
1414
+ light: "#ffffff",
1415
+ dark: "#09090b"
1416
+ },
1417
+ foreground: {
1418
+ light: "#111827",
1419
+ dark: "#ffffff"
1420
+ },
1421
+ surface: {
1422
+ light: "#ffffff",
1423
+ dark: "#18181b"
1424
+ },
1425
+ muted: {
1426
+ light: "#64748b",
1427
+ dark: "#a1a1aa"
1428
+ },
1429
+ border: {
1430
+ light: "rgb(15 23 42 / 0.12)",
1431
+ dark: "rgb(255 255 255 / 0.1)"
1432
+ },
1433
+ codeBackground: {
1434
+ light: "#f6fbf8",
1435
+ dark: "#18181b"
1436
+ }
1294
1437
  },
1295
1438
  radius: {
1296
1439
  sm: "6px",
@@ -1308,12 +1451,30 @@ var clarifyThemePresets = {
1308
1451
  colors: {
1309
1452
  primary: "#18181b",
1310
1453
  accent: "#52525b",
1311
- background: "#ffffff",
1312
- foreground: "#18181b",
1313
- surface: "#ffffff",
1314
- muted: "#71717a",
1315
- border: "rgb(24 24 27 / 0.12)",
1316
- codeBackground: "#f4f4f5"
1454
+ background: {
1455
+ light: "#ffffff",
1456
+ dark: "#09090b"
1457
+ },
1458
+ foreground: {
1459
+ light: "#18181b",
1460
+ dark: "#ffffff"
1461
+ },
1462
+ surface: {
1463
+ light: "#ffffff",
1464
+ dark: "#18181b"
1465
+ },
1466
+ muted: {
1467
+ light: "#71717a",
1468
+ dark: "#a1a1aa"
1469
+ },
1470
+ border: {
1471
+ light: "rgb(24 24 27 / 0.12)",
1472
+ dark: "rgb(255 255 255 / 0.1)"
1473
+ },
1474
+ codeBackground: {
1475
+ light: "#f4f4f5",
1476
+ dark: "#18181b"
1477
+ }
1317
1478
  },
1318
1479
  radius: {
1319
1480
  sm: "6px",
@@ -1368,38 +1529,9 @@ function resolveThemeColors(colors, resolvedTheme = "light") {
1368
1529
  codeBackground: resolveThemeColorValue(colors.codeBackground, resolvedTheme)
1369
1530
  };
1370
1531
  }
1371
- function matchesPresetTheme(theme) {
1372
- const preset = clarifyThemePresets[theme.preset];
1373
- return JSON.stringify({
1374
- tokens: theme.tokens,
1375
- layout: theme.layout
1376
- }) === JSON.stringify({
1377
- tokens: preset.tokens,
1378
- layout: preset.layout
1379
- });
1380
- }
1381
- function effectiveTheme(theme, resolvedTheme) {
1382
- if (resolvedTheme !== "dark" || !matchesPresetTheme(theme)) return theme;
1383
- return {
1384
- ...theme,
1385
- tokens: {
1386
- ...theme.tokens,
1387
- colors: {
1388
- ...theme.tokens.colors,
1389
- background: "#09090b",
1390
- foreground: "#ffffff",
1391
- surface: "#18181b",
1392
- muted: "#a1a1aa",
1393
- border: "rgb(255 255 255 / 0.1)",
1394
- codeBackground: "#18181b"
1395
- }
1396
- }
1397
- };
1398
- }
1399
1532
  function themeToCssVariables(theme, resolvedTheme) {
1400
- const resolved = effectiveTheme(theme, resolvedTheme);
1401
- const colors = resolveThemeColors(resolved.tokens.colors, resolvedTheme);
1402
- const { radius } = resolved.tokens;
1533
+ const colors = resolveThemeColors(theme.tokens.colors, resolvedTheme);
1534
+ const { radius } = theme.tokens;
1403
1535
  return {
1404
1536
  "--clarify-theme-tokens-colors-primary": colors.primary,
1405
1537
  "--clarify-theme-tokens-colors-accent": colors.accent,
@@ -1413,9 +1545,14 @@ function themeToCssVariables(theme, resolvedTheme) {
1413
1545
  "--clarify-theme-tokens-radius-md": radius.md,
1414
1546
  "--clarify-theme-tokens-radius-lg": radius.lg,
1415
1547
  "--clarify-theme-tokens-radius-xl": radius.xl,
1416
- "--clarify-theme-layout-max-width": resolved.layout.maxWidth
1548
+ "--clarify-theme-layout-max-width": theme.layout.maxWidth
1417
1549
  };
1418
1550
  }
1551
+ function themeBootstrapScript(theme = themePresets.default) {
1552
+ const darkVariables = themeToCssVariables(theme, "dark");
1553
+ const lightVariables = themeToCssVariables(theme, "light");
1554
+ return `(function(){try{var c=${JSON.stringify(themeCookieName)};var m=document.cookie?document.cookie.split('; '):[];var e=null;for(var i=0;i<m.length;i++){var p=m[i].indexOf('=');var n=p===-1?m[i]:m[i].slice(0,p);if(decodeURIComponent(n)===c){e=p===-1?'':decodeURIComponent(m[i].slice(p+1));break}}var t=e==='dark'||e==='light'||e==='system'?e:'system';var r=t==='system'?window.matchMedia('(prefers-color-scheme: dark)').matches:t==='dark';var v=r?${JSON.stringify(darkVariables)}:${JSON.stringify(lightVariables)};var s=document.documentElement.style;for(var k in v)s.setProperty(k,v[k]);document.documentElement.classList.toggle('dark',r);document.documentElement.style.colorScheme=r?'dark':'light'}catch(e){}})();`;
1555
+ }
1419
1556
  function uniqueElements(elements) {
1420
1557
  return Array.from(new Set(elements));
1421
1558
  }
@@ -1498,18 +1635,24 @@ var layoutFields = [{
1498
1635
  key: "maxWidth",
1499
1636
  label: "Max width"
1500
1637
  }];
1501
- var clarifyThemeEditorPresets = clarifyThemePresets;
1502
- function applyClarifyThemeVariables(theme, target) {
1638
+ var themeEditorPresets = themePresets;
1639
+ function applyThemeVariables(theme, target) {
1503
1640
  return applyThemeCssVariables(themeToCssVariables(theme), resolveThemeVariableTargets(target));
1504
1641
  }
1505
1642
  function isHexColor(value) {
1506
1643
  return /^#[0-9a-f]{6}$/i.test(value);
1507
1644
  }
1508
- function updateThemeModeColorValue(value, resolvedTheme, nextValue) {
1509
- if (typeof value === "string") return nextValue;
1645
+ function updateThemeModeColorValue(value, mode, nextValue) {
1646
+ if (typeof value === "string") return mode === "light" ? {
1647
+ light: nextValue,
1648
+ dark: value
1649
+ } : {
1650
+ light: value,
1651
+ dark: nextValue
1652
+ };
1510
1653
  return {
1511
1654
  ...value,
1512
- [resolvedTheme]: nextValue
1655
+ [mode]: nextValue
1513
1656
  };
1514
1657
  }
1515
1658
  function TextField(props) {
@@ -1542,6 +1685,61 @@ function TextField(props) {
1542
1685
  })]
1543
1686
  });
1544
1687
  }
1688
+ function ColorField(props) {
1689
+ const { id, label, value, onChange } = props;
1690
+ const lightValue = resolveThemeColorValue(value, "light");
1691
+ const darkValue = resolveThemeColorValue(value, "dark");
1692
+ return /* @__PURE__ */ jsxs("div", {
1693
+ className: "grid min-w-0 gap-1.5",
1694
+ children: [/* @__PURE__ */ jsx("span", {
1695
+ className: "text-xs/5 font-medium text-(--clarify-ui-text)",
1696
+ children: label
1697
+ }), /* @__PURE__ */ jsxs("div", {
1698
+ className: "grid grid-cols-2 gap-2",
1699
+ children: [/* @__PURE__ */ jsx(ColorModeInput, {
1700
+ id: `${id}-light`,
1701
+ mode: "light",
1702
+ value: lightValue,
1703
+ onChange: (v) => onChange("light", v)
1704
+ }), /* @__PURE__ */ jsx(ColorModeInput, {
1705
+ id: `${id}-dark`,
1706
+ mode: "dark",
1707
+ value: darkValue,
1708
+ onChange: (v) => onChange("dark", v)
1709
+ })]
1710
+ })]
1711
+ });
1712
+ }
1713
+ function ColorModeInput(props) {
1714
+ const { id, mode, value, onChange } = props;
1715
+ const canUseColorInput = isHexColor(value);
1716
+ function handleTextChange(event) {
1717
+ onChange(event.target.value);
1718
+ }
1719
+ return /* @__PURE__ */ jsxs("label", {
1720
+ htmlFor: id,
1721
+ className: "grid min-w-0 gap-1 text-[11px]/4 font-medium text-(--clarify-ui-text-faint)",
1722
+ children: [/* @__PURE__ */ jsxs("span", {
1723
+ className: "flex min-w-0 items-center justify-between gap-2",
1724
+ children: [/* @__PURE__ */ jsx("span", {
1725
+ className: "uppercase tracking-wide",
1726
+ children: mode
1727
+ }), canUseColorInput ? /* @__PURE__ */ jsx("input", {
1728
+ type: "color",
1729
+ value,
1730
+ "aria-label": `${id} color`,
1731
+ className: "h-4 w-6 shrink-0 cursor-pointer rounded border border-(--clarify-theme-tokens-colors-border) bg-transparent p-0",
1732
+ onChange: handleTextChange
1733
+ }) : null]
1734
+ }), /* @__PURE__ */ jsx("input", {
1735
+ id,
1736
+ value,
1737
+ spellCheck: false,
1738
+ className: "h-8 w-full min-w-0 rounded-(--clarify-theme-tokens-radius-sm) border border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-background) px-2 font-mono text-xs text-(--clarify-theme-tokens-colors-foreground) shadow-xs outline-none transition focus:border-(--clarify-theme-tokens-colors-primary) focus:ring-2 focus:ring-(--clarify-ui-accent-border)",
1739
+ onChange: handleTextChange
1740
+ })]
1741
+ });
1742
+ }
1545
1743
  function themeToConfigSource(theme) {
1546
1744
  return JSON.stringify({ theme: {
1547
1745
  preset: theme.preset,
@@ -1553,7 +1751,7 @@ function ThemeEditor(props) {
1553
1751
  const { initialTheme, onChange, target, defaultOpen = false, className } = props;
1554
1752
  const { resolvedTheme } = useTheme();
1555
1753
  const [isOpen, setIsOpen] = useState(defaultOpen);
1556
- const [theme, setTheme] = useState(() => cloneTheme(initialTheme ?? clarifyThemeEditorPresets.default));
1754
+ const [theme, setTheme] = useState(() => cloneTheme(initialTheme ?? themeEditorPresets.default));
1557
1755
  const [copyState, setCopyState] = useState("idle");
1558
1756
  const configSource = useMemo(() => themeToConfigSource(theme), [theme]);
1559
1757
  useEffect(() => applyThemeCssVariables(themeToCssVariables(theme, resolvedTheme), resolveThemeVariableTargets(target)), [
@@ -1566,16 +1764,16 @@ function ThemeEditor(props) {
1566
1764
  onChange?.(nextTheme);
1567
1765
  }
1568
1766
  function updatePreset(nextPreset) {
1569
- commit(cloneTheme(clarifyThemeEditorPresets[nextPreset]));
1767
+ commit(cloneTheme(themeEditorPresets[nextPreset]));
1570
1768
  }
1571
- function updateColorToken(key, value) {
1769
+ function updateColorToken(key, mode, value) {
1572
1770
  commit({
1573
1771
  ...theme,
1574
1772
  tokens: {
1575
1773
  ...theme.tokens,
1576
1774
  colors: {
1577
1775
  ...theme.tokens.colors,
1578
- [key]: updateThemeModeColorValue(theme.tokens.colors[key], resolvedTheme, value)
1776
+ [key]: updateThemeModeColorValue(theme.tokens.colors[key], mode, value)
1579
1777
  }
1580
1778
  }
1581
1779
  });
@@ -1665,12 +1863,11 @@ function ThemeEditor(props) {
1665
1863
  children: "Colors"
1666
1864
  }), /* @__PURE__ */ jsx("div", {
1667
1865
  className: "grid grid-cols-1 gap-3",
1668
- children: colorTokenFields.map((field) => /* @__PURE__ */ jsx(TextField, {
1866
+ children: colorTokenFields.map((field) => /* @__PURE__ */ jsx(ColorField, {
1669
1867
  id: `clarify-theme-editor-color-${field.key}`,
1670
1868
  label: field.label,
1671
- value: resolveThemeColorValue(theme.tokens.colors[field.key], resolvedTheme),
1672
- withColorInput: true,
1673
- onChange: (value) => updateColorToken(field.key, value)
1869
+ value: theme.tokens.colors[field.key],
1870
+ onChange: (mode, value) => updateColorToken(field.key, mode, value)
1674
1871
  }, field.key))
1675
1872
  })]
1676
1873
  }),
@@ -1747,11 +1944,10 @@ function ThemeRoot(props) {
1747
1944
  return /* @__PURE__ */ jsxs("div", {
1748
1945
  className: "clarify-app h-full min-h-screen bg-(--clarify-theme-tokens-colors-background) text-(--clarify-theme-tokens-colors-foreground)",
1749
1946
  "data-theme-preset": theme.preset,
1750
- style: themeVariables,
1751
1947
  children: [children, themeEditor ? /* @__PURE__ */ jsx(ThemeEditor, { initialTheme: theme }) : null]
1752
1948
  });
1753
1949
  }
1754
1950
  //#endregion
1755
- export { AppShell as a, clarifyThemeEditorPresets as i, ThemeEditor as n, PageFooter as o, applyClarifyThemeVariables as r, BuiltWithClarify as s, ThemeRoot as t };
1951
+ export { themeBootstrapScript as a, AppShell as c, PageBanner as d, themeEditorPresets as i, PageFooter as l, ThemeEditor as n, themePresets as o, applyThemeVariables as r, themeStorageKey as s, ThemeRoot as t, BuiltWithClarify as u };
1756
1952
 
1757
- //# sourceMappingURL=ThemeRoot-DErmHskn.js.map
1953
+ //# sourceMappingURL=ThemeRoot-CLa0yvRQ.js.map