@clarify-labs/renderer 0.11.7 → 0.11.8

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 (66) hide show
  1. package/output/{ClarifyShell-CKvXZj0f.js → ClarifyShell-CGoRrkn1.js} +120 -68
  2. package/output/ClarifyShell-CGoRrkn1.js.map +1 -0
  3. package/output/{ClarifyShell-CukbPOAd.cjs → ClarifyShell-D8OGIUWq.cjs} +120 -68
  4. package/output/ClarifyShell-D8OGIUWq.cjs.map +1 -0
  5. package/output/{MermaidViewer-FOg263MO.cjs → MermaidViewer-CFqy0BnO.cjs} +3 -3
  6. package/output/{MermaidViewer-FOg263MO.cjs.map → MermaidViewer-CFqy0BnO.cjs.map} +1 -1
  7. package/output/{MermaidViewer-_tpH0JNn.js → MermaidViewer-TdU3sRfy.js} +3 -3
  8. package/output/{MermaidViewer-_tpH0JNn.js.map → MermaidViewer-TdU3sRfy.js.map} +1 -1
  9. package/output/{OpenApiOperation-c-I6Nw9j.cjs → OpenApiOperation-Bd68uxXq.cjs} +9 -8
  10. package/output/{OpenApiOperation-c-I6Nw9j.cjs.map → OpenApiOperation-Bd68uxXq.cjs.map} +1 -1
  11. package/output/{OpenApiOperation-Dv9u2GEJ.js → OpenApiOperation-vCuIKI4O.js} +9 -8
  12. package/output/{OpenApiOperation-Dv9u2GEJ.js.map → OpenApiOperation-vCuIKI4O.js.map} +1 -1
  13. package/output/{PageActions-DviEypf6.js → PageActions-CqXr0SyW.js} +112 -75
  14. package/output/PageActions-CqXr0SyW.js.map +1 -0
  15. package/output/{PageActions-ob2OJusG.cjs → PageActions-DPYXFL6N.cjs} +117 -74
  16. package/output/PageActions-DPYXFL6N.cjs.map +1 -0
  17. package/output/{SearchDialog-89JAjQMh.js → SearchDialog-BQcbGNvl.js} +29 -20
  18. package/output/SearchDialog-BQcbGNvl.js.map +1 -0
  19. package/output/{SearchDialog-CTiUIKeo.cjs → SearchDialog-CExM6Bxd.cjs} +29 -20
  20. package/output/SearchDialog-CExM6Bxd.cjs.map +1 -0
  21. package/output/app/AppShell.d.ts +1 -2
  22. package/output/app/BuiltInNotFoundPage.d.ts +1 -0
  23. package/output/app/PageActions.d.ts +0 -1
  24. package/output/client.cjs +3 -3
  25. package/output/client.js +3 -3
  26. package/output/context.d.ts +2 -1
  27. package/output/core/context.d.ts +9 -0
  28. package/output/core/types.d.ts +4 -0
  29. package/output/{i18n-Cff810G_.js → i18n-D4O3z-sP.js} +24 -3
  30. package/output/i18n-D4O3z-sP.js.map +1 -0
  31. package/output/{i18n-Cjfk1N7i.cjs → i18n-Dw4Jlho-.cjs} +36 -3
  32. package/output/i18n-Dw4Jlho-.cjs.map +1 -0
  33. package/output/index.cjs +11 -7
  34. package/output/index.cjs.map +1 -1
  35. package/output/index.d.ts +3 -2
  36. package/output/index.js +8 -8
  37. package/output/index.js.map +1 -1
  38. package/output/preview.cjs +6 -6
  39. package/output/preview.cjs.map +1 -1
  40. package/output/preview.js +6 -6
  41. package/output/preview.js.map +1 -1
  42. package/output/{render-BxiVlY6q.cjs → render-CqBz1q82.cjs} +2 -2
  43. package/output/{render-BxiVlY6q.cjs.map → render-CqBz1q82.cjs.map} +1 -1
  44. package/output/{render-B41PHjt8.js → render-DQRifjrn.js} +2 -2
  45. package/output/{render-B41PHjt8.js.map → render-DQRifjrn.js.map} +1 -1
  46. package/output/renderer.css +4 -0
  47. package/output/server.cjs +2 -2
  48. package/output/server.js +2 -2
  49. package/output/shell/ContentActions.d.ts +0 -1
  50. package/output/shell/Header.d.ts +1 -2
  51. package/output/shell/Search.d.ts +3 -6
  52. package/output/shell/mobile.d.ts +1 -2
  53. package/output/shell/search/SearchDialog.d.ts +2 -1
  54. package/output/shell/search/pagefind.d.ts +3 -2
  55. package/output/theme/ThemeRoot.d.ts +0 -2
  56. package/output/theme/randomTheme.d.ts +2 -1
  57. package/output/utils/href.d.ts +2 -0
  58. package/package.json +1 -1
  59. package/output/ClarifyShell-CKvXZj0f.js.map +0 -1
  60. package/output/ClarifyShell-CukbPOAd.cjs.map +0 -1
  61. package/output/PageActions-DviEypf6.js.map +0 -1
  62. package/output/PageActions-ob2OJusG.cjs.map +0 -1
  63. package/output/SearchDialog-89JAjQMh.js.map +0 -1
  64. package/output/SearchDialog-CTiUIKeo.cjs.map +0 -1
  65. package/output/i18n-Cff810G_.js.map +0 -1
  66. package/output/i18n-Cjfk1N7i.cjs.map +0 -1
@@ -1,10 +1,10 @@
1
- import { a as useConfig, i as OpenApiSpecsContext, n as ConfigContext, o as useConfigOptional, r as LocaleContext, s as useLocale, t as useBuiltInText } from "./i18n-Cff810G_.js";
2
- import { C as isExternalHref, E as copyTextToClipboard, S as themeCookieName, a as SectionProvider, b as storeLocalePreference, d as normalizeRoutePath, f as resolveLocalizedText, g as getStoredLocalePreference, h as useTheme, i as Navigation, m as ThemeProvider, n as PageActionsProvider, o as useSectionStore, r as Header, u as isSameRoutePath, w as localizeHref } from "./PageActions-DviEypf6.js";
1
+ import { a as useConfig, c as useConfigUpdaterOptional, i as OpenApiSpecsContext, l as useLocale, n as ConfigProvider, o as useConfigOptional, r as LocaleContext, s as useConfigUpdater, t as useBuiltInText } from "./i18n-D4O3z-sP.js";
2
+ import { C as isExternalHref, D as copyTextToClipboard, E as resolveHomeHref, S as themeCookieName, a as SectionProvider, b as storeLocalePreference, d as normalizeRoutePath, f as resolveLocalizedText, g as getStoredLocalePreference, h as useTheme, i as Navigation, m as ThemeProvider, n as PageActionsProvider, o as useSectionStore, r as Header, u as isSameRoutePath, w as localizeHref } from "./PageActions-CqXr0SyW.js";
3
3
  import clsx from "clsx";
4
4
  import { Component, Suspense, createContext, lazy, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
5
5
  import { Link, Route, Routes, useLocation, useNavigate } from "react-router-dom";
6
- import { ArrowRight, ChevronDown, ChevronLeft, ChevronRight, Settings, WandSparkles, X } from "lucide-react";
7
6
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
+ import { ArrowRight, ChevronDown, ChevronLeft, ChevronRight, Settings, WandSparkles, X } from "lucide-react";
8
8
  //#region source/slots/context.tsx
9
9
  var UISlotContextValue = createContext(null);
10
10
  /**
@@ -118,6 +118,39 @@ function safeDecodeURIComponent(value) {
118
118
  }
119
119
  }
120
120
  //#endregion
121
+ //#region source/app/BuiltInNotFoundPage.tsx
122
+ function BuiltInNotFoundPage() {
123
+ const text = useBuiltInText();
124
+ const homeHref = resolveHomeHref(useConfig(), useLocale());
125
+ return /* @__PURE__ */ jsxs("section", {
126
+ className: "mx-auto flex min-h-(--clarify-error-page-min-height) max-w-2xl flex-col justify-center py-16 text-(--clarify-theme-tokens-colors-foreground)",
127
+ "aria-labelledby": "clarify-not-found-title",
128
+ children: [
129
+ /* @__PURE__ */ jsx("p", {
130
+ className: "text-sm/6 font-semibold text-(--clarify-theme-tokens-colors-primary)",
131
+ children: text("notFound.label")
132
+ }),
133
+ /* @__PURE__ */ jsx("h1", {
134
+ id: "clarify-not-found-title",
135
+ className: "mt-3 text-3xl/9 font-semibold tracking-tight text-(--clarify-theme-tokens-colors-foreground)",
136
+ children: text("notFound.title")
137
+ }),
138
+ /* @__PURE__ */ jsx("p", {
139
+ className: "mt-4 text-sm/6 text-(--clarify-theme-tokens-colors-muted)",
140
+ children: text("notFound.description")
141
+ }),
142
+ /* @__PURE__ */ jsx("div", {
143
+ className: "mt-8",
144
+ children: /* @__PURE__ */ jsx(Link, {
145
+ className: "inline-flex items-center rounded-(--clarify-theme-tokens-radius-md) bg-(--clarify-theme-tokens-colors-primary) px-3 py-2 text-sm/5 font-semibold text-white shadow-xs transition hover:opacity-90",
146
+ to: homeHref,
147
+ children: text("notFound.home")
148
+ })
149
+ })
150
+ ]
151
+ });
152
+ }
153
+ //#endregion
121
154
  //#region source/assets/clarify.svg?url
122
155
  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";
123
156
  //#endregion
@@ -478,12 +511,6 @@ function PageBanner(props) {
478
511
  }
479
512
  //#endregion
480
513
  //#region source/app/PageFooter.tsx
481
- function localeForPath(config, pathname) {
482
- const locales = config.locales;
483
- if (!locales) return void 0;
484
- const firstSegment = pathname.split("/").filter(Boolean)[0];
485
- return locales.locales.find((locale) => locale.code === firstSegment)?.code ?? locales.default;
486
- }
487
514
  function FooterLink(arg0) {
488
515
  const { link, locale, config } = arg0;
489
516
  const external = link.external ?? isExternalHref(link.href);
@@ -515,7 +542,7 @@ function SocialLink(arg0) {
515
542
  }
516
543
  function PageFooter() {
517
544
  const config = useConfig();
518
- const locale = localeForPath(config, useLocation().pathname);
545
+ const locale = useLocale() ?? config.locales?.default;
519
546
  const footer = config.footer;
520
547
  const links = footer?.links ?? [];
521
548
  const socials = Object.entries(footer?.socials ?? {});
@@ -1047,43 +1074,14 @@ function getLayoutVariant(hasTabs, hasBanner) {
1047
1074
  function getAppShellLayoutConfig(hasTabs, hasBanner) {
1048
1075
  return appShellLayoutConfig[getLayoutVariant(hasTabs, hasBanner)];
1049
1076
  }
1050
- function BuiltInNotFoundPage() {
1051
- const text = useBuiltInText();
1052
- return /* @__PURE__ */ jsxs("section", {
1053
- className: "mx-auto flex min-h-(--clarify-error-page-min-height) max-w-2xl flex-col justify-center py-16 text-(--clarify-theme-tokens-colors-foreground)",
1054
- "aria-labelledby": "clarify-not-found-title",
1055
- children: [
1056
- /* @__PURE__ */ jsx("p", {
1057
- className: "text-sm/6 font-semibold text-(--clarify-theme-tokens-colors-primary)",
1058
- children: text("notFound.label")
1059
- }),
1060
- /* @__PURE__ */ jsx("h1", {
1061
- id: "clarify-not-found-title",
1062
- className: "mt-3 text-3xl/9 font-semibold tracking-tight text-(--clarify-theme-tokens-colors-foreground)",
1063
- children: text("notFound.title")
1064
- }),
1065
- /* @__PURE__ */ jsx("p", {
1066
- className: "mt-4 text-sm/6 text-(--clarify-theme-tokens-colors-muted)",
1067
- children: text("notFound.description")
1068
- }),
1069
- /* @__PURE__ */ jsx("div", {
1070
- className: "mt-8",
1071
- children: /* @__PURE__ */ jsx(Link, {
1072
- className: "inline-flex items-center rounded-(--clarify-theme-tokens-radius-md) bg-(--clarify-theme-tokens-colors-primary) px-3 py-2 text-sm/5 font-semibold text-white shadow-xs transition hover:opacity-90",
1073
- to: "/",
1074
- children: text("notFound.home")
1075
- })
1076
- })
1077
- ]
1078
- });
1079
- }
1080
1077
  function NotFoundRouteElement(props) {
1081
1078
  const { component: RouteComponent } = props;
1082
1079
  if (!RouteComponent) return /* @__PURE__ */ jsx(BuiltInNotFoundPage, {});
1083
1080
  return /* @__PURE__ */ jsx(RouteComponent, {});
1084
1081
  }
1085
1082
  function AppShell(arg0) {
1086
- const { config, routes, navigation, runtimeSlots } = arg0;
1083
+ const { routes, navigation, runtimeSlots } = arg0;
1084
+ const config = useConfig();
1087
1085
  const location = useLocation();
1088
1086
  const navigate = useNavigate();
1089
1087
  const pathname = normalizeRoutePath(location.pathname);
@@ -1093,7 +1091,7 @@ function AppShell(arg0) {
1093
1091
  const { currentRoute, explicitLocale, storedLocale, currentLocale, currentLocaleConfig, notFoundRoute, currentNavigation, sections } = useRouteState(config, routes, navigation, pathname);
1094
1092
  const text = useBuiltInText(currentLocale);
1095
1093
  const { activeBannerKey, bannerResolved, dismissedBannerKey, hasBanner, dismissBanner } = useBannerState(config, currentLocale);
1096
- const layoutConfig = getAppShellLayoutConfig(Boolean(currentNavigation.tabs?.length), hasBanner);
1094
+ const layoutConfig = getAppShellLayoutConfig(Boolean(currentNavigation.tabs?.length) && config.layout?.tabs !== "navbar", hasBanner);
1097
1095
  const { renderRoutes, NotFoundRouteComponent } = useRenderedRoutes(routes, notFoundRoute);
1098
1096
  useAppShellNavigationEffects({
1099
1097
  config,
@@ -1126,7 +1124,6 @@ function AppShell(arg0) {
1126
1124
  return /* @__PURE__ */ jsx(Header, {
1127
1125
  ref: headerRef,
1128
1126
  topAreaRef: headerTopAreaRef,
1129
- config,
1130
1127
  navigation: currentNavigation.items,
1131
1128
  tabs: currentNavigation.tabs,
1132
1129
  routes,
@@ -1201,7 +1198,6 @@ function AppShell(arg0) {
1201
1198
  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", layoutConfig.contentClassName),
1202
1199
  children: /* @__PURE__ */ jsxs(PageActionsProvider, {
1203
1200
  route: currentRoute,
1204
- routePrefix: config.routePrefix,
1205
1201
  children: [
1206
1202
  renderMain(),
1207
1203
  /* @__PURE__ */ jsx(PageNavigation, {
@@ -1854,6 +1850,7 @@ var randomLayoutWidths = [
1854
1850
  "128rem",
1855
1851
  "144rem"
1856
1852
  ];
1853
+ var randomTabsLayouts = ["subnav", "navbar"];
1857
1854
  var randomDarkAccentPairs = [
1858
1855
  {
1859
1856
  primary: "#34d399",
@@ -1940,6 +1937,9 @@ function createRandomTheme() {
1940
1937
  layout: { maxWidth: selection.maxWidth }
1941
1938
  };
1942
1939
  }
1940
+ function createRandomTabsLayout() {
1941
+ return randomItem(randomTabsLayouts);
1942
+ }
1943
1943
  //#endregion
1944
1944
  //#region source/theme/variables.ts
1945
1945
  var themeStorageKey = themeCookieName;
@@ -2283,18 +2283,22 @@ function ColorModeInput(props) {
2283
2283
  })]
2284
2284
  });
2285
2285
  }
2286
- function themeToConfigSource(theme) {
2287
- return JSON.stringify({ theme: {
2288
- preset: theme.preset,
2289
- tokens: theme.tokens,
2290
- layout: theme.layout
2291
- } }, null, 2);
2286
+ function configToSource(theme, tabs = "subnav") {
2287
+ return JSON.stringify({
2288
+ theme: {
2289
+ preset: theme.preset,
2290
+ tokens: theme.tokens,
2291
+ layout: theme.layout
2292
+ },
2293
+ layout: { tabs }
2294
+ }, null, 2);
2292
2295
  }
2293
2296
  function useThemeEditorState(arg0) {
2294
2297
  const { initialTheme, onChange, target, resolvedTheme } = arg0;
2295
2298
  const [theme, setTheme] = useState(() => cloneTheme(initialTheme ?? themeEditorPresets.default));
2296
2299
  const [copyState, setCopyState] = useState("idle");
2297
- const configSource = useMemo(() => themeToConfigSource(theme), [theme]);
2300
+ const config = useConfigOptional();
2301
+ const configSource = useMemo(() => configToSource(theme, config?.layout?.tabs), [config?.layout?.tabs, theme]);
2298
2302
  useEffect(() => applyThemeCssVariables(themeToCssVariables(theme, resolvedTheme), resolveThemeVariableTargets(target)), [
2299
2303
  resolvedTheme,
2300
2304
  target,
@@ -2363,6 +2367,8 @@ function useThemeEditorState(arg0) {
2363
2367
  }
2364
2368
  function ThemeEditor(props) {
2365
2369
  const { initialTheme, onChange, target, defaultOpen = false, className } = props;
2370
+ const config = useConfigOptional();
2371
+ const updateConfig = useConfigUpdaterOptional();
2366
2372
  const { resolvedTheme } = useTheme();
2367
2373
  const [isOpen, setIsOpen] = useState(defaultOpen);
2368
2374
  const { theme, copyState, commit, updatePreset, updateColorToken, updateRadiusToken, updateLayoutToken, copyConfig } = useThemeEditorState({
@@ -2371,6 +2377,16 @@ function ThemeEditor(props) {
2371
2377
  target,
2372
2378
  resolvedTheme
2373
2379
  });
2380
+ function randomize() {
2381
+ commit(createRandomTheme());
2382
+ updateConfig?.((currentConfig) => ({
2383
+ ...currentConfig,
2384
+ layout: {
2385
+ ...currentConfig.layout,
2386
+ tabs: createRandomTabsLayout()
2387
+ }
2388
+ }));
2389
+ }
2374
2390
  function renderPanelHeader() {
2375
2391
  return /* @__PURE__ */ jsxs("header", {
2376
2392
  className: "shrink-0 flex items-start justify-between gap-4 border-b border-(--clarify-theme-tokens-colors-border) px-4 py-3",
@@ -2447,15 +2463,44 @@ function ThemeEditor(props) {
2447
2463
  }),
2448
2464
  /* @__PURE__ */ jsxs("fieldset", {
2449
2465
  className: "grid gap-3",
2450
- children: [/* @__PURE__ */ jsx("legend", {
2451
- className: "mb-2 text-xs/5 font-semibold uppercase tracking-wide text-(--clarify-ui-text-faint)",
2452
- children: "Layout"
2453
- }), layoutFields.map((field) => /* @__PURE__ */ jsx(TextField, {
2454
- id: `clarify-theme-editor-layout-${field.key}`,
2455
- label: field.label,
2456
- value: theme.layout[field.key],
2457
- onChange: (value) => updateLayoutToken(field.key, value)
2458
- }, field.key))]
2466
+ children: [
2467
+ /* @__PURE__ */ jsx("legend", {
2468
+ className: "mb-2 text-xs/5 font-semibold uppercase tracking-wide text-(--clarify-ui-text-faint)",
2469
+ children: "Layout"
2470
+ }),
2471
+ config && updateConfig ? /* @__PURE__ */ jsxs("label", {
2472
+ htmlFor: "clarify-theme-editor-tabs-position",
2473
+ className: "grid gap-1.5 text-xs/5 font-medium text-(--clarify-ui-text)",
2474
+ children: ["Tabs position", /* @__PURE__ */ jsxs("span", {
2475
+ className: "relative block",
2476
+ children: [/* @__PURE__ */ jsxs("select", {
2477
+ id: "clarify-theme-editor-tabs-position",
2478
+ value: config.layout?.tabs ?? "subnav",
2479
+ className: "h-9 w-full appearance-none rounded-(--clarify-theme-tokens-radius-md) border border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-background) px-2.5 pr-9 text-sm 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)",
2480
+ onChange: (event) => updateConfig((currentConfig) => ({
2481
+ ...currentConfig,
2482
+ layout: {
2483
+ ...currentConfig.layout,
2484
+ tabs: event.target.value
2485
+ }
2486
+ })),
2487
+ children: [/* @__PURE__ */ jsx("option", {
2488
+ value: "subnav",
2489
+ children: "Below navbar"
2490
+ }), /* @__PURE__ */ jsx("option", {
2491
+ value: "navbar",
2492
+ children: "Inside navbar"
2493
+ })]
2494
+ }), /* @__PURE__ */ jsx(ChevronDown, { className: "pointer-events-none absolute top-1/2 right-3 size-4 -translate-y-1/2 stroke-current stroke-2 text-(--clarify-ui-text-faint)" })]
2495
+ })]
2496
+ }) : null,
2497
+ layoutFields.map((field) => /* @__PURE__ */ jsx(TextField, {
2498
+ id: `clarify-theme-editor-layout-${field.key}`,
2499
+ label: field.label,
2500
+ value: theme.layout[field.key],
2501
+ onChange: (value) => updateLayoutToken(field.key, value)
2502
+ }, field.key))
2503
+ ]
2459
2504
  })
2460
2505
  ]
2461
2506
  })
@@ -2474,7 +2519,7 @@ function ThemeEditor(props) {
2474
2519
  }), /* @__PURE__ */ jsxs("button", {
2475
2520
  type: "button",
2476
2521
  className: "inline-flex items-center gap-1.5 rounded-(--clarify-theme-tokens-radius-md) px-2.5 py-1.5 text-xs/5 font-semibold text-(--clarify-ui-text) transition hover:bg-(--clarify-ui-hover-background) hover:text-(--clarify-ui-text-strong)",
2477
- onClick: () => commit(createRandomTheme()),
2522
+ onClick: randomize,
2478
2523
  children: [/* @__PURE__ */ jsx(WandSparkles, { className: "size-3.5 stroke-current stroke-2" }), "Random"]
2479
2524
  })]
2480
2525
  }), /* @__PURE__ */ jsx("button", {
@@ -2512,14 +2557,23 @@ function ThemeEditor(props) {
2512
2557
  //#endregion
2513
2558
  //#region source/theme/ThemeRoot.tsx
2514
2559
  function ThemeRoot(props) {
2515
- const { children, theme, themeEditor = false } = props;
2560
+ const { children, themeEditor = false } = props;
2561
+ const config = useConfig();
2562
+ const updateConfig = useConfigUpdater();
2563
+ const theme = config.theme;
2516
2564
  const { resolvedTheme } = useTheme();
2517
2565
  const themeVariables = useMemo(() => themeToCssVariables(theme, resolvedTheme), [resolvedTheme, theme]);
2518
2566
  useEffect(() => applyThemeCssVariables(themeVariables, resolveThemeVariableTargets(":root")), [themeVariables]);
2519
2567
  return /* @__PURE__ */ jsxs("div", {
2520
2568
  className: "clarify-app h-full min-h-screen bg-(--clarify-theme-tokens-colors-background) text-(--clarify-theme-tokens-colors-foreground)",
2521
2569
  "data-theme-preset": theme.preset,
2522
- children: [children, themeEditor ? /* @__PURE__ */ jsx(ThemeEditor, { initialTheme: theme }) : null]
2570
+ children: [children, themeEditor ? /* @__PURE__ */ jsx(ThemeEditor, {
2571
+ initialTheme: theme,
2572
+ onChange: (nextTheme) => updateConfig((currentConfig) => ({
2573
+ ...currentConfig,
2574
+ theme: nextTheme
2575
+ }))
2576
+ }) : null]
2523
2577
  });
2524
2578
  }
2525
2579
  //#endregion
@@ -2534,15 +2588,13 @@ function ThemeRoot(props) {
2534
2588
  */
2535
2589
  function ClarifyShell(props) {
2536
2590
  const { config, routes, navigation, openApiSpecs, runtimeSlots, themeEditor = false } = props;
2537
- return /* @__PURE__ */ jsx(ConfigContext.Provider, {
2538
- value: config,
2591
+ return /* @__PURE__ */ jsx(ConfigProvider, {
2592
+ config,
2539
2593
  children: /* @__PURE__ */ jsx(OpenApiSpecsContext.Provider, {
2540
2594
  value: openApiSpecs,
2541
2595
  children: /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(ThemeRoot, {
2542
- theme: config.theme,
2543
2596
  themeEditor,
2544
2597
  children: /* @__PURE__ */ jsx(AppShell, {
2545
- config,
2546
2598
  routes,
2547
2599
  navigation: navigation ?? {
2548
2600
  kind: "flat",
@@ -2557,4 +2609,4 @@ function ClarifyShell(props) {
2557
2609
  //#endregion
2558
2610
  export { themeBootstrapScript as a, AppShell as c, RenderErrorPanel as d, BuiltWithClarify as f, useSlot as g, SlotProvider as h, themeEditorPresets as i, PageFooter as l, RuntimeSlotsProvider as m, ThemeEditor as n, themePresets as o, RuntimeSlot as p, applyThemeVariables as r, themeStorageKey as s, ClarifyShell as t, PageBanner as u };
2559
2611
 
2560
- //# sourceMappingURL=ClarifyShell-CKvXZj0f.js.map
2612
+ //# sourceMappingURL=ClarifyShell-CGoRrkn1.js.map