@clarify-labs/renderer 0.9.0 → 0.9.2

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 (43) hide show
  1. package/output/{ClarifyShell-BPv2bxI4.js → ClarifyShell-C38EkErX.js} +397 -250
  2. package/output/ClarifyShell-C38EkErX.js.map +1 -0
  3. package/output/{ClarifyShell-B74Fq4UU.cjs → ClarifyShell-DdYRgrfY.cjs} +396 -249
  4. package/output/ClarifyShell-DdYRgrfY.cjs.map +1 -0
  5. package/output/{OpenApiOperation-BMXfV15v.cjs → OpenApiOperation-CP_fxT_F.cjs} +344 -219
  6. package/output/OpenApiOperation-CP_fxT_F.cjs.map +1 -0
  7. package/output/{OpenApiOperation-fJ3QQOJX.js → OpenApiOperation-DIFaYAe5.js} +344 -219
  8. package/output/OpenApiOperation-DIFaYAe5.js.map +1 -0
  9. package/output/{PageActions-DOKkt2zo.cjs → PageActions-B08cDCzq.cjs} +278 -167
  10. package/output/PageActions-B08cDCzq.cjs.map +1 -0
  11. package/output/{PageActions-BwY7ierv.js → PageActions-tmnpzi23.js} +279 -168
  12. package/output/PageActions-tmnpzi23.js.map +1 -0
  13. package/output/app/SectionProvider.d.ts +1 -0
  14. package/output/client.cjs +3 -3
  15. package/output/client.js +3 -3
  16. package/output/core/types.d.ts +1 -0
  17. package/output/index.cjs +4 -4
  18. package/output/index.js +4 -4
  19. package/output/openapi/components/CodeDisplay.d.ts +25 -0
  20. package/output/openapi/components/EndpointSections.d.ts +4 -0
  21. package/output/openapi/components/ExamplePanels.d.ts +8 -17
  22. package/output/openapi/components/OpenApiOperation.state.d.ts +43 -0
  23. package/output/openapi/components/SelectControl.d.ts +15 -0
  24. package/output/openapi/components/helpers.d.ts +22 -0
  25. package/output/preview.cjs +114 -67
  26. package/output/preview.cjs.map +1 -1
  27. package/output/preview.js +114 -67
  28. package/output/preview.js.map +1 -1
  29. package/output/{render-Cghgq1AQ.js → render-6gHfrR9h.js} +2 -2
  30. package/output/{render-Cghgq1AQ.js.map → render-6gHfrR9h.js.map} +1 -1
  31. package/output/{render-ZSckbg74.cjs → render-Bvf5ZMZb.cjs} +2 -2
  32. package/output/{render-ZSckbg74.cjs.map → render-Bvf5ZMZb.cjs.map} +1 -1
  33. package/output/renderer.css +168 -107
  34. package/output/server.cjs +2 -2
  35. package/output/server.js +2 -2
  36. package/output/shell/Header.d.ts +2 -0
  37. package/package.json +1 -1
  38. package/output/ClarifyShell-B74Fq4UU.cjs.map +0 -1
  39. package/output/ClarifyShell-BPv2bxI4.js.map +0 -1
  40. package/output/OpenApiOperation-BMXfV15v.cjs.map +0 -1
  41. package/output/OpenApiOperation-fJ3QQOJX.js.map +0 -1
  42. package/output/PageActions-BwY7ierv.js.map +0 -1
  43. package/output/PageActions-DOKkt2zo.cjs.map +0 -1
@@ -1,6 +1,6 @@
1
- import { A as LocaleContext, C as themeCookieName, D as copyTextToClipboard, M as useConfig, N as useLocale, O as useBuiltInText, T as localizeHref, _ as getStoredLocalePreference, a as safeDecodeURIComponent, d as isSameRoutePath, f as normalizeRoutePath, g as useTheme, h as ThemeProvider, i as Navigation, j as OpenApisContext, k as ConfigContext, o as SectionProvider, p as resolveLocalizedText, r as Header, t as PageActionsProvider, w as isExternalHref, x as storeLocalePreference } from "./PageActions-BwY7ierv.js";
1
+ import { A as LocaleContext, C as themeCookieName, D as copyTextToClipboard, M as useConfig, N as useLocale, O as useBuiltInText, T as localizeHref, _ as getStoredLocalePreference, a as safeDecodeURIComponent, d as isSameRoutePath, f as normalizeRoutePath, g as useTheme, h as ThemeProvider, i as Navigation, j as OpenApisContext, k as ConfigContext, o as SectionProvider, p as resolveLocalizedText, r as Header, t as PageActionsProvider, w as isExternalHref, x as storeLocalePreference } from "./PageActions-tmnpzi23.js";
2
2
  import clsx from "clsx";
3
- import { Component, Suspense, createContext, lazy, useContext, useEffect, useMemo, useState } from "react";
3
+ import { Component, Suspense, createContext, lazy, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
4
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";
@@ -580,9 +580,9 @@ function PageSkeleton() {
580
580
  //#endregion
581
581
  //#region source/app/AppShell.tsx
582
582
  function BannerSlot(props) {
583
- const { activeBannerKey, dismissedBannerKey, onDismiss, config, locale } = props;
583
+ const { activeBannerKey, dismissedBannerKey, bannerResolved, onDismiss, config, locale } = props;
584
584
  function DefaultBannerComponent() {
585
- if (!(Boolean(config.banner) && dismissedBannerKey !== activeBannerKey)) return null;
585
+ if (!(bannerResolved && Boolean(config.banner) && dismissedBannerKey !== activeBannerKey)) return null;
586
586
  return /* @__PURE__ */ jsx(PageBanner, {
587
587
  currentLocale: locale,
588
588
  onDismiss
@@ -683,6 +683,130 @@ function applyDocumentMetadata(config, route) {
683
683
  setNamedMeta("description", route?.description ?? config.description);
684
684
  setNamedMeta("keywords", route?.keywords?.join(", "));
685
685
  }
686
+ function useRouteState(config, routes, navigation, pathname) {
687
+ const currentRoute = routeForPath(routes, pathname);
688
+ const explicitLocale = explicitLocaleForPath(config, pathname);
689
+ const storedLocale = storedLocaleForConfig(config);
690
+ const currentLocale = explicitLocale ?? storedLocale ?? fallbackLocale(config);
691
+ return {
692
+ currentRoute,
693
+ explicitLocale,
694
+ storedLocale,
695
+ currentLocale,
696
+ currentLocaleConfig: config.i18n?.locales.find((locale) => locale.code === currentLocale),
697
+ notFoundRoute: currentRoute ? void 0 : notFoundRouteForPath(routes, pathname, currentLocale),
698
+ currentNavigation: navigationForLocale(navigation, currentLocale, pathname),
699
+ sections: sectionsForRoute(currentRoute)
700
+ };
701
+ }
702
+ function useRenderedRoutes(routes, notFoundRoute) {
703
+ const renderRoutes = useMemo(() => routes.map((route) => ({
704
+ ...route,
705
+ component: resolveRouteComponent(route)
706
+ })), [routes]);
707
+ return {
708
+ renderRoutes,
709
+ NotFoundRouteComponent: notFoundRoute ? renderRoutes.find((route) => isSameRoutePath(route.path, notFoundRoute.path))?.component : void 0
710
+ };
711
+ }
712
+ function emptySubscribe() {
713
+ return () => {};
714
+ }
715
+ function useStoredBannerDismissed(storageKey) {
716
+ return useSyncExternalStore(emptySubscribe, () => Boolean(storageKey && window.localStorage.getItem(storageKey) === "1"), () => true);
717
+ }
718
+ function useBannerState(config, currentLocale) {
719
+ const banner = config.banner;
720
+ const bannerContent = banner ? resolveLocalizedText(banner.content, currentLocale, config.i18n?.defaultLocale) : "";
721
+ const bannerStorageKey = banner && bannerContent ? `clarify:banner:dismissed:${config.title}:${bannerContent}` : void 0;
722
+ const storedBannerDismissed = useStoredBannerDismissed(banner?.dismissible ? bannerStorageKey : void 0);
723
+ const [dismissedBannerKey, setDismissedBannerKey] = useState();
724
+ const activeBannerKey = banner ? JSON.stringify(banner) : void 0;
725
+ return {
726
+ activeBannerKey,
727
+ bannerResolved: !banner?.dismissible || !storedBannerDismissed,
728
+ dismissedBannerKey,
729
+ hasBanner: Boolean(banner && bannerContent) && !storedBannerDismissed && dismissedBannerKey !== activeBannerKey,
730
+ dismissBanner: () => setDismissedBannerKey(activeBannerKey)
731
+ };
732
+ }
733
+ function useAppShellNavigationEffects(arg0) {
734
+ const { config, currentRoute, explicitLocale, location, navigate, pathname, storedLocale } = arg0;
735
+ useEffect(() => {
736
+ if (explicitLocale) storeLocalePreference(explicitLocale);
737
+ }, [explicitLocale]);
738
+ useEffect(() => {
739
+ if (explicitLocale || !storedLocale || isDefaultLocale(config, storedLocale)) return;
740
+ const localizedPath = currentRoute?.alternates?.[storedLocale];
741
+ if (!localizedPath || isSameRoutePath(localizedPath, pathname)) return;
742
+ navigate(`${localizedPath}${location.search}${location.hash}`, { replace: true });
743
+ }, [
744
+ config,
745
+ currentRoute,
746
+ explicitLocale,
747
+ location.hash,
748
+ location.search,
749
+ navigate,
750
+ pathname,
751
+ storedLocale
752
+ ]);
753
+ useEffect(() => {
754
+ if (location.hash) {
755
+ scrollToHash(location.hash);
756
+ return;
757
+ }
758
+ window.scrollTo({
759
+ top: 0,
760
+ left: 0
761
+ });
762
+ window.requestAnimationFrame(() => {
763
+ window.dispatchEvent(new Event("scroll"));
764
+ });
765
+ }, [location.hash, location.pathname]);
766
+ }
767
+ function useAppShellDocumentEffects(arg0) {
768
+ const { currentLocale, currentLocaleConfig, config, route } = arg0;
769
+ useEffect(() => {
770
+ if (!currentLocale) return;
771
+ document.documentElement.lang = currentLocale;
772
+ if (currentLocaleConfig?.dir) document.documentElement.dir = currentLocaleConfig.dir;
773
+ else document.documentElement.removeAttribute("dir");
774
+ }, [currentLocale, currentLocaleConfig?.dir]);
775
+ useEffect(() => {
776
+ applyDocumentMetadata(config, route);
777
+ }, [config, route]);
778
+ }
779
+ var appShellLayoutConfig = {
780
+ base: {
781
+ headerOffset: "3.5rem",
782
+ sidebarScrollClassName: "lg:top-14 lg:h-(--clarify-sidebar-height) lg:pt-10",
783
+ contentClassName: "pt-14"
784
+ },
785
+ banner: {
786
+ headerOffset: "6.5rem",
787
+ sidebarScrollClassName: "lg:top-26 lg:h-(--clarify-sidebar-height-with-banner) lg:pt-10",
788
+ contentClassName: "pt-26"
789
+ },
790
+ tabs: {
791
+ headerOffset: "7rem",
792
+ sidebarScrollClassName: "lg:top-28 lg:h-(--clarify-sidebar-height-with-tabs) lg:pt-10",
793
+ contentClassName: "pt-14 lg:pt-28"
794
+ },
795
+ "tabs-banner": {
796
+ headerOffset: "10rem",
797
+ sidebarScrollClassName: "lg:top-40 lg:h-(--clarify-sidebar-height-with-tabs-and-banner) lg:pt-10",
798
+ contentClassName: "pt-26 lg:pt-40"
799
+ }
800
+ };
801
+ function getLayoutVariant(hasTabs, hasBanner) {
802
+ if (hasTabs && hasBanner) return "tabs-banner";
803
+ if (hasTabs) return "tabs";
804
+ if (hasBanner) return "banner";
805
+ return "base";
806
+ }
807
+ function getAppShellLayoutConfig(hasTabs, hasBanner) {
808
+ return appShellLayoutConfig[getLayoutVariant(hasTabs, hasBanner)];
809
+ }
686
810
  function BuiltInNotFoundPage() {
687
811
  const text = useBuiltInText();
688
812
  return /* @__PURE__ */ jsxs("section", {
@@ -723,68 +847,133 @@ function AppShell(arg0) {
723
847
  const location = useLocation();
724
848
  const navigate = useNavigate();
725
849
  const pathname = normalizeRoutePath(location.pathname);
726
- const currentRoute = routeForPath(routes, pathname);
727
- const explicitLocale = explicitLocaleForPath(config, pathname);
728
- const storedLocale = storedLocaleForConfig(config);
729
- const currentLocale = explicitLocale ?? storedLocale ?? fallbackLocale(config);
730
- const currentLocaleConfig = config.i18n?.locales.find((locale) => locale.code === currentLocale);
731
- const notFoundRoute = currentRoute ? void 0 : notFoundRouteForPath(routes, pathname, currentLocale);
850
+ const headerRef = useRef(null);
851
+ const headerTopAreaRef = useRef(null);
852
+ const { currentRoute, explicitLocale, storedLocale, currentLocale, currentLocaleConfig, notFoundRoute, currentNavigation, sections } = useRouteState(config, routes, navigation, pathname);
732
853
  const text = useBuiltInText(currentLocale);
733
- const currentNavigation = navigationForLocale(navigation, currentLocale, pathname);
734
- const sections = sectionsForRoute(currentRoute);
735
- const [dismissedBannerKey, setDismissedBannerKey] = useState();
736
- const activeBannerKey = config.banner ? JSON.stringify(config.banner) : void 0;
737
- const hasBanner = Boolean(config.banner) && dismissedBannerKey !== activeBannerKey;
738
- const hasTabs = Boolean(currentNavigation.tabs?.length);
739
- const renderRoutes = useMemo(() => routes.map((route) => ({
740
- ...route,
741
- component: resolveRouteComponent(route)
742
- })), [routes]);
743
- const NotFoundRouteComponent = notFoundRoute ? renderRoutes.find((route) => isSameRoutePath(route.path, notFoundRoute.path))?.component : void 0;
744
- useEffect(() => {
745
- if (explicitLocale) storeLocalePreference(explicitLocale);
746
- }, [explicitLocale]);
747
- useEffect(() => {
748
- if (explicitLocale || !storedLocale || isDefaultLocale(config, storedLocale)) return;
749
- const localizedPath = currentRoute?.alternates?.[storedLocale];
750
- if (!localizedPath || isSameRoutePath(localizedPath, pathname)) return;
751
- navigate(`${localizedPath}${location.search}${location.hash}`, { replace: true });
752
- }, [
854
+ const { activeBannerKey, bannerResolved, dismissedBannerKey, hasBanner, dismissBanner } = useBannerState(config, currentLocale);
855
+ const layoutConfig = getAppShellLayoutConfig(Boolean(currentNavigation.tabs?.length), hasBanner);
856
+ const { renderRoutes, NotFoundRouteComponent } = useRenderedRoutes(routes, notFoundRoute);
857
+ useAppShellNavigationEffects({
753
858
  config,
754
859
  currentRoute,
755
860
  explicitLocale,
756
- location.hash,
757
- location.search,
861
+ location,
758
862
  navigate,
759
863
  pathname,
760
864
  storedLocale
761
- ]);
762
- useEffect(() => {
763
- if (location.hash) {
764
- scrollToHash(location.hash);
765
- return;
766
- }
767
- window.scrollTo({
768
- top: 0,
769
- left: 0
865
+ });
866
+ useAppShellDocumentEffects({
867
+ currentLocale,
868
+ currentLocaleConfig,
869
+ config,
870
+ route: currentRoute ?? notFoundRoute
871
+ });
872
+ const layoutStyle = { "--clarify-header-offset": layoutConfig.headerOffset };
873
+ function renderBannerSlot() {
874
+ return /* @__PURE__ */ jsx(BannerSlot, {
875
+ activeBannerKey,
876
+ dismissedBannerKey,
877
+ bannerResolved,
878
+ onDismiss: dismissBanner,
879
+ config,
880
+ locale: currentLocale
770
881
  });
771
- window.requestAnimationFrame(() => {
772
- window.dispatchEvent(new Event("scroll"));
882
+ }
883
+ function renderHeader() {
884
+ return /* @__PURE__ */ jsx(Header, {
885
+ ref: headerRef,
886
+ topAreaRef: headerTopAreaRef,
887
+ config,
888
+ navigation: currentNavigation.items,
889
+ tabs: currentNavigation.tabs,
890
+ routes,
891
+ currentLocale,
892
+ currentRoute,
893
+ banner: renderBannerSlot()
773
894
  });
774
- }, [location.hash, location.pathname]);
775
- useEffect(() => {
776
- if (!currentLocale) return;
777
- document.documentElement.lang = currentLocale;
778
- if (currentLocaleConfig?.dir) document.documentElement.dir = currentLocaleConfig.dir;
779
- else document.documentElement.removeAttribute("dir");
780
- }, [currentLocale, currentLocaleConfig?.dir]);
781
- useEffect(() => {
782
- applyDocumentMetadata(config, currentRoute ?? notFoundRoute);
783
- }, [
784
- config,
785
- currentRoute,
786
- notFoundRoute
787
- ]);
895
+ }
896
+ function renderSidebar() {
897
+ return /* @__PURE__ */ jsx("aside", {
898
+ "data-pagefind-ignore": true,
899
+ className: "clarify-sidebar hidden lg:block lg:self-stretch lg:bg-(--clarify-theme-tokens-colors-background) lg:px-5 xl:px-6",
900
+ children: /* @__PURE__ */ jsx("div", {
901
+ className: clsx("clarify-sidebar-scroll lg:sticky lg:z-30 lg:overflow-y-auto lg:pb-8", layoutConfig.sidebarScrollClassName),
902
+ children: /* @__PURE__ */ jsx(Navigation, { navigation: currentNavigation.items })
903
+ })
904
+ });
905
+ }
906
+ function renderRouteElements() {
907
+ return /* @__PURE__ */ jsxs(Routes, { children: [renderRoutes.map((route) => /* @__PURE__ */ jsx(Route, {
908
+ path: route.path,
909
+ element: /* @__PURE__ */ jsx(route.component, {})
910
+ }, route.path)), /* @__PURE__ */ jsx(Route, {
911
+ path: "*",
912
+ element: /* @__PURE__ */ jsx(NotFoundRouteElement, { component: NotFoundRouteComponent })
913
+ })] });
914
+ }
915
+ function renderMain() {
916
+ return /* @__PURE__ */ jsx("main", {
917
+ className: "clarify-main min-w-0 flex-auto",
918
+ "data-pagefind-body": true,
919
+ children: /* @__PURE__ */ jsx(PageErrorBoundary, {
920
+ title: text("renderError.title"),
921
+ description: text("renderError.description"),
922
+ reloadLabel: text("renderError.reload"),
923
+ detailsLabel: text("renderError.details"),
924
+ pathLabel: text("renderError.path"),
925
+ typeLabel: text("renderError.type"),
926
+ messageLabel: text("renderError.message"),
927
+ stackLabel: text("renderError.stack"),
928
+ componentStackLabel: text("renderError.componentStack"),
929
+ timestampLabel: text("renderError.timestamp"),
930
+ copyLabel: text("actions.copy"),
931
+ copiedLabel: text("actions.copied"),
932
+ path: pathname,
933
+ children: /* @__PURE__ */ jsx(Suspense, {
934
+ fallback: /* @__PURE__ */ jsx(PageSkeleton, {}),
935
+ children: renderRouteElements()
936
+ })
937
+ }, pathname)
938
+ });
939
+ }
940
+ function renderFooter() {
941
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
942
+ /* @__PURE__ */ jsx(RuntimeSlot, { name: "page.footer.before" }),
943
+ /* @__PURE__ */ jsx(RuntimeSlot, {
944
+ name: "page.footer.replace",
945
+ default: DefaultFooterComponent
946
+ }),
947
+ /* @__PURE__ */ jsx("div", {
948
+ className: "flex justify-end",
949
+ children: /* @__PURE__ */ jsx(BuiltWithClarify, {})
950
+ })
951
+ ] });
952
+ }
953
+ function renderContent() {
954
+ return /* @__PURE__ */ jsx("div", {
955
+ 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),
956
+ children: /* @__PURE__ */ jsxs(PageActionsProvider, {
957
+ route: currentRoute,
958
+ routePrefix: config.routePrefix,
959
+ children: [
960
+ renderMain(),
961
+ /* @__PURE__ */ jsx(PageNavigation, {
962
+ navigation: currentNavigation.items,
963
+ currentRoute
964
+ }),
965
+ renderFooter()
966
+ ]
967
+ })
968
+ });
969
+ }
970
+ function renderLayout() {
971
+ return /* @__PURE__ */ jsxs("div", {
972
+ 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)",
973
+ style: layoutStyle,
974
+ children: [renderSidebar(), renderContent()]
975
+ });
976
+ }
788
977
  return /* @__PURE__ */ jsx(LocaleContext.Provider, {
789
978
  value: currentLocale,
790
979
  children: /* @__PURE__ */ jsx(RuntimeSlotsProvider, {
@@ -792,82 +981,8 @@ function AppShell(arg0) {
792
981
  route: currentRoute,
793
982
  children: /* @__PURE__ */ jsxs(SectionProvider, {
794
983
  sections,
795
- children: [/* @__PURE__ */ jsx(Header, {
796
- config,
797
- navigation: currentNavigation.items,
798
- tabs: currentNavigation.tabs,
799
- routes,
800
- currentLocale,
801
- currentRoute,
802
- banner: /* @__PURE__ */ jsx(BannerSlot, {
803
- activeBannerKey,
804
- dismissedBannerKey,
805
- onDismiss: () => setDismissedBannerKey(activeBannerKey),
806
- config,
807
- locale: currentLocale
808
- })
809
- }), /* @__PURE__ */ jsxs("div", {
810
- 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)",
811
- style: { "--clarify-header-offset": hasTabs && hasBanner ? "10rem" : hasTabs && !hasBanner ? "7rem" : !hasTabs && hasBanner ? "6.5rem" : "3.5rem" },
812
- children: [/* @__PURE__ */ jsx("aside", {
813
- "data-pagefind-ignore": true,
814
- className: "clarify-sidebar hidden lg:block lg:self-stretch lg:bg-(--clarify-theme-tokens-colors-background) lg:px-5 xl:px-6",
815
- children: /* @__PURE__ */ jsx("div", {
816
- 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-26 lg:h-(--clarify-sidebar-height-with-banner) lg:pt-10", !hasTabs && !hasBanner && "lg:top-14 lg:h-(--clarify-sidebar-height) lg:pt-10"),
817
- children: /* @__PURE__ */ jsx(Navigation, { navigation: currentNavigation.items })
818
- })
819
- }), /* @__PURE__ */ jsx("div", {
820
- 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-26 lg:pt-40", hasTabs && !hasBanner && "pt-14 lg:pt-28", !hasTabs && hasBanner && "pt-26", !hasTabs && !hasBanner && "pt-14"),
821
- children: /* @__PURE__ */ jsxs(PageActionsProvider, {
822
- route: currentRoute,
823
- routePrefix: config.routePrefix,
824
- children: [
825
- /* @__PURE__ */ jsx("main", {
826
- className: "clarify-main min-w-0 flex-auto",
827
- "data-pagefind-body": true,
828
- children: /* @__PURE__ */ jsx(PageErrorBoundary, {
829
- title: text("renderError.title"),
830
- description: text("renderError.description"),
831
- reloadLabel: text("renderError.reload"),
832
- detailsLabel: text("renderError.details"),
833
- pathLabel: text("renderError.path"),
834
- typeLabel: text("renderError.type"),
835
- messageLabel: text("renderError.message"),
836
- stackLabel: text("renderError.stack"),
837
- componentStackLabel: text("renderError.componentStack"),
838
- timestampLabel: text("renderError.timestamp"),
839
- copyLabel: text("actions.copy"),
840
- copiedLabel: text("actions.copied"),
841
- path: pathname,
842
- children: /* @__PURE__ */ jsx(Suspense, {
843
- fallback: /* @__PURE__ */ jsx(PageSkeleton, {}),
844
- children: /* @__PURE__ */ jsxs(Routes, { children: [renderRoutes.map((route) => /* @__PURE__ */ jsx(Route, {
845
- path: route.path,
846
- element: /* @__PURE__ */ jsx(route.component, {})
847
- }, route.path)), /* @__PURE__ */ jsx(Route, {
848
- path: "*",
849
- element: /* @__PURE__ */ jsx(NotFoundRouteElement, { component: NotFoundRouteComponent })
850
- })] })
851
- })
852
- }, pathname)
853
- }),
854
- /* @__PURE__ */ jsx(PageNavigation, {
855
- navigation: currentNavigation.items,
856
- currentRoute
857
- }),
858
- /* @__PURE__ */ jsx(RuntimeSlot, { name: "page.footer.before" }),
859
- /* @__PURE__ */ jsx(RuntimeSlot, {
860
- name: "page.footer.replace",
861
- default: DefaultFooterComponent
862
- }),
863
- /* @__PURE__ */ jsx("div", {
864
- className: "flex justify-end",
865
- children: /* @__PURE__ */ jsx(BuiltWithClarify, {})
866
- })
867
- ]
868
- })
869
- })]
870
- })]
984
+ headerTopAreaRef,
985
+ children: [renderHeader(), renderLayout()]
871
986
  })
872
987
  })
873
988
  });
@@ -1923,10 +2038,8 @@ function themeToConfigSource(theme) {
1923
2038
  layout: theme.layout
1924
2039
  } }, null, 2);
1925
2040
  }
1926
- function ThemeEditor(props) {
1927
- const { initialTheme, onChange, target, defaultOpen = false, className } = props;
1928
- const { resolvedTheme } = useTheme();
1929
- const [isOpen, setIsOpen] = useState(defaultOpen);
2041
+ function useThemeEditorState(arg0) {
2042
+ const { initialTheme, onChange, target, resolvedTheme } = arg0;
1930
2043
  const [theme, setTheme] = useState(() => cloneTheme(initialTheme ?? themeEditorPresets.default));
1931
2044
  const [copyState, setCopyState] = useState("idle");
1932
2045
  const configSource = useMemo(() => themeToConfigSource(theme), [theme]);
@@ -1985,122 +2098,156 @@ function ThemeEditor(props) {
1985
2098
  window.setTimeout(() => setCopyState("idle"), 1400);
1986
2099
  }
1987
2100
  }
1988
- return /* @__PURE__ */ jsxs("div", {
1989
- className: clsx("clarify-theme-editor fixed right-4 bottom-4 z-50 text-(--clarify-theme-tokens-colors-foreground)", className),
1990
- children: [isOpen ? /* @__PURE__ */ jsxs("section", {
2101
+ return {
2102
+ theme,
2103
+ copyState,
2104
+ commit,
2105
+ updatePreset,
2106
+ updateColorToken,
2107
+ updateRadiusToken,
2108
+ updateLayoutToken,
2109
+ copyConfig
2110
+ };
2111
+ }
2112
+ function ThemeEditor(props) {
2113
+ const { initialTheme, onChange, target, defaultOpen = false, className } = props;
2114
+ const { resolvedTheme } = useTheme();
2115
+ const [isOpen, setIsOpen] = useState(defaultOpen);
2116
+ const { theme, copyState, commit, updatePreset, updateColorToken, updateRadiusToken, updateLayoutToken, copyConfig } = useThemeEditorState({
2117
+ initialTheme,
2118
+ onChange,
2119
+ target,
2120
+ resolvedTheme
2121
+ });
2122
+ function renderPanelHeader() {
2123
+ return /* @__PURE__ */ jsxs("header", {
2124
+ className: "shrink-0 flex items-start justify-between gap-4 border-b border-(--clarify-theme-tokens-colors-border) px-4 py-3",
2125
+ children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h2", {
2126
+ className: "text-sm/6 font-semibold text-(--clarify-theme-tokens-colors-foreground)",
2127
+ children: "Theme editor"
2128
+ }), /* @__PURE__ */ jsx("p", {
2129
+ className: "mt-0.5 text-xs/5 text-(--clarify-ui-text-soft)",
2130
+ children: "Live CSS variable preview for Clarify theme tokens."
2131
+ })] }), /* @__PURE__ */ jsx("button", {
2132
+ type: "button",
2133
+ 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)",
2134
+ "aria-label": "Close theme editor",
2135
+ onClick: () => setIsOpen(false),
2136
+ children: /* @__PURE__ */ jsx(X, { className: "size-4 stroke-current stroke-2" })
2137
+ })]
2138
+ });
2139
+ }
2140
+ function renderPanelBody() {
2141
+ return /* @__PURE__ */ jsx("div", {
2142
+ className: "min-h-0 flex-1 overflow-y-auto px-4 py-4",
2143
+ children: /* @__PURE__ */ jsxs("div", {
2144
+ className: "grid gap-5",
2145
+ children: [
2146
+ /* @__PURE__ */ jsxs("label", {
2147
+ htmlFor: "clarify-theme-editor-preset",
2148
+ className: "grid gap-1.5 text-xs/5 font-medium text-(--clarify-ui-text)",
2149
+ children: ["Preset", /* @__PURE__ */ jsxs("span", {
2150
+ className: "relative block",
2151
+ children: [/* @__PURE__ */ jsxs("select", {
2152
+ id: "clarify-theme-editor-preset",
2153
+ value: theme.preset,
2154
+ 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)",
2155
+ onChange: (event) => updatePreset(event.target.value),
2156
+ children: [/* @__PURE__ */ jsx("option", {
2157
+ value: "default",
2158
+ children: "default"
2159
+ }), /* @__PURE__ */ jsx("option", {
2160
+ value: "base",
2161
+ children: "base"
2162
+ })]
2163
+ }), /* @__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)" })]
2164
+ })]
2165
+ }),
2166
+ /* @__PURE__ */ jsxs("fieldset", {
2167
+ className: "grid gap-3",
2168
+ children: [/* @__PURE__ */ jsx("legend", {
2169
+ className: "mb-2 text-xs/5 font-semibold uppercase tracking-wide text-(--clarify-ui-text-faint)",
2170
+ children: "Colors"
2171
+ }), /* @__PURE__ */ jsx("div", {
2172
+ className: "grid grid-cols-1 gap-3",
2173
+ children: colorTokenFields.map((field) => /* @__PURE__ */ jsx(ColorField, {
2174
+ id: `clarify-theme-editor-color-${field.key}`,
2175
+ label: field.label,
2176
+ value: theme.tokens.colors[field.key],
2177
+ onChange: (mode, value) => updateColorToken(field.key, mode, value)
2178
+ }, field.key))
2179
+ })]
2180
+ }),
2181
+ /* @__PURE__ */ jsxs("fieldset", {
2182
+ className: "grid gap-3",
2183
+ children: [/* @__PURE__ */ jsx("legend", {
2184
+ className: "mb-2 text-xs/5 font-semibold uppercase tracking-wide text-(--clarify-ui-text-faint)",
2185
+ children: "Radius"
2186
+ }), /* @__PURE__ */ jsx("div", {
2187
+ className: "grid grid-cols-2 gap-3",
2188
+ children: radiusTokenFields.map((field) => /* @__PURE__ */ jsx(TextField, {
2189
+ id: `clarify-theme-editor-radius-${field.key}`,
2190
+ label: field.label,
2191
+ value: theme.tokens.radius[field.key],
2192
+ onChange: (value) => updateRadiusToken(field.key, value)
2193
+ }, field.key))
2194
+ })]
2195
+ }),
2196
+ /* @__PURE__ */ jsxs("fieldset", {
2197
+ className: "grid gap-3",
2198
+ children: [/* @__PURE__ */ jsx("legend", {
2199
+ className: "mb-2 text-xs/5 font-semibold uppercase tracking-wide text-(--clarify-ui-text-faint)",
2200
+ children: "Layout"
2201
+ }), layoutFields.map((field) => /* @__PURE__ */ jsx(TextField, {
2202
+ id: `clarify-theme-editor-layout-${field.key}`,
2203
+ label: field.label,
2204
+ value: theme.layout[field.key],
2205
+ onChange: (value) => updateLayoutToken(field.key, value)
2206
+ }, field.key))]
2207
+ })
2208
+ ]
2209
+ })
2210
+ });
2211
+ }
2212
+ function renderPanelFooter() {
2213
+ return /* @__PURE__ */ jsxs("footer", {
2214
+ 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",
2215
+ children: [/* @__PURE__ */ jsxs("div", {
2216
+ className: "flex items-center gap-1.5",
2217
+ children: [/* @__PURE__ */ jsx("button", {
2218
+ type: "button",
2219
+ 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)",
2220
+ onClick: () => updatePreset(theme.preset),
2221
+ children: "Reset preset"
2222
+ }), /* @__PURE__ */ jsxs("button", {
2223
+ type: "button",
2224
+ 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)",
2225
+ onClick: () => commit(createRandomTheme()),
2226
+ children: [/* @__PURE__ */ jsx(WandSparkles, { className: "size-3.5 stroke-current stroke-2" }), "Random"]
2227
+ })]
2228
+ }), /* @__PURE__ */ jsx("button", {
2229
+ type: "button",
2230
+ 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",
2231
+ onClick: copyConfig,
2232
+ children: copyState === "copied" ? "Copied" : copyState === "failed" ? "Copy failed" : "Copy config"
2233
+ })]
2234
+ });
2235
+ }
2236
+ function renderEditorPanel() {
2237
+ if (!isOpen) return null;
2238
+ return /* @__PURE__ */ jsxs("section", {
1991
2239
  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",
1992
2240
  "aria-label": "Clarify theme editor",
1993
2241
  children: [
1994
- /* @__PURE__ */ jsxs("header", {
1995
- className: "shrink-0 flex items-start justify-between gap-4 border-b border-(--clarify-theme-tokens-colors-border) px-4 py-3",
1996
- children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h2", {
1997
- className: "text-sm/6 font-semibold text-(--clarify-theme-tokens-colors-foreground)",
1998
- children: "Theme editor"
1999
- }), /* @__PURE__ */ jsx("p", {
2000
- className: "mt-0.5 text-xs/5 text-(--clarify-ui-text-soft)",
2001
- children: "Live CSS variable preview for Clarify theme tokens."
2002
- })] }), /* @__PURE__ */ jsx("button", {
2003
- type: "button",
2004
- 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)",
2005
- "aria-label": "Close theme editor",
2006
- onClick: () => setIsOpen(false),
2007
- children: /* @__PURE__ */ jsx(X, { className: "size-4 stroke-current stroke-2" })
2008
- })]
2009
- }),
2010
- /* @__PURE__ */ jsx("div", {
2011
- className: "min-h-0 flex-1 overflow-y-auto px-4 py-4",
2012
- children: /* @__PURE__ */ jsxs("div", {
2013
- className: "grid gap-5",
2014
- children: [
2015
- /* @__PURE__ */ jsxs("label", {
2016
- htmlFor: "clarify-theme-editor-preset",
2017
- className: "grid gap-1.5 text-xs/5 font-medium text-(--clarify-ui-text)",
2018
- children: ["Preset", /* @__PURE__ */ jsxs("span", {
2019
- className: "relative block",
2020
- children: [/* @__PURE__ */ jsxs("select", {
2021
- id: "clarify-theme-editor-preset",
2022
- value: theme.preset,
2023
- 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)",
2024
- onChange: (event) => updatePreset(event.target.value),
2025
- children: [/* @__PURE__ */ jsx("option", {
2026
- value: "default",
2027
- children: "default"
2028
- }), /* @__PURE__ */ jsx("option", {
2029
- value: "base",
2030
- children: "base"
2031
- })]
2032
- }), /* @__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)" })]
2033
- })]
2034
- }),
2035
- /* @__PURE__ */ jsxs("fieldset", {
2036
- className: "grid gap-3",
2037
- children: [/* @__PURE__ */ jsx("legend", {
2038
- className: "mb-2 text-xs/5 font-semibold uppercase tracking-wide text-(--clarify-ui-text-faint)",
2039
- children: "Colors"
2040
- }), /* @__PURE__ */ jsx("div", {
2041
- className: "grid grid-cols-1 gap-3",
2042
- children: colorTokenFields.map((field) => /* @__PURE__ */ jsx(ColorField, {
2043
- id: `clarify-theme-editor-color-${field.key}`,
2044
- label: field.label,
2045
- value: theme.tokens.colors[field.key],
2046
- onChange: (mode, value) => updateColorToken(field.key, mode, value)
2047
- }, field.key))
2048
- })]
2049
- }),
2050
- /* @__PURE__ */ jsxs("fieldset", {
2051
- className: "grid gap-3",
2052
- children: [/* @__PURE__ */ jsx("legend", {
2053
- className: "mb-2 text-xs/5 font-semibold uppercase tracking-wide text-(--clarify-ui-text-faint)",
2054
- children: "Radius"
2055
- }), /* @__PURE__ */ jsx("div", {
2056
- className: "grid grid-cols-2 gap-3",
2057
- children: radiusTokenFields.map((field) => /* @__PURE__ */ jsx(TextField, {
2058
- id: `clarify-theme-editor-radius-${field.key}`,
2059
- label: field.label,
2060
- value: theme.tokens.radius[field.key],
2061
- onChange: (value) => updateRadiusToken(field.key, value)
2062
- }, field.key))
2063
- })]
2064
- }),
2065
- /* @__PURE__ */ jsxs("fieldset", {
2066
- className: "grid gap-3",
2067
- children: [/* @__PURE__ */ jsx("legend", {
2068
- className: "mb-2 text-xs/5 font-semibold uppercase tracking-wide text-(--clarify-ui-text-faint)",
2069
- children: "Layout"
2070
- }), layoutFields.map((field) => /* @__PURE__ */ jsx(TextField, {
2071
- id: `clarify-theme-editor-layout-${field.key}`,
2072
- label: field.label,
2073
- value: theme.layout[field.key],
2074
- onChange: (value) => updateLayoutToken(field.key, value)
2075
- }, field.key))]
2076
- })
2077
- ]
2078
- })
2079
- }),
2080
- /* @__PURE__ */ jsxs("footer", {
2081
- 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",
2082
- children: [/* @__PURE__ */ jsxs("div", {
2083
- className: "flex items-center gap-1.5",
2084
- children: [/* @__PURE__ */ jsx("button", {
2085
- type: "button",
2086
- 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)",
2087
- onClick: () => updatePreset(theme.preset),
2088
- children: "Reset preset"
2089
- }), /* @__PURE__ */ jsxs("button", {
2090
- type: "button",
2091
- 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)",
2092
- onClick: () => commit(createRandomTheme()),
2093
- children: [/* @__PURE__ */ jsx(WandSparkles, { className: "size-3.5 stroke-current stroke-2" }), "Random"]
2094
- })]
2095
- }), /* @__PURE__ */ jsx("button", {
2096
- type: "button",
2097
- 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",
2098
- onClick: copyConfig,
2099
- children: copyState === "copied" ? "Copied" : copyState === "failed" ? "Copy failed" : "Copy config"
2100
- })]
2101
- })
2242
+ renderPanelHeader(),
2243
+ renderPanelBody(),
2244
+ renderPanelFooter()
2102
2245
  ]
2103
- }) : null, /* @__PURE__ */ jsx("button", {
2246
+ });
2247
+ }
2248
+ return /* @__PURE__ */ jsxs("div", {
2249
+ className: clsx("clarify-theme-editor fixed right-4 bottom-4 z-50 text-(--clarify-theme-tokens-colors-foreground)", className),
2250
+ children: [renderEditorPanel(), /* @__PURE__ */ jsx("button", {
2104
2251
  type: "button",
2105
2252
  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)",
2106
2253
  "aria-label": isOpen ? "Close Clarify theme editor" : "Open Clarify theme editor",
@@ -2155,4 +2302,4 @@ function ClarifyShell(props) {
2155
2302
  //#endregion
2156
2303
  export { themeBootstrapScript as a, AppShell as c, BuiltWithClarify as d, RuntimeSlot as f, useSlot as h, themeEditorPresets as i, PageFooter as l, SlotProvider as m, ThemeEditor as n, themePresets as o, RuntimeSlotsProvider as p, applyThemeVariables as r, themeStorageKey as s, ClarifyShell as t, PageBanner as u };
2157
2304
 
2158
- //# sourceMappingURL=ClarifyShell-BPv2bxI4.js.map
2305
+ //# sourceMappingURL=ClarifyShell-C38EkErX.js.map