@clarify-labs/renderer 0.9.1 → 0.9.3

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 (48) hide show
  1. package/output/{ClarifyShell-291_IXxJ.js → ClarifyShell-BQ29N8P5.js} +223 -161
  2. package/output/ClarifyShell-BQ29N8P5.js.map +1 -0
  3. package/output/{ClarifyShell-DJ4fOVOd.cjs → ClarifyShell-Dm--LZco.cjs} +224 -162
  4. package/output/ClarifyShell-Dm--LZco.cjs.map +1 -0
  5. package/output/{OpenApiOperation-E8lSLsSK.js → OpenApiOperation-C9xyRo5a.js} +597 -292
  6. package/output/OpenApiOperation-C9xyRo5a.js.map +1 -0
  7. package/output/{OpenApiOperation-3DUVruIO.cjs → OpenApiOperation-DIWGdw29.cjs} +595 -290
  8. package/output/OpenApiOperation-DIWGdw29.cjs.map +1 -0
  9. package/output/{PageActions-DaXQgMYP.js → PageActions-B_tSec1f.js} +282 -197
  10. package/output/PageActions-B_tSec1f.js.map +1 -0
  11. package/output/{PageActions-GI1t-JrR.cjs → PageActions-DEuFHgyB.cjs} +280 -201
  12. package/output/PageActions-DEuFHgyB.cjs.map +1 -0
  13. package/output/app/SectionProvider.d.ts +1 -1
  14. package/output/client.cjs +3 -3
  15. package/output/client.js +3 -3
  16. package/output/components/Tabs.d.ts +16 -0
  17. package/output/components/index.d.ts +1 -0
  18. package/output/core/i18n.d.ts +1 -1
  19. package/output/core/types.d.ts +1 -0
  20. package/output/index.cjs +4 -4
  21. package/output/index.js +4 -4
  22. package/output/openapi/components/CodeDisplay.d.ts +25 -0
  23. package/output/openapi/components/EndpointSections.d.ts +6 -0
  24. package/output/openapi/components/ExamplePanels.d.ts +10 -17
  25. package/output/openapi/components/OpenApiOperation.d.ts +6 -0
  26. package/output/openapi/components/OpenApiOperation.state.d.ts +43 -0
  27. package/output/openapi/components/SchemaProperties.d.ts +2 -0
  28. package/output/openapi/components/SelectControl.d.ts +15 -0
  29. package/output/openapi/components/helpers.d.ts +22 -0
  30. package/output/preview.cjs +114 -67
  31. package/output/preview.cjs.map +1 -1
  32. package/output/preview.js +114 -67
  33. package/output/preview.js.map +1 -1
  34. package/output/{render-r9DclX3Y.cjs → render-BCGK1WpS.cjs} +2 -2
  35. package/output/{render-r9DclX3Y.cjs.map → render-BCGK1WpS.cjs.map} +1 -1
  36. package/output/{render-yBo2SUlA.js → render-CEWLJSmt.js} +2 -2
  37. package/output/{render-yBo2SUlA.js.map → render-CEWLJSmt.js.map} +1 -1
  38. package/output/renderer.css +207 -104
  39. package/output/server.cjs +2 -2
  40. package/output/server.js +2 -2
  41. package/output/shell/Header.d.ts +2 -0
  42. package/package.json +1 -1
  43. package/output/ClarifyShell-291_IXxJ.js.map +0 -1
  44. package/output/ClarifyShell-DJ4fOVOd.cjs.map +0 -1
  45. package/output/OpenApiOperation-3DUVruIO.cjs.map +0 -1
  46. package/output/OpenApiOperation-E8lSLsSK.js.map +0 -1
  47. package/output/PageActions-DaXQgMYP.js.map +0 -1
  48. package/output/PageActions-GI1t-JrR.cjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-DakpK96I.cjs");
2
- const require_PageActions = require("./PageActions-GI1t-JrR.cjs");
2
+ const require_PageActions = require("./PageActions-DEuFHgyB.cjs");
3
3
  let clsx = require("clsx");
4
4
  clsx = require_chunk.__toESM(clsx, 1);
5
5
  let react = require("react");
@@ -110,6 +110,15 @@ function LazySlotComponent(props) {
110
110
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, {});
111
111
  }
112
112
  //#endregion
113
+ //#region source/utils/hash.ts
114
+ function safeDecodeURIComponent(value) {
115
+ try {
116
+ return decodeURIComponent(value);
117
+ } catch {
118
+ return value;
119
+ }
120
+ }
121
+ //#endregion
113
122
  //#region source/assets/clarify.svg?url
114
123
  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";
115
124
  //#endregion
@@ -621,12 +630,25 @@ function resolveRouteComponent(route) {
621
630
  }
622
631
  function scrollToHash(hash) {
623
632
  if (!hash) return;
624
- const targetId = require_PageActions.safeDecodeURIComponent(hash.slice(1));
625
- window.requestAnimationFrame(() => {
626
- document.getElementById(targetId)?.scrollIntoView();
633
+ const targetId = safeDecodeURIComponent(hash.slice(1));
634
+ const tryScrollToTarget = (attempt = 0) => {
635
+ const target = document.getElementById(targetId);
636
+ if (!target) {
637
+ if (attempt < 12) window.requestAnimationFrame(() => {
638
+ tryScrollToTarget(attempt + 1);
639
+ });
640
+ return;
641
+ }
642
+ target.scrollIntoView({
643
+ behavior: "smooth",
644
+ block: "start"
645
+ });
627
646
  window.requestAnimationFrame(() => {
628
647
  window.dispatchEvent(new Event("scroll"));
629
648
  });
649
+ };
650
+ window.requestAnimationFrame(() => {
651
+ tryScrollToTarget();
630
652
  });
631
653
  }
632
654
  function explicitLocaleForPath(config, pathname) {
@@ -715,7 +737,7 @@ function emptySubscribe() {
715
737
  return () => {};
716
738
  }
717
739
  function useStoredBannerDismissed(storageKey) {
718
- return (0, react.useSyncExternalStore)(emptySubscribe, () => Boolean(storageKey && window.localStorage.getItem(storageKey) === "1"), () => false);
740
+ return (0, react.useSyncExternalStore)(emptySubscribe, () => Boolean(storageKey && window.localStorage.getItem(storageKey) === "1"), () => true);
719
741
  }
720
742
  function useBannerState(config, currentLocale) {
721
743
  const banner = config.banner;
@@ -732,13 +754,11 @@ function useBannerState(config, currentLocale) {
732
754
  dismissBanner: () => setDismissedBannerKey(activeBannerKey)
733
755
  };
734
756
  }
735
- function useStoredLocalePreference(explicitLocale) {
757
+ function useAppShellNavigationEffects(arg0) {
758
+ const { config, currentRoute, explicitLocale, location, navigate, pathname, storedLocale } = arg0;
736
759
  (0, react.useEffect)(() => {
737
760
  if (explicitLocale) require_PageActions.storeLocalePreference(explicitLocale);
738
761
  }, [explicitLocale]);
739
- }
740
- function useStoredLocaleRedirect(arg0) {
741
- const { config, currentRoute, explicitLocale, location, navigate, pathname, storedLocale } = arg0;
742
762
  (0, react.useEffect)(() => {
743
763
  if (explicitLocale || !storedLocale || isDefaultLocale(config, storedLocale)) return;
744
764
  const localizedPath = currentRoute?.alternates?.[storedLocale];
@@ -754,8 +774,6 @@ function useStoredLocaleRedirect(arg0) {
754
774
  pathname,
755
775
  storedLocale
756
776
  ]);
757
- }
758
- function useRouteScroll(location) {
759
777
  (0, react.useEffect)(() => {
760
778
  if (location.hash) {
761
779
  scrollToHash(location.hash);
@@ -770,40 +788,48 @@ function useRouteScroll(location) {
770
788
  });
771
789
  }, [location.hash, location.pathname]);
772
790
  }
773
- function useDocumentLanguage(currentLocale, currentLocaleConfig) {
791
+ function useAppShellDocumentEffects(arg0) {
792
+ const { currentLocale, currentLocaleConfig, config, route } = arg0;
774
793
  (0, react.useEffect)(() => {
775
794
  if (!currentLocale) return;
776
795
  document.documentElement.lang = currentLocale;
777
796
  if (currentLocaleConfig?.dir) document.documentElement.dir = currentLocaleConfig.dir;
778
797
  else document.documentElement.removeAttribute("dir");
779
798
  }, [currentLocale, currentLocaleConfig?.dir]);
780
- }
781
- function useDocumentMetadata(config, route) {
782
799
  (0, react.useEffect)(() => {
783
800
  applyDocumentMetadata(config, route);
784
801
  }, [config, route]);
785
802
  }
786
- function headerOffsetForLayout(hasTabs, hasBanner) {
787
- if (hasTabs && hasBanner) return "10rem";
788
- if (hasTabs) return "7rem";
789
- if (hasBanner) return "6.5rem";
790
- return "3.5rem";
791
- }
792
- function sidebarScrollClassName(hasTabs, hasBanner) {
793
- const classNames = ["clarify-sidebar-scroll lg:sticky lg:z-30 lg:overflow-y-auto lg:pb-8"];
794
- if (hasTabs && hasBanner) classNames.push("lg:top-40 lg:h-(--clarify-sidebar-height-with-tabs-and-banner) lg:pt-10");
795
- else if (hasTabs) classNames.push("lg:top-28 lg:h-(--clarify-sidebar-height-with-tabs) lg:pt-10");
796
- else if (hasBanner) classNames.push("lg:top-26 lg:h-(--clarify-sidebar-height-with-banner) lg:pt-10");
797
- else classNames.push("lg:top-14 lg:h-(--clarify-sidebar-height) lg:pt-10");
798
- return (0, clsx.default)(classNames);
799
- }
800
- function contentClassName(hasTabs, hasBanner) {
801
- const classNames = ["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"];
802
- if (hasTabs && hasBanner) classNames.push("pt-26 lg:pt-40");
803
- else if (hasTabs) classNames.push("pt-14 lg:pt-28");
804
- else if (hasBanner) classNames.push("pt-26");
805
- else classNames.push("pt-14");
806
- return (0, clsx.default)(classNames);
803
+ var appShellLayoutConfig = {
804
+ base: {
805
+ headerOffset: "3.5rem",
806
+ sidebarScrollClassName: "lg:top-14 lg:h-(--clarify-sidebar-height) lg:pt-10",
807
+ contentClassName: "pt-14"
808
+ },
809
+ banner: {
810
+ headerOffset: "6.5rem",
811
+ sidebarScrollClassName: "lg:top-26 lg:h-(--clarify-sidebar-height-with-banner) lg:pt-10",
812
+ contentClassName: "pt-26"
813
+ },
814
+ tabs: {
815
+ headerOffset: "7rem",
816
+ sidebarScrollClassName: "lg:top-28 lg:h-(--clarify-sidebar-height-with-tabs) lg:pt-10",
817
+ contentClassName: "pt-14 lg:pt-28"
818
+ },
819
+ "tabs-banner": {
820
+ headerOffset: "10rem",
821
+ sidebarScrollClassName: "lg:top-40 lg:h-(--clarify-sidebar-height-with-tabs-and-banner) lg:pt-10",
822
+ contentClassName: "pt-26 lg:pt-40"
823
+ }
824
+ };
825
+ function getLayoutVariant(hasTabs, hasBanner) {
826
+ if (hasTabs && hasBanner) return "tabs-banner";
827
+ if (hasTabs) return "tabs";
828
+ if (hasBanner) return "banner";
829
+ return "base";
830
+ }
831
+ function getAppShellLayoutConfig(hasTabs, hasBanner) {
832
+ return appShellLayoutConfig[getLayoutVariant(hasTabs, hasBanner)];
807
833
  }
808
834
  function BuiltInNotFoundPage() {
809
835
  const text = require_PageActions.useBuiltInText();
@@ -846,13 +872,13 @@ function AppShell(arg0) {
846
872
  const navigate = (0, react_router_dom.useNavigate)();
847
873
  const pathname = require_PageActions.normalizeRoutePath(location.pathname);
848
874
  const headerRef = (0, react.useRef)(null);
875
+ const headerTopAreaRef = (0, react.useRef)(null);
849
876
  const { currentRoute, explicitLocale, storedLocale, currentLocale, currentLocaleConfig, notFoundRoute, currentNavigation, sections } = useRouteState(config, routes, navigation, pathname);
850
877
  const text = require_PageActions.useBuiltInText(currentLocale);
851
878
  const { activeBannerKey, bannerResolved, dismissedBannerKey, hasBanner, dismissBanner } = useBannerState(config, currentLocale);
852
- const hasTabs = Boolean(currentNavigation.tabs?.length);
879
+ const layoutConfig = getAppShellLayoutConfig(Boolean(currentNavigation.tabs?.length), hasBanner);
853
880
  const { renderRoutes, NotFoundRouteComponent } = useRenderedRoutes(routes, notFoundRoute);
854
- useStoredLocalePreference(explicitLocale);
855
- useStoredLocaleRedirect({
881
+ useAppShellNavigationEffects({
856
882
  config,
857
883
  currentRoute,
858
884
  explicitLocale,
@@ -861,10 +887,13 @@ function AppShell(arg0) {
861
887
  pathname,
862
888
  storedLocale
863
889
  });
864
- useRouteScroll(location);
865
- useDocumentLanguage(currentLocale, currentLocaleConfig);
866
- useDocumentMetadata(config, currentRoute ?? notFoundRoute);
867
- const layoutStyle = { "--clarify-header-offset": headerOffsetForLayout(hasTabs, hasBanner) };
890
+ useAppShellDocumentEffects({
891
+ currentLocale,
892
+ currentLocaleConfig,
893
+ config,
894
+ route: currentRoute ?? notFoundRoute
895
+ });
896
+ const layoutStyle = { "--clarify-header-offset": layoutConfig.headerOffset };
868
897
  function renderBannerSlot() {
869
898
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BannerSlot, {
870
899
  activeBannerKey,
@@ -878,6 +907,7 @@ function AppShell(arg0) {
878
907
  function renderHeader() {
879
908
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_PageActions.Header, {
880
909
  ref: headerRef,
910
+ topAreaRef: headerTopAreaRef,
881
911
  config,
882
912
  navigation: currentNavigation.items,
883
913
  tabs: currentNavigation.tabs,
@@ -892,7 +922,7 @@ function AppShell(arg0) {
892
922
  "data-pagefind-ignore": true,
893
923
  className: "clarify-sidebar hidden lg:block lg:self-stretch lg:bg-(--clarify-theme-tokens-colors-background) lg:px-5 xl:px-6",
894
924
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
895
- className: sidebarScrollClassName(hasTabs, hasBanner),
925
+ className: (0, clsx.default)("clarify-sidebar-scroll lg:sticky lg:z-30 lg:overflow-y-auto lg:pb-8", layoutConfig.sidebarScrollClassName),
896
926
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_PageActions.Navigation, { navigation: currentNavigation.items })
897
927
  })
898
928
  });
@@ -946,7 +976,7 @@ function AppShell(arg0) {
946
976
  }
947
977
  function renderContent() {
948
978
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
949
- className: contentClassName(hasTabs, hasBanner),
979
+ className: (0, clsx.default)("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),
950
980
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_PageActions.PageActionsProvider, {
951
981
  route: currentRoute,
952
982
  routePrefix: config.routePrefix,
@@ -975,7 +1005,7 @@ function AppShell(arg0) {
975
1005
  route: currentRoute,
976
1006
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_PageActions.SectionProvider, {
977
1007
  sections,
978
- headerRef,
1008
+ headerTopAreaRef,
979
1009
  children: [renderHeader(), renderLayout()]
980
1010
  })
981
1011
  })
@@ -2032,10 +2062,8 @@ function themeToConfigSource(theme) {
2032
2062
  layout: theme.layout
2033
2063
  } }, null, 2);
2034
2064
  }
2035
- function ThemeEditor(props) {
2036
- const { initialTheme, onChange, target, defaultOpen = false, className } = props;
2037
- const { resolvedTheme } = require_PageActions.useTheme();
2038
- const [isOpen, setIsOpen] = (0, react.useState)(defaultOpen);
2065
+ function useThemeEditorState(arg0) {
2066
+ const { initialTheme, onChange, target, resolvedTheme } = arg0;
2039
2067
  const [theme, setTheme] = (0, react.useState)(() => cloneTheme(initialTheme ?? themeEditorPresets.default));
2040
2068
  const [copyState, setCopyState] = (0, react.useState)("idle");
2041
2069
  const configSource = (0, react.useMemo)(() => themeToConfigSource(theme), [theme]);
@@ -2094,122 +2122,156 @@ function ThemeEditor(props) {
2094
2122
  window.setTimeout(() => setCopyState("idle"), 1400);
2095
2123
  }
2096
2124
  }
2097
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2098
- className: (0, clsx.default)("clarify-theme-editor fixed right-4 bottom-4 z-50 text-(--clarify-theme-tokens-colors-foreground)", className),
2099
- children: [isOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2125
+ return {
2126
+ theme,
2127
+ copyState,
2128
+ commit,
2129
+ updatePreset,
2130
+ updateColorToken,
2131
+ updateRadiusToken,
2132
+ updateLayoutToken,
2133
+ copyConfig
2134
+ };
2135
+ }
2136
+ function ThemeEditor(props) {
2137
+ const { initialTheme, onChange, target, defaultOpen = false, className } = props;
2138
+ const { resolvedTheme } = require_PageActions.useTheme();
2139
+ const [isOpen, setIsOpen] = (0, react.useState)(defaultOpen);
2140
+ const { theme, copyState, commit, updatePreset, updateColorToken, updateRadiusToken, updateLayoutToken, copyConfig } = useThemeEditorState({
2141
+ initialTheme,
2142
+ onChange,
2143
+ target,
2144
+ resolvedTheme
2145
+ });
2146
+ function renderPanelHeader() {
2147
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
2148
+ className: "shrink-0 flex items-start justify-between gap-4 border-b border-(--clarify-theme-tokens-colors-border) px-4 py-3",
2149
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
2150
+ className: "text-sm/6 font-semibold text-(--clarify-theme-tokens-colors-foreground)",
2151
+ children: "Theme editor"
2152
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2153
+ className: "mt-0.5 text-xs/5 text-(--clarify-ui-text-soft)",
2154
+ children: "Live CSS variable preview for Clarify theme tokens."
2155
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2156
+ type: "button",
2157
+ className: "-mr-1 flex size-8 items-center justify-center rounded-(--clarify-theme-tokens-radius-md) text-(--clarify-ui-text-soft) transition hover:bg-(--clarify-ui-hover-background) hover:text-(--clarify-ui-text-strong)",
2158
+ "aria-label": "Close theme editor",
2159
+ onClick: () => setIsOpen(false),
2160
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, { className: "size-4 stroke-current stroke-2" })
2161
+ })]
2162
+ });
2163
+ }
2164
+ function renderPanelBody() {
2165
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2166
+ className: "min-h-0 flex-1 overflow-y-auto px-4 py-4",
2167
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2168
+ className: "grid gap-5",
2169
+ children: [
2170
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2171
+ htmlFor: "clarify-theme-editor-preset",
2172
+ className: "grid gap-1.5 text-xs/5 font-medium text-(--clarify-ui-text)",
2173
+ children: ["Preset", /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2174
+ className: "relative block",
2175
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
2176
+ id: "clarify-theme-editor-preset",
2177
+ value: theme.preset,
2178
+ 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)",
2179
+ onChange: (event) => updatePreset(event.target.value),
2180
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2181
+ value: "default",
2182
+ children: "default"
2183
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2184
+ value: "base",
2185
+ children: "base"
2186
+ })]
2187
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.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)" })]
2188
+ })]
2189
+ }),
2190
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
2191
+ className: "grid gap-3",
2192
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", {
2193
+ className: "mb-2 text-xs/5 font-semibold uppercase tracking-wide text-(--clarify-ui-text-faint)",
2194
+ children: "Colors"
2195
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2196
+ className: "grid grid-cols-1 gap-3",
2197
+ children: colorTokenFields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ColorField, {
2198
+ id: `clarify-theme-editor-color-${field.key}`,
2199
+ label: field.label,
2200
+ value: theme.tokens.colors[field.key],
2201
+ onChange: (mode, value) => updateColorToken(field.key, mode, value)
2202
+ }, field.key))
2203
+ })]
2204
+ }),
2205
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
2206
+ className: "grid gap-3",
2207
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", {
2208
+ className: "mb-2 text-xs/5 font-semibold uppercase tracking-wide text-(--clarify-ui-text-faint)",
2209
+ children: "Radius"
2210
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2211
+ className: "grid grid-cols-2 gap-3",
2212
+ children: radiusTokenFields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextField, {
2213
+ id: `clarify-theme-editor-radius-${field.key}`,
2214
+ label: field.label,
2215
+ value: theme.tokens.radius[field.key],
2216
+ onChange: (value) => updateRadiusToken(field.key, value)
2217
+ }, field.key))
2218
+ })]
2219
+ }),
2220
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
2221
+ className: "grid gap-3",
2222
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", {
2223
+ className: "mb-2 text-xs/5 font-semibold uppercase tracking-wide text-(--clarify-ui-text-faint)",
2224
+ children: "Layout"
2225
+ }), layoutFields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextField, {
2226
+ id: `clarify-theme-editor-layout-${field.key}`,
2227
+ label: field.label,
2228
+ value: theme.layout[field.key],
2229
+ onChange: (value) => updateLayoutToken(field.key, value)
2230
+ }, field.key))]
2231
+ })
2232
+ ]
2233
+ })
2234
+ });
2235
+ }
2236
+ function renderPanelFooter() {
2237
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("footer", {
2238
+ className: "shrink-0 flex items-center justify-between gap-3 border-t border-(--clarify-theme-tokens-colors-border) bg-(--clarify-ui-subtle-background) px-4 py-3",
2239
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2240
+ className: "flex items-center gap-1.5",
2241
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2242
+ type: "button",
2243
+ className: "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)",
2244
+ onClick: () => updatePreset(theme.preset),
2245
+ children: "Reset preset"
2246
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2247
+ type: "button",
2248
+ 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)",
2249
+ onClick: () => commit(createRandomTheme()),
2250
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.WandSparkles, { className: "size-3.5 stroke-current stroke-2" }), "Random"]
2251
+ })]
2252
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2253
+ type: "button",
2254
+ className: "rounded-(--clarify-theme-tokens-radius-md) bg-(--clarify-theme-tokens-colors-primary) px-3 py-1.5 text-xs/5 font-semibold text-white shadow-xs transition hover:opacity-90",
2255
+ onClick: copyConfig,
2256
+ children: copyState === "copied" ? "Copied" : copyState === "failed" ? "Copy failed" : "Copy config"
2257
+ })]
2258
+ });
2259
+ }
2260
+ function renderEditorPanel() {
2261
+ if (!isOpen) return null;
2262
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2100
2263
  className: "mb-3 flex max-h-(--clarify-theme-editor-panel-max-height) w-(--clarify-theme-editor-width) flex-col overflow-hidden rounded-md border border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-surface)/95 shadow-2xl shadow-zinc-900/15 backdrop-blur",
2101
2264
  "aria-label": "Clarify theme editor",
2102
2265
  children: [
2103
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
2104
- className: "shrink-0 flex items-start justify-between gap-4 border-b border-(--clarify-theme-tokens-colors-border) px-4 py-3",
2105
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
2106
- className: "text-sm/6 font-semibold text-(--clarify-theme-tokens-colors-foreground)",
2107
- children: "Theme editor"
2108
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2109
- className: "mt-0.5 text-xs/5 text-(--clarify-ui-text-soft)",
2110
- children: "Live CSS variable preview for Clarify theme tokens."
2111
- })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2112
- type: "button",
2113
- className: "-mr-1 flex size-8 items-center justify-center rounded-(--clarify-theme-tokens-radius-md) text-(--clarify-ui-text-soft) transition hover:bg-(--clarify-ui-hover-background) hover:text-(--clarify-ui-text-strong)",
2114
- "aria-label": "Close theme editor",
2115
- onClick: () => setIsOpen(false),
2116
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, { className: "size-4 stroke-current stroke-2" })
2117
- })]
2118
- }),
2119
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2120
- className: "min-h-0 flex-1 overflow-y-auto px-4 py-4",
2121
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2122
- className: "grid gap-5",
2123
- children: [
2124
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2125
- htmlFor: "clarify-theme-editor-preset",
2126
- className: "grid gap-1.5 text-xs/5 font-medium text-(--clarify-ui-text)",
2127
- children: ["Preset", /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2128
- className: "relative block",
2129
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
2130
- id: "clarify-theme-editor-preset",
2131
- value: theme.preset,
2132
- 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)",
2133
- onChange: (event) => updatePreset(event.target.value),
2134
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2135
- value: "default",
2136
- children: "default"
2137
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2138
- value: "base",
2139
- children: "base"
2140
- })]
2141
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.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)" })]
2142
- })]
2143
- }),
2144
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
2145
- className: "grid gap-3",
2146
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", {
2147
- className: "mb-2 text-xs/5 font-semibold uppercase tracking-wide text-(--clarify-ui-text-faint)",
2148
- children: "Colors"
2149
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2150
- className: "grid grid-cols-1 gap-3",
2151
- children: colorTokenFields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ColorField, {
2152
- id: `clarify-theme-editor-color-${field.key}`,
2153
- label: field.label,
2154
- value: theme.tokens.colors[field.key],
2155
- onChange: (mode, value) => updateColorToken(field.key, mode, value)
2156
- }, field.key))
2157
- })]
2158
- }),
2159
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
2160
- className: "grid gap-3",
2161
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", {
2162
- className: "mb-2 text-xs/5 font-semibold uppercase tracking-wide text-(--clarify-ui-text-faint)",
2163
- children: "Radius"
2164
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2165
- className: "grid grid-cols-2 gap-3",
2166
- children: radiusTokenFields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextField, {
2167
- id: `clarify-theme-editor-radius-${field.key}`,
2168
- label: field.label,
2169
- value: theme.tokens.radius[field.key],
2170
- onChange: (value) => updateRadiusToken(field.key, value)
2171
- }, field.key))
2172
- })]
2173
- }),
2174
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
2175
- className: "grid gap-3",
2176
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", {
2177
- className: "mb-2 text-xs/5 font-semibold uppercase tracking-wide text-(--clarify-ui-text-faint)",
2178
- children: "Layout"
2179
- }), layoutFields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextField, {
2180
- id: `clarify-theme-editor-layout-${field.key}`,
2181
- label: field.label,
2182
- value: theme.layout[field.key],
2183
- onChange: (value) => updateLayoutToken(field.key, value)
2184
- }, field.key))]
2185
- })
2186
- ]
2187
- })
2188
- }),
2189
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("footer", {
2190
- className: "shrink-0 flex items-center justify-between gap-3 border-t border-(--clarify-theme-tokens-colors-border) bg-(--clarify-ui-subtle-background) px-4 py-3",
2191
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2192
- className: "flex items-center gap-1.5",
2193
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2194
- type: "button",
2195
- className: "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)",
2196
- onClick: () => updatePreset(theme.preset),
2197
- children: "Reset preset"
2198
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2199
- type: "button",
2200
- 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)",
2201
- onClick: () => commit(createRandomTheme()),
2202
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.WandSparkles, { className: "size-3.5 stroke-current stroke-2" }), "Random"]
2203
- })]
2204
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2205
- type: "button",
2206
- className: "rounded-(--clarify-theme-tokens-radius-md) bg-(--clarify-theme-tokens-colors-primary) px-3 py-1.5 text-xs/5 font-semibold text-white shadow-xs transition hover:opacity-90",
2207
- onClick: copyConfig,
2208
- children: copyState === "copied" ? "Copied" : copyState === "failed" ? "Copy failed" : "Copy config"
2209
- })]
2210
- })
2266
+ renderPanelHeader(),
2267
+ renderPanelBody(),
2268
+ renderPanelFooter()
2211
2269
  ]
2212
- }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2270
+ });
2271
+ }
2272
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2273
+ className: (0, clsx.default)("clarify-theme-editor fixed right-4 bottom-4 z-50 text-(--clarify-theme-tokens-colors-foreground)", className),
2274
+ children: [renderEditorPanel(), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2213
2275
  type: "button",
2214
2276
  className: "ml-auto flex size-12 items-center justify-center rounded-full border border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-surface)/95 text-(--clarify-theme-tokens-colors-primary) shadow-xl shadow-zinc-900/15 backdrop-blur transition hover:scale-105 hover:bg-(--clarify-ui-accent-background) focus:outline-none focus:ring-2 focus:ring-(--clarify-ui-accent-border)",
2215
2277
  "aria-label": isOpen ? "Close Clarify theme editor" : "Open Clarify theme editor",
@@ -2353,4 +2415,4 @@ Object.defineProperty(exports, "useSlot", {
2353
2415
  }
2354
2416
  });
2355
2417
 
2356
- //# sourceMappingURL=ClarifyShell-DJ4fOVOd.cjs.map
2418
+ //# sourceMappingURL=ClarifyShell-Dm--LZco.cjs.map