@povio/ui 5.0.0-rc.10 → 5.0.0-rc.12

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.
@@ -48,8 +48,8 @@ import { i as alertDefinition, n as statusIconDefinition, r as statusSeparatorDe
48
48
  import { a as toastDefinition, i as toastContainerDefinition } from "./toast.cva-C_L_RffH.js";
49
49
  import { t as linkDefinition } from "./link.cva-DMTHZiJG.js";
50
50
  import { t as tooltipWrapperTriggerDefinition } from "./tooltipWrapper.cva-BBQ4ic3D.js";
51
- import { C as validToken, S as toRgb, a as generateShades, b as spacingLevels, c as isFontSizeToken, d as layoutKindFor, f as layoutKinds, g as listedLayoutToken, h as linkedLayoutTokens, i as exportCss, l as isRgb, m as layoutScales, n as controlHeightCounterpart, o as groupFor, p as layoutLevelFor, r as emptyTheme, s as groups, t as baseColorNames, u as labelFor, v as previewTokens, x as toHex, y as runtimeCss } from "./theme-model-DtYPxNvH.js";
52
- import $ahdqC$react, { Suspense, createContext, lazy, use, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
51
+ import { C as toRgb, S as toHex, _ as listedLayoutToken, a as generateShades, b as runtimeCss, c as isEditableToken, d as labelFor, f as layoutKindFor, g as linkedLayoutTokens, h as layoutScales, i as exportCss, l as isFontSizeToken, m as layoutLevelFor, n as controlHeightCounterpart, o as groupFor, p as layoutKinds, r as emptyTheme, s as groups, t as baseColorNames, u as isRgb, w as validToken, x as spacingLevels, y as previewTokens } from "./theme-model-DtTsIxou.js";
52
+ import $ahdqC$react, { Fragment, Suspense, createContext, lazy, use, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
53
53
  import { c } from "react/compiler-runtime";
54
54
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
55
55
  import { mergeProps } from "react-aria/mergeProps";
@@ -609,7 +609,7 @@ const emptyConfiguration = () => ({
609
609
  });
610
610
  const ConfigurationContext = createContext(null);
611
611
  function UIConfigurationProvider(t0) {
612
- const $ = c(40);
612
+ const $ = c(50);
613
613
  const { defaults, initialValue, onApply, children } = t0;
614
614
  const inheritedOverrides = UIOverrides.useConfig();
615
615
  const [applied, setApplied] = useState(initialValue ?? emptyConfiguration);
@@ -618,68 +618,115 @@ function UIConfigurationProvider(t0) {
618
618
  const [floating, setFloating] = useState(false);
619
619
  const [revision, setRevision] = useState(0);
620
620
  const [previewConfiguration, setPreviewConfiguration] = useState(null);
621
- const active = previewConfiguration ?? (isOpen ? draft : applied);
621
+ const [tokenRequest, setTokenRequest] = useState(null);
622
+ const [componentHosts, setComponentHosts] = useState(0);
622
623
  let t1;
623
- if ($[0] !== applied) {
624
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
624
625
  t1 = () => {
626
+ setComponentHosts(_temp$7);
627
+ return () => setComponentHosts(_temp2$5);
628
+ };
629
+ $[0] = t1;
630
+ } else t1 = $[0];
631
+ const hostComponents = t1;
632
+ let t2;
633
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
634
+ t2 = (value, t3) => {
635
+ if (t3 === void 0 ? false : t3) setOpen(false);
636
+ setApplied(structuredClone(value));
637
+ setDraft(structuredClone(value));
638
+ setPreviewConfiguration(null);
639
+ setRevision(_temp3$4);
640
+ };
641
+ $[1] = t2;
642
+ } else t2 = $[1];
643
+ const replaceConfiguration = t2;
644
+ const active = previewConfiguration ?? (isOpen ? draft : applied);
645
+ let t3;
646
+ if ($[2] !== applied) {
647
+ t3 = () => {
625
648
  setFloating(false);
626
649
  setDraft(structuredClone(applied));
627
- setRevision(_temp$7);
650
+ setRevision(_temp4$4);
628
651
  setOpen(true);
629
652
  };
630
- $[0] = applied;
631
- $[1] = t1;
632
- } else t1 = $[1];
633
- const open = t1;
634
- let t2;
635
- if ($[2] !== isOpen || $[3] !== open) {
636
- t2 = () => {
637
- if (isOpen) setRevision(_temp2$5);
653
+ $[2] = applied;
654
+ $[3] = t3;
655
+ } else t3 = $[3];
656
+ const open = t3;
657
+ let t4;
658
+ if ($[4] !== isOpen || $[5] !== open) {
659
+ t4 = () => {
660
+ if (isOpen) setRevision(_temp5$2);
638
661
  else open();
639
662
  setFloating(true);
640
663
  };
641
- $[2] = isOpen;
642
- $[3] = open;
643
- $[4] = t2;
644
- } else t2 = $[4];
645
- const openFloating = t2;
646
- let t3;
647
- if ($[5] !== applied) {
648
- t3 = () => {
664
+ $[4] = isOpen;
665
+ $[5] = open;
666
+ $[6] = t4;
667
+ } else t4 = $[6];
668
+ const openFloating = t4;
669
+ let t5;
670
+ if ($[7] !== isOpen || $[8] !== openFloating) {
671
+ t5 = (name) => {
672
+ setTokenRequest((current_0) => ({
673
+ name,
674
+ id: (current_0?.id ?? 0) + 1
675
+ }));
676
+ if (!isOpen) openFloating();
677
+ };
678
+ $[7] = isOpen;
679
+ $[8] = openFloating;
680
+ $[9] = t5;
681
+ } else t5 = $[9];
682
+ const revealToken = t5;
683
+ let t6;
684
+ if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
685
+ t6 = () => setTokenRequest(null);
686
+ $[10] = t6;
687
+ } else t6 = $[10];
688
+ const clearTokenRequest = t6;
689
+ let t7;
690
+ if ($[11] !== applied) {
691
+ t7 = () => {
649
692
  setDraft(structuredClone(applied));
650
693
  setOpen(false);
651
694
  };
652
- $[5] = applied;
653
- $[6] = t3;
654
- } else t3 = $[6];
655
- const cancel = t3;
656
- let t4;
657
- if ($[7] !== draft || $[8] !== onApply) {
658
- t4 = () => {
695
+ $[11] = applied;
696
+ $[12] = t7;
697
+ } else t7 = $[12];
698
+ const cancel = t7;
699
+ let t8;
700
+ if ($[13] !== draft || $[14] !== onApply) {
701
+ t8 = () => {
659
702
  onApply?.(structuredClone(draft));
660
703
  setApplied(structuredClone(draft));
661
704
  setOpen(false);
662
705
  };
663
- $[7] = draft;
664
- $[8] = onApply;
665
- $[9] = t4;
666
- } else t4 = $[9];
667
- const apply = t4;
668
- let t5;
669
- if ($[10] !== active.overrides || $[11] !== inheritedOverrides) {
670
- t5 = applyCvaEdits(inheritedOverrides, active.overrides);
671
- $[10] = active.overrides;
672
- $[11] = inheritedOverrides;
673
- $[12] = t5;
674
- } else t5 = $[12];
675
- const overrides = t5;
676
- let t6;
677
- if ($[13] !== active || $[14] !== apply || $[15] !== cancel || $[16] !== defaults || $[17] !== draft || $[18] !== floating || $[19] !== inheritedOverrides || $[20] !== isOpen || $[21] !== open || $[22] !== openFloating || $[23] !== revision) {
678
- t6 = {
706
+ $[13] = draft;
707
+ $[14] = onApply;
708
+ $[15] = t8;
709
+ } else t8 = $[15];
710
+ const apply = t8;
711
+ let t9;
712
+ if ($[16] !== active.overrides || $[17] !== inheritedOverrides) {
713
+ t9 = applyCvaEdits(inheritedOverrides, active.overrides);
714
+ $[16] = active.overrides;
715
+ $[17] = inheritedOverrides;
716
+ $[18] = t9;
717
+ } else t9 = $[18];
718
+ const overrides = t9;
719
+ const t10 = isOpen ? draft : applied;
720
+ const t11 = componentHosts > 0;
721
+ let t12;
722
+ if ($[19] !== active || $[20] !== apply || $[21] !== cancel || $[22] !== defaults || $[23] !== draft || $[24] !== floating || $[25] !== inheritedOverrides || $[26] !== isOpen || $[27] !== open || $[28] !== openFloating || $[29] !== revealToken || $[30] !== revision || $[31] !== t10 || $[32] !== t11 || $[33] !== tokenRequest) {
723
+ t12 = {
679
724
  defaults,
680
725
  inheritedOverrides,
681
726
  draft,
682
727
  active,
728
+ currentConfiguration: t10,
729
+ replaceConfiguration,
683
730
  setPreviewConfiguration,
684
731
  setDraft,
685
732
  isOpen,
@@ -688,76 +735,94 @@ function UIConfigurationProvider(t0) {
688
735
  floating,
689
736
  cancel,
690
737
  apply,
691
- revision
738
+ revision,
739
+ revealToken,
740
+ tokenRequest,
741
+ clearTokenRequest,
742
+ componentsHosted: t11,
743
+ hostComponents
692
744
  };
693
- $[13] = active;
694
- $[14] = apply;
695
- $[15] = cancel;
696
- $[16] = defaults;
697
- $[17] = draft;
698
- $[18] = floating;
699
- $[19] = inheritedOverrides;
700
- $[20] = isOpen;
701
- $[21] = open;
702
- $[22] = openFloating;
703
- $[23] = revision;
704
- $[24] = t6;
705
- } else t6 = $[24];
706
- const contextValue = t6;
707
- let t7;
708
- if ($[25] !== active.theme || $[26] !== defaults) {
709
- t7 = runtimeCss(defaults, active.theme);
710
- $[25] = active.theme;
711
- $[26] = defaults;
712
- $[27] = t7;
713
- } else t7 = $[27];
714
- let t8;
715
- if ($[28] !== t7) {
716
- t8 = /* @__PURE__ */ jsx("style", {
745
+ $[19] = active;
746
+ $[20] = apply;
747
+ $[21] = cancel;
748
+ $[22] = defaults;
749
+ $[23] = draft;
750
+ $[24] = floating;
751
+ $[25] = inheritedOverrides;
752
+ $[26] = isOpen;
753
+ $[27] = open;
754
+ $[28] = openFloating;
755
+ $[29] = revealToken;
756
+ $[30] = revision;
757
+ $[31] = t10;
758
+ $[32] = t11;
759
+ $[33] = tokenRequest;
760
+ $[34] = t12;
761
+ } else t12 = $[34];
762
+ const contextValue = t12;
763
+ let t13;
764
+ if ($[35] !== active.theme || $[36] !== defaults) {
765
+ t13 = runtimeCss(defaults, active.theme);
766
+ $[35] = active.theme;
767
+ $[36] = defaults;
768
+ $[37] = t13;
769
+ } else t13 = $[37];
770
+ let t14;
771
+ if ($[38] !== t13) {
772
+ t14 = /* @__PURE__ */ jsx("style", {
717
773
  "data-povio-ui-configuration": true,
718
- children: t7
774
+ children: t13
719
775
  });
720
- $[28] = t7;
721
- $[29] = t8;
722
- } else t8 = $[29];
723
- let t9;
724
- if ($[30] !== active.config || $[31] !== children) {
725
- t9 = /* @__PURE__ */ jsx(UIConfig.Provider, {
776
+ $[38] = t13;
777
+ $[39] = t14;
778
+ } else t14 = $[39];
779
+ let t15;
780
+ if ($[40] !== active.config || $[41] !== children) {
781
+ t15 = /* @__PURE__ */ jsx(UIConfig.Provider, {
726
782
  config: active.config,
727
783
  children
728
784
  });
729
- $[30] = active.config;
730
- $[31] = children;
731
- $[32] = t9;
732
- } else t9 = $[32];
733
- let t10;
734
- if ($[33] !== overrides || $[34] !== t9) {
735
- t10 = /* @__PURE__ */ jsx(UIOverrides.Provider, {
785
+ $[40] = active.config;
786
+ $[41] = children;
787
+ $[42] = t15;
788
+ } else t15 = $[42];
789
+ let t16;
790
+ if ($[43] !== overrides || $[44] !== t15) {
791
+ t16 = /* @__PURE__ */ jsx(UIOverrides.Provider, {
736
792
  config: overrides,
737
- children: t9
793
+ children: t15
738
794
  });
739
- $[33] = overrides;
740
- $[34] = t9;
741
- $[35] = t10;
742
- } else t10 = $[35];
743
- let t11;
744
- if ($[36] !== contextValue || $[37] !== t10 || $[38] !== t8) {
745
- t11 = /* @__PURE__ */ jsxs(ConfigurationContext.Provider, {
795
+ $[43] = overrides;
796
+ $[44] = t15;
797
+ $[45] = t16;
798
+ } else t16 = $[45];
799
+ let t17;
800
+ if ($[46] !== contextValue || $[47] !== t14 || $[48] !== t16) {
801
+ t17 = /* @__PURE__ */ jsxs(ConfigurationContext.Provider, {
746
802
  value: contextValue,
747
- children: [t8, t10]
803
+ children: [t14, t16]
748
804
  });
749
- $[36] = contextValue;
750
- $[37] = t10;
751
- $[38] = t8;
752
- $[39] = t11;
753
- } else t11 = $[39];
754
- return t11;
805
+ $[46] = contextValue;
806
+ $[47] = t14;
807
+ $[48] = t16;
808
+ $[49] = t17;
809
+ } else t17 = $[49];
810
+ return t17;
811
+ }
812
+ function _temp5$2(value_1) {
813
+ return value_1 + 1;
755
814
  }
756
- function _temp2$5(value_0) {
815
+ function _temp4$4(value_0) {
757
816
  return value_0 + 1;
758
817
  }
759
- function _temp$7(value) {
760
- return value + 1;
818
+ function _temp3$4(current) {
819
+ return current + 1;
820
+ }
821
+ function _temp2$5(count_0) {
822
+ return count_0 - 1;
823
+ }
824
+ function _temp$7(count) {
825
+ return count + 1;
761
826
  }
762
827
  function useUIConfiguration() {
763
828
  const context = use(ConfigurationContext);
@@ -766,6 +831,10 @@ function useUIConfiguration() {
766
831
  }
767
832
  //#endregion
768
833
  //#region src/configurator/inspector/InspectorDetails.tsx
834
+ /** A token as a design tool names a variable: `--text-large--line-height` → `text-large/line-height`. */
835
+ const variableName = (token) => token.replace(/^--/, "").replace(/-base$/, "").replaceAll("--", "/");
836
+ /** Pixel values read like the box model's numbers and fonts by their family, as a design tool shows them. */
837
+ const displayValue = (value, label) => label === "Font" ? value.split(",")[0]?.replace(/["']/g, "").trim() ?? value : value.replace(/(-?\d*\.\d+)px/g, (_, amount) => `${Math.round(Number(amount) * 10) / 10}px`);
769
838
  /** Shared inspector measurements and property groups for preview and app canvas. */
770
839
  function InspectorDetails(t0) {
771
840
  const $ = c(18);
@@ -813,16 +882,30 @@ function InspectorDetails(t0) {
813
882
  if ($[10] !== onSelect || $[11] !== snapshot.groups) {
814
883
  let t6;
815
884
  if ($[13] !== onSelect) {
816
- t6 = (group_1) => /* @__PURE__ */ jsxs("section", { children: [group_1.name !== "Layout" && /* @__PURE__ */ jsx("h3", { children: group_1.name }), /* @__PURE__ */ jsx("dl", { children: group_1.properties.map((property_0) => /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: property_0.label }), /* @__PURE__ */ jsxs("dd", { children: [
817
- property_0.color && /* @__PURE__ */ jsx("i", { style: { background: property_0.color } }),
818
- /* @__PURE__ */ jsx("span", { children: property_0.value }),
819
- property_0.token && /* @__PURE__ */ jsx("button", {
820
- type: "button",
821
- title: `Edit ${property_0.token}`,
822
- onClick: () => onSelect(property_0.token),
823
- children: property_0.token.replace(/^--/, "")
824
- })
825
- ] })] }, property_0.label)) })] }, group_1.name);
885
+ t6 = (group_1) => /* @__PURE__ */ jsxs("section", { children: [group_1.name !== "Layout" && /* @__PURE__ */ jsx("h3", { children: group_1.name }), /* @__PURE__ */ jsx("dl", { children: group_1.properties.map((property_0) => /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: property_0.label }), /* @__PURE__ */ jsx("dd", { children: property_0.token ? /* @__PURE__ */ jsxs("button", {
886
+ type: "button",
887
+ className: "studio-inspector-chip",
888
+ title: `Edit ${property_0.token} · ${property_0.value}`,
889
+ onClick: () => onSelect(property_0.token),
890
+ children: [
891
+ property_0.color && /* @__PURE__ */ jsx("i", { style: { background: property_0.color } }),
892
+ /* @__PURE__ */ jsx("span", {
893
+ className: "studio-inspector-chip-name",
894
+ children: variableName(property_0.token)
895
+ }),
896
+ /* @__PURE__ */ jsx("span", {
897
+ className: "studio-inspector-chip-value",
898
+ children: displayValue(property_0.value, property_0.label)
899
+ })
900
+ ]
901
+ }) : /* @__PURE__ */ jsxs("span", {
902
+ className: "studio-inspector-chip",
903
+ title: property_0.value,
904
+ children: [property_0.color && /* @__PURE__ */ jsx("i", { style: { background: property_0.color } }), /* @__PURE__ */ jsx("span", {
905
+ className: "studio-inspector-chip-value",
906
+ children: displayValue(property_0.value, property_0.label)
907
+ })]
908
+ }) })] }, property_0.label)) })] }, group_1.name);
826
909
  $[13] = onSelect;
827
910
  $[14] = t6;
828
911
  } else t6 = $[14];
@@ -1435,6 +1518,74 @@ function splitVariants(className) {
1435
1518
  utility: current
1436
1519
  };
1437
1520
  }
1521
+ /** Variants that style a pseudo-element or other elements, never the element's own value. */
1522
+ const otherTargets = /* @__PURE__ */ new Set([
1523
+ "placeholder",
1524
+ "before",
1525
+ "after",
1526
+ "selection",
1527
+ "marker",
1528
+ "file",
1529
+ "first-letter",
1530
+ "first-line",
1531
+ "backdrop",
1532
+ "*",
1533
+ "**"
1534
+ ]);
1535
+ const stateSelectors = {
1536
+ hover: ":hover",
1537
+ focus: ":focus",
1538
+ "focus-within": ":focus-within",
1539
+ "focus-visible": ":focus-visible",
1540
+ active: ":active",
1541
+ disabled: ":disabled",
1542
+ enabled: ":enabled",
1543
+ checked: ":checked",
1544
+ indeterminate: ":indeterminate",
1545
+ invalid: ":invalid",
1546
+ valid: ":valid",
1547
+ required: ":required",
1548
+ optional: ":optional",
1549
+ "read-only": ":read-only",
1550
+ "placeholder-shown": ":placeholder-shown",
1551
+ empty: ":empty",
1552
+ open: ":is([open], :popover-open, :open)",
1553
+ first: ":first-child",
1554
+ last: ":last-child",
1555
+ only: ":only-child",
1556
+ odd: ":nth-child(odd)",
1557
+ even: ":nth-child(even)"
1558
+ };
1559
+ /** A CSS selector for one state variant, or `undefined` when its condition cannot be read from the element. */
1560
+ function variantSelector(variant) {
1561
+ if (variant.startsWith("not-")) {
1562
+ const inner = variantSelector(variant.slice(4));
1563
+ return inner && `:not(${inner})`;
1564
+ }
1565
+ if (variant.startsWith("has-")) {
1566
+ const inner = variantSelector(variant.slice(4));
1567
+ return inner && `:has(${inner})`;
1568
+ }
1569
+ if (stateSelectors[variant]) return stateSelectors[variant];
1570
+ if (variant.startsWith("aria-") && !variant.includes("[")) return `[aria-${variant.slice(5)}="true"]`;
1571
+ const arbitrary = variant.match(/^\[(&?)(:[^\s&>+~,]+)\]$/);
1572
+ return arbitrary ? arbitrary[2].replaceAll("_", " ") : void 0;
1573
+ }
1574
+ /**
1575
+ * How a variant class relates to an element's current value: `other` styles a pseudo-element or descendants,
1576
+ * `inactive` / `active` are state conditions read from the element, and `unknown` covers breakpoints, container
1577
+ * queries, group/peer state and anything else that cannot be checked from the element alone.
1578
+ */
1579
+ function variantState(variants, element) {
1580
+ if (variants.some((variant) => otherTargets.has(variant))) return "other";
1581
+ const selectors = variants.map(variantSelector);
1582
+ if (selectors.some((selector) => selector === void 0) || typeof element.matches !== "function") return "unknown";
1583
+ try {
1584
+ return element.matches(`*${selectors.join("")}`) ? "active" : "inactive";
1585
+ } catch {
1586
+ return "unknown";
1587
+ }
1588
+ }
1438
1589
  /** Breakpoint weight when every variant is an active breakpoint; `undefined` for state variants or inactive breakpoints. */
1439
1590
  function variantWeight(variants, viewportWidth, rootFontSize) {
1440
1591
  let weight = 0;
@@ -1545,17 +1696,21 @@ function inspectElement(element, isKnown) {
1545
1696
  const position = style.getPropertyValue("position");
1546
1697
  if (position && position !== "static") box.position = readSides("");
1547
1698
  const classes = Array.from(element.classList);
1548
- const plainClasses = classes.filter((name) => !splitVariants(name).variants.length && !name.includes("["));
1699
+ const plainOf = (list) => list.filter((name) => !splitVariants(name).variants.length && !name.includes("["));
1700
+ const plainClasses = plainOf(classes);
1549
1701
  const spacing = inspectTokens(plainClasses.join(" "), isKnown);
1550
- const candidates = (prefix, namespaces) => plainClasses.flatMap((raw) => {
1702
+ const candidates = (prefix, namespaces, suffix = "") => (plain) => plain.flatMap((raw) => {
1551
1703
  const utility = raw.replace(/^!|!$/g, "");
1552
1704
  if (!utility.startsWith(`${prefix}-`)) return [];
1553
- const suffix = utility.slice(prefix.length + 1);
1554
- return namespaces.map((namespace) => `--${namespace}${suffix}`);
1705
+ const name = utility.slice(prefix.length + 1);
1706
+ return namespaces.map((namespace) => `--${namespace}${name}${suffix}`);
1555
1707
  });
1556
- const variantsAffect = (prefixes) => classes.some((raw) => {
1708
+ const touches = (utility, prefixes) => prefixes.some((prefix) => utility.replace(/^!/, "").startsWith(`${prefix}-`));
1709
+ const variantsAffect = (node, list, plain, prefixes) => list.some((raw) => {
1557
1710
  const { variants, utility } = splitVariants(raw);
1558
- return variants.length > 0 && prefixes.some((prefix) => utility.replace(/^!/, "").startsWith(`${prefix}-`));
1711
+ if (!variants.length || plain.includes(utility) || !touches(utility, prefixes)) return false;
1712
+ const state = variantState(variants, node);
1713
+ return state === "active" || state === "unknown";
1559
1714
  });
1560
1715
  const equivalent = (value, computed, property) => {
1561
1716
  if (!value) return false;
@@ -1570,12 +1725,35 @@ function inspectElement(element, isKnown) {
1570
1725
  if (length[2] === "em") factor = Number.parseFloat(style.fontSize);
1571
1726
  return Math.abs(Number(length[1]) * factor - Number.parseFloat(computed)) < .02;
1572
1727
  }
1728
+ if (property === "line-height" && /^\d+(?:\.\d+)?$/.test(value) && computed.endsWith("px")) return Math.abs(Number(value) * Number.parseFloat(style.fontSize) - Number.parseFloat(computed)) < .05;
1573
1729
  return value.replace(/["']/g, "").replace(/\s+/g, " ") === computed.replace(/["']/g, "").replace(/\s+/g, " ");
1574
1730
  };
1575
- const property = (label, css, tokens = [], prefixes = []) => {
1731
+ const matchingToken = (nodeStyle, tokens, computed, css) => tokens.find((token) => !!token && isKnown(token) && equivalent(resolveToken(nodeStyle, token), computed, css));
1732
+ /**
1733
+ * Inherited properties (type and text color) usually come from an ancestor's utility, like the text style on a
1734
+ * field wrapper. Walk up to the first element whose plain class renders this value; stop where the value changes or
1735
+ * where a variant or arbitrary class sets it, since its active condition is unknown.
1736
+ */
1737
+ const inheritedToken = (css, computed, tokens, prefixes) => {
1738
+ for (let node = element.parentElement; node; node = node.parentElement) {
1739
+ const nodeStyle = view.getComputedStyle(node);
1740
+ if (css !== "line-height" && nodeStyle.getPropertyValue(css) !== computed) return void 0;
1741
+ const list = Array.from(node.classList);
1742
+ const plain = plainOf(list);
1743
+ if (variantsAffect(node, list, plain, prefixes)) return void 0;
1744
+ const token = matchingToken(nodeStyle, tokens(plain), computed, css);
1745
+ if (token) return token;
1746
+ if (list.some((name) => name.includes("[") && touches(splitVariants(name).utility, prefixes))) return void 0;
1747
+ }
1748
+ };
1749
+ const setsOwn = (css, prefixes) => classes.some((name) => {
1750
+ const { utility } = splitVariants(name);
1751
+ return name.includes("[") && touches(utility, prefixes) || css === "line-height" && touches(utility, ["leading"]) || css === "letter-spacing" && touches(utility, ["tracking"]);
1752
+ });
1753
+ const property = (label, css, tokens = [], prefixes = [], inherited = false) => {
1576
1754
  const computed = style.getPropertyValue(css);
1577
- const matching = variantsAffect(prefixes) ? [] : tokens.filter((token) => !!token && isKnown(token) && equivalent(resolveToken(style, token), computed, css));
1578
- const token = [...new Set(matching)][0];
1755
+ const own = typeof tokens === "function" ? tokens(plainClasses) : tokens;
1756
+ const token = variantsAffect(element, classes, plainClasses, prefixes) ? void 0 : matchingToken(style, own, computed, css) ?? (inherited && typeof tokens === "function" && !setsOwn(css, prefixes) ? inheritedToken(css, computed, tokens, prefixes) : void 0);
1579
1757
  const isColor = css.includes("color");
1580
1758
  return {
1581
1759
  label,
@@ -1618,18 +1796,19 @@ function inspectElement(element, isKnown) {
1618
1796
  property("Radius", "border-radius", [spacing.radius], ["rounded"]),
1619
1797
  ...sides.map((side) => property(`Border ${side} width`, `border-${side}-width`))
1620
1798
  ];
1799
+ const withBase = (tokens) => (plain) => tokens(plain).flatMap((token) => [token, `${token}-base`]);
1621
1800
  const typography = [
1622
- property("Font", "font-family", candidates("font", ["font-"]), ["font"]),
1623
- property("Size", "font-size", candidates("text", ["text-"]), ["text"]),
1624
- property("Weight", "font-weight", candidates("font", ["font-weight-"]), ["font"]),
1625
- property("Line height", "line-height"),
1626
- property("Letter spacing", "letter-spacing"),
1801
+ property("Font", "font-family", candidates("font", ["font-"]), ["font"], true),
1802
+ property("Size", "font-size", candidates("text", ["text-"]), ["text"], true),
1803
+ property("Weight", "font-weight", candidates("font", ["font-weight-"]), ["font"], true),
1804
+ property("Line height", "line-height", candidates("text", ["text-"], "--line-height"), ["text", "leading"], true),
1805
+ property("Letter spacing", "letter-spacing", candidates("text", ["text-"], "--letter-spacing"), ["text", "tracking"], true),
1627
1806
  property("Alignment", "text-align")
1628
1807
  ];
1629
1808
  const appearance = [
1630
- property("Text", "color", candidates("text", ["color-", ""]).flatMap((token) => [token, `${token}-base`]), ["text"]),
1631
- property("Fill", "background-color", candidates("bg", ["color-", ""]).flatMap((token) => [token, `${token}-base`]), ["bg"]),
1632
- property("Border", "border-top-color", candidates("border", ["color-", ""]).flatMap((token) => [token, `${token}-base`]), ["border"]),
1809
+ property("Text", "color", withBase(candidates("text", ["color-", ""])), ["text"], true),
1810
+ property("Fill", "background-color", withBase(candidates("bg", ["color-", ""])), ["bg"]),
1811
+ property("Border", "border-top-color", withBase(candidates("border", ["color-", ""])), ["border"]),
1633
1812
  property("Opacity", "opacity"),
1634
1813
  property("Shadow", "box-shadow")
1635
1814
  ];
@@ -2446,9 +2625,20 @@ function useStudioWindow(bounds, enabled = true) {
2446
2625
  }
2447
2626
  };
2448
2627
  }
2628
+ const move = controls("move");
2449
2629
  return {
2450
2630
  ref,
2451
- move: controls("move"),
2631
+ move,
2632
+ dragArea: {
2633
+ onPointerMove: (event_3) => move.onPointerMove(event_3),
2634
+ onPointerUp: (event_4) => move.onPointerUp(event_4),
2635
+ onLostPointerCapture: move.onLostPointerCapture,
2636
+ onPointerCancel: move.onPointerCancel,
2637
+ onPointerDown(event_5) {
2638
+ if (event_5.target.closest("button, input, select, textarea, a, label, [role='tab']")) return;
2639
+ move.onPointerDown(event_5);
2640
+ }
2641
+ },
2452
2642
  resize: (edge) => controls(edge)
2453
2643
  };
2454
2644
  }
@@ -4535,8 +4725,8 @@ function familyName(value) {
4535
4725
  * theme's font families, like a design tool's font picker.
4536
4726
  */
4537
4727
  function FontRoleCard(t0) {
4538
- const $ = c(44);
4539
- const { label, value, options, changed, onChange, onReset } = t0;
4728
+ const $ = c(46);
4729
+ const { label, value, options, changed, onChange, onReset, token, highlighted } = t0;
4540
4730
  let t1;
4541
4731
  if ($[0] !== options || $[1] !== value) {
4542
4732
  let t2;
@@ -4551,112 +4741,113 @@ function FontRoleCard(t0) {
4551
4741
  $[2] = t1;
4552
4742
  } else t1 = $[2];
4553
4743
  const selected = t1;
4554
- let t2;
4744
+ const t2 = `studio-font-role ${highlighted ? "is-highlighted" : ""}`;
4745
+ let t3;
4555
4746
  if ($[5] !== label) {
4556
- t2 = /* @__PURE__ */ jsx("span", { children: label });
4747
+ t3 = /* @__PURE__ */ jsx("span", { children: label });
4557
4748
  $[5] = label;
4558
- $[6] = t2;
4559
- } else t2 = $[6];
4560
- let t3;
4749
+ $[6] = t3;
4750
+ } else t3 = $[6];
4751
+ let t4;
4561
4752
  if ($[7] !== selected?.label || $[8] !== value) {
4562
- t3 = selected?.label ?? familyName(value);
4753
+ t4 = selected?.label ?? familyName(value);
4563
4754
  $[7] = selected?.label;
4564
4755
  $[8] = value;
4565
- $[9] = t3;
4566
- } else t3 = $[9];
4567
- let t4;
4568
- if ($[10] !== t3) {
4569
- t4 = /* @__PURE__ */ jsx("strong", { children: t3 });
4570
- $[10] = t3;
4571
- $[11] = t4;
4572
- } else t4 = $[11];
4756
+ $[9] = t4;
4757
+ } else t4 = $[9];
4573
4758
  let t5;
4574
- if ($[12] !== t2 || $[13] !== t4) {
4575
- t5 = /* @__PURE__ */ jsxs("span", {
4759
+ if ($[10] !== t4) {
4760
+ t5 = /* @__PURE__ */ jsx("strong", { children: t4 });
4761
+ $[10] = t4;
4762
+ $[11] = t5;
4763
+ } else t5 = $[11];
4764
+ let t6;
4765
+ if ($[12] !== t3 || $[13] !== t5) {
4766
+ t6 = /* @__PURE__ */ jsxs("span", {
4576
4767
  className: "studio-font-role-text",
4577
- children: [t2, t4]
4768
+ children: [t3, t5]
4578
4769
  });
4579
- $[12] = t2;
4580
- $[13] = t4;
4581
- $[14] = t5;
4582
- } else t5 = $[14];
4583
- let t6;
4770
+ $[12] = t3;
4771
+ $[13] = t5;
4772
+ $[14] = t6;
4773
+ } else t6 = $[14];
4774
+ let t7;
4584
4775
  if ($[15] !== value) {
4585
- t6 = /* @__PURE__ */ jsx("span", {
4776
+ t7 = /* @__PURE__ */ jsx("span", {
4586
4777
  className: "studio-font-role-sample",
4587
4778
  style: { fontFamily: value },
4588
4779
  "aria-hidden": "true",
4589
4780
  children: "Aa"
4590
4781
  });
4591
4782
  $[15] = value;
4592
- $[16] = t6;
4593
- } else t6 = $[16];
4594
- const t7 = `${label} font`;
4595
- const t8 = selected?.name ?? "";
4596
- let t9;
4783
+ $[16] = t7;
4784
+ } else t7 = $[16];
4785
+ const t8 = `${label} font`;
4786
+ const t9 = selected?.name ?? "";
4787
+ let t10;
4597
4788
  if ($[17] !== onChange || $[18] !== options) {
4598
- t9 = (event) => {
4599
- const option_0 = options.find((t10) => {
4600
- const { name } = t10;
4789
+ t10 = (event) => {
4790
+ const option_0 = options.find((t11) => {
4791
+ const { name } = t11;
4601
4792
  return name === event.target.value;
4602
4793
  });
4603
4794
  if (option_0) onChange(option_0.value);
4604
4795
  };
4605
4796
  $[17] = onChange;
4606
4797
  $[18] = options;
4607
- $[19] = t9;
4608
- } else t9 = $[19];
4609
- let t10;
4798
+ $[19] = t10;
4799
+ } else t10 = $[19];
4800
+ let t11;
4610
4801
  if ($[20] !== selected) {
4611
- t10 = !selected && /* @__PURE__ */ jsx("option", {
4802
+ t11 = !selected && /* @__PURE__ */ jsx("option", {
4612
4803
  value: "",
4613
4804
  disabled: true,
4614
4805
  children: "Custom"
4615
4806
  });
4616
4807
  $[20] = selected;
4617
- $[21] = t10;
4618
- } else t10 = $[21];
4619
- let t11;
4808
+ $[21] = t11;
4809
+ } else t11 = $[21];
4810
+ let t12;
4620
4811
  if ($[22] !== options) {
4621
- t11 = new Set(options.map(_temp3));
4812
+ t12 = new Set(options.map(_temp3));
4622
4813
  $[22] = options;
4623
- $[23] = t11;
4624
- } else t11 = $[23];
4625
- let t12;
4626
- if ($[24] !== t11) {
4627
- t12 = [...t11];
4628
- $[24] = t11;
4629
- $[25] = t12;
4630
- } else t12 = $[25];
4814
+ $[23] = t12;
4815
+ } else t12 = $[23];
4631
4816
  let t13;
4632
- if ($[26] !== options || $[27] !== t12) {
4633
- t13 = t12.map((group_0) => /* @__PURE__ */ jsx("optgroup", {
4817
+ if ($[24] !== t12) {
4818
+ t13 = [...t12];
4819
+ $[24] = t12;
4820
+ $[25] = t13;
4821
+ } else t13 = $[25];
4822
+ let t14;
4823
+ if ($[26] !== options || $[27] !== t13) {
4824
+ t14 = t13.map((group_0) => /* @__PURE__ */ jsx("optgroup", {
4634
4825
  label: group_0,
4635
4826
  children: options.filter((option_1) => option_1.group === group_0).map(_temp4)
4636
4827
  }, group_0));
4637
4828
  $[26] = options;
4638
- $[27] = t12;
4639
- $[28] = t13;
4640
- } else t13 = $[28];
4641
- let t14;
4642
- if ($[29] !== t10 || $[30] !== t13 || $[31] !== t7 || $[32] !== t8 || $[33] !== t9) {
4643
- t14 = /* @__PURE__ */ jsxs("select", {
4829
+ $[27] = t13;
4830
+ $[28] = t14;
4831
+ } else t14 = $[28];
4832
+ let t15;
4833
+ if ($[29] !== t10 || $[30] !== t11 || $[31] !== t14 || $[32] !== t8 || $[33] !== t9) {
4834
+ t15 = /* @__PURE__ */ jsxs("select", {
4644
4835
  className: "studio-font-role-select",
4645
- "aria-label": t7,
4646
- value: t8,
4647
- onChange: t9,
4648
- children: [t10, t13]
4836
+ "aria-label": t8,
4837
+ value: t9,
4838
+ onChange: t10,
4839
+ children: [t11, t14]
4649
4840
  });
4650
4841
  $[29] = t10;
4651
- $[30] = t13;
4652
- $[31] = t7;
4842
+ $[30] = t11;
4843
+ $[31] = t14;
4653
4844
  $[32] = t8;
4654
4845
  $[33] = t9;
4655
- $[34] = t14;
4656
- } else t14 = $[34];
4657
- let t15;
4846
+ $[34] = t15;
4847
+ } else t15 = $[34];
4848
+ let t16;
4658
4849
  if ($[35] !== changed || $[36] !== label || $[37] !== onReset) {
4659
- t15 = changed && /* @__PURE__ */ jsx("button", {
4850
+ t16 = changed && /* @__PURE__ */ jsx("button", {
4660
4851
  type: "button",
4661
4852
  className: "studio-font-role-reset",
4662
4853
  "aria-label": `Reset ${label} font`,
@@ -4670,26 +4861,29 @@ function FontRoleCard(t0) {
4670
4861
  $[35] = changed;
4671
4862
  $[36] = label;
4672
4863
  $[37] = onReset;
4673
- $[38] = t15;
4674
- } else t15 = $[38];
4675
- let t16;
4676
- if ($[39] !== t14 || $[40] !== t15 || $[41] !== t5 || $[42] !== t6) {
4677
- t16 = /* @__PURE__ */ jsxs("div", {
4678
- className: "studio-font-role",
4864
+ $[38] = t16;
4865
+ } else t16 = $[38];
4866
+ let t17;
4867
+ if ($[39] !== t15 || $[40] !== t16 || $[41] !== t2 || $[42] !== t6 || $[43] !== t7 || $[44] !== token) {
4868
+ t17 = /* @__PURE__ */ jsxs("div", {
4869
+ className: t2,
4870
+ "data-token": token,
4679
4871
  children: [
4680
- t5,
4681
4872
  t6,
4682
- t14,
4683
- t15
4873
+ t7,
4874
+ t15,
4875
+ t16
4684
4876
  ]
4685
4877
  });
4686
- $[39] = t14;
4687
- $[40] = t15;
4688
- $[41] = t5;
4878
+ $[39] = t15;
4879
+ $[40] = t16;
4880
+ $[41] = t2;
4689
4881
  $[42] = t6;
4690
- $[43] = t16;
4691
- } else t16 = $[43];
4692
- return t16;
4882
+ $[43] = t7;
4883
+ $[44] = token;
4884
+ $[45] = t17;
4885
+ } else t17 = $[45];
4886
+ return t17;
4693
4887
  }
4694
4888
  function _temp4(option_2) {
4695
4889
  return /* @__PURE__ */ jsx("option", {
@@ -5248,6 +5442,67 @@ function _temp(t0) {
5248
5442
  return step;
5249
5443
  }
5250
5444
  //#endregion
5445
+ //#region src/configurator/ComponentPreview.tsx
5446
+ const ComponentGallery = lazy(() => import("./ComponentGallery-D4U5hXZL.js"));
5447
+ /** Every component, styled by a configuration; the configurator's preview and the App Canvas Components view. */
5448
+ function ComponentPreview(t0) {
5449
+ const $ = c(14);
5450
+ const { value, mode, inspector } = t0;
5451
+ const { defaults } = useUIConfiguration();
5452
+ const t1 = value.config;
5453
+ const t2 = `studio-sample ${mode}`;
5454
+ let t3;
5455
+ if ($[0] !== defaults || $[1] !== mode || $[2] !== value.theme) {
5456
+ t3 = previewTokens(defaults, value.theme, mode);
5457
+ $[0] = defaults;
5458
+ $[1] = mode;
5459
+ $[2] = value.theme;
5460
+ $[3] = t3;
5461
+ } else t3 = $[3];
5462
+ const t4 = t3;
5463
+ let t5;
5464
+ if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
5465
+ t5 = /* @__PURE__ */ jsx("p", {
5466
+ className: "studio-gallery-loading",
5467
+ children: "Loading components…"
5468
+ });
5469
+ $[4] = t5;
5470
+ } else t5 = $[4];
5471
+ let t6;
5472
+ if ($[5] !== inspector) {
5473
+ t6 = /* @__PURE__ */ jsx(Suspense, {
5474
+ fallback: t5,
5475
+ children: /* @__PURE__ */ jsx(ComponentGallery, { inspector })
5476
+ });
5477
+ $[5] = inspector;
5478
+ $[6] = t6;
5479
+ } else t6 = $[6];
5480
+ let t7;
5481
+ if ($[7] !== t2 || $[8] !== t4 || $[9] !== t6) {
5482
+ t7 = /* @__PURE__ */ jsx("div", {
5483
+ className: t2,
5484
+ style: t4,
5485
+ "data-testid": "component-preview",
5486
+ children: t6
5487
+ });
5488
+ $[7] = t2;
5489
+ $[8] = t4;
5490
+ $[9] = t6;
5491
+ $[10] = t7;
5492
+ } else t7 = $[10];
5493
+ let t8;
5494
+ if ($[11] !== t7 || $[12] !== value.config) {
5495
+ t8 = /* @__PURE__ */ jsx(UIConfig.Provider, {
5496
+ config: t1,
5497
+ children: t7
5498
+ });
5499
+ $[11] = t7;
5500
+ $[12] = value.config;
5501
+ $[13] = t8;
5502
+ } else t8 = $[13];
5503
+ return t8;
5504
+ }
5505
+ //#endregion
5251
5506
  //#region src/configurator/UIConfigurator.tsx
5252
5507
  const colorNamespaces = {
5253
5508
  surface: "Surfaces",
@@ -5346,64 +5601,6 @@ function groupKeyFor(section, name, defaults) {
5346
5601
  const textStyle = section === "Typography" ? name.match(/^--text-(.+?)(?:--.+)?$/)?.[1] : void 0;
5347
5602
  return textStyle ? `--text-${textStyle}` : section === "Typography" ? name.startsWith("--font-weight-") ? "Font weights" : name.startsWith("--font-") ? "Font families" : "Letter spacing" : section === "Colors" ? baseColorNames(defaults).has(name) ? `Base system · ${name.slice(2).split("-")[0]}` : colorNamespaces[name.slice(2).split("-")[0]] ?? "Other" : section === "Spacing" || section === "Radius" || section === "Sizing" ? componentToken(name).title : section === "Effects" ? effectToken(name).title : "tokens";
5348
5603
  }
5349
- const ComponentGallery = lazy(() => import("./ComponentGallery-CMFrbwEN.js"));
5350
- function ComponentPreview(t0) {
5351
- const $ = c(14);
5352
- const { value, mode, inspector } = t0;
5353
- const { defaults } = useUIConfiguration();
5354
- const t1 = value.config;
5355
- const t2 = `studio-sample ${mode}`;
5356
- let t3;
5357
- if ($[0] !== defaults || $[1] !== mode || $[2] !== value.theme) {
5358
- t3 = previewTokens(defaults, value.theme, mode);
5359
- $[0] = defaults;
5360
- $[1] = mode;
5361
- $[2] = value.theme;
5362
- $[3] = t3;
5363
- } else t3 = $[3];
5364
- const t4 = t3;
5365
- let t5;
5366
- if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
5367
- t5 = /* @__PURE__ */ jsx("p", {
5368
- className: "studio-gallery-loading",
5369
- children: "Loading components…"
5370
- });
5371
- $[4] = t5;
5372
- } else t5 = $[4];
5373
- let t6;
5374
- if ($[5] !== inspector) {
5375
- t6 = /* @__PURE__ */ jsx(Suspense, {
5376
- fallback: t5,
5377
- children: /* @__PURE__ */ jsx(ComponentGallery, { inspector })
5378
- });
5379
- $[5] = inspector;
5380
- $[6] = t6;
5381
- } else t6 = $[6];
5382
- let t7;
5383
- if ($[7] !== t2 || $[8] !== t4 || $[9] !== t6) {
5384
- t7 = /* @__PURE__ */ jsx("div", {
5385
- className: t2,
5386
- style: t4,
5387
- "data-testid": "component-preview",
5388
- children: t6
5389
- });
5390
- $[7] = t2;
5391
- $[8] = t4;
5392
- $[9] = t6;
5393
- $[10] = t7;
5394
- } else t7 = $[10];
5395
- let t8;
5396
- if ($[11] !== t7 || $[12] !== value.config) {
5397
- t8 = /* @__PURE__ */ jsx(UIConfig.Provider, {
5398
- config: t1,
5399
- children: t7
5400
- });
5401
- $[11] = t7;
5402
- $[12] = value.config;
5403
- $[13] = t8;
5404
- } else t8 = $[13];
5405
- return t8;
5406
- }
5407
5604
  /** Changing a text style's font size sets its line height to this multiple of it; the line height stays editable. */
5408
5605
  const fontSizeLineHeight = "1.5";
5409
5606
  const remPresets = [
@@ -5591,20 +5788,34 @@ function TokenField({ name, value, original, changed, onChange, onReset, onValid
5591
5788
  });
5592
5789
  }
5593
5790
  function PopoutOverlay(t0) {
5594
- const $ = c(3);
5595
- const { children, className } = t0;
5791
+ const $ = c(6);
5792
+ const { children, className, onOpenChange } = t0;
5596
5793
  const t1 = className ?? "studio-overlay";
5597
5794
  let t2;
5598
- if ($[0] !== children || $[1] !== t1) {
5599
- t2 = /* @__PURE__ */ jsx("div", {
5795
+ if ($[0] !== onOpenChange) {
5796
+ t2 = (event) => {
5797
+ if (event.key === "Escape" && !event.defaultPrevented) {
5798
+ event.preventDefault();
5799
+ event.stopPropagation();
5800
+ onOpenChange?.(false);
5801
+ }
5802
+ };
5803
+ $[0] = onOpenChange;
5804
+ $[1] = t2;
5805
+ } else t2 = $[1];
5806
+ let t3;
5807
+ if ($[2] !== children || $[3] !== t1 || $[4] !== t2) {
5808
+ t3 = /* @__PURE__ */ jsx("div", {
5600
5809
  className: t1,
5810
+ onKeyDown: t2,
5601
5811
  children
5602
5812
  });
5603
- $[0] = children;
5604
- $[1] = t1;
5605
- $[2] = t2;
5606
- } else t2 = $[2];
5607
- return t2;
5813
+ $[2] = children;
5814
+ $[3] = t1;
5815
+ $[4] = t2;
5816
+ $[5] = t3;
5817
+ } else t3 = $[5];
5818
+ return t3;
5608
5819
  }
5609
5820
  function ConfigurationModalContent({ memory, windowBounds, poppedOut, floating, onPopout, onDock, onMinimize, popupBlocked }) {
5610
5821
  const Overlay = poppedOut || floating ? PopoutOverlay : $8b8d26808cb8cb53$export$8948f78d83984c69;
@@ -5621,7 +5832,7 @@ function ConfigurationModalContent({ memory, windowBounds, poppedOut, floating,
5621
5832
  return () => observer.disconnect();
5622
5833
  }, [studioWindow.ref]);
5623
5834
  const inherited = UIConfig.useConfig();
5624
- const { defaults, draft, setDraft, isOpen, cancel, apply, revision } = useUIConfiguration();
5835
+ const { defaults, draft, setDraft, isOpen, apply, revision, tokenRequest, clearTokenRequest, componentsHosted } = useUIConfiguration();
5625
5836
  const remembered = memory.current;
5626
5837
  const [mode, setMode] = useState(remembered.mode ?? "light");
5627
5838
  const [sizeUnit, setSizeUnit] = useState(remembered.sizeUnit ?? "px");
@@ -5708,7 +5919,7 @@ function ConfigurationModalContent({ memory, windowBounds, poppedOut, floating,
5708
5919
  setHighlightedToken(null);
5709
5920
  };
5710
5921
  const [highlightedToken, setHighlightedToken] = useState(null);
5711
- const isInspectable = useCallback((name) => (name in defaults.theme || name in defaults.light || name in defaults.dark) && groups.includes(groupFor(name)) && !name.startsWith("--color-"), [defaults]);
5922
+ const isInspectable = useCallback((name) => isEditableToken(name, defaults), [defaults]);
5712
5923
  const describeToken = useCallback((name_0) => {
5713
5924
  const section_0 = sectionFor(name_0);
5714
5925
  const bucket = mode === "dark" && name_0 in defaults.dark ? "dark" : name_0 in defaults.light ? "light" : "theme";
@@ -5746,10 +5957,20 @@ function ConfigurationModalContent({ memory, windowBounds, poppedOut, floating,
5746
5957
  }));
5747
5958
  setHighlightedToken(name_1);
5748
5959
  }, [defaults]);
5960
+ useEffect(() => {
5961
+ if (!tokenRequest) return;
5962
+ focusToken(tokenRequest.name);
5963
+ clearTokenRequest();
5964
+ }, [
5965
+ tokenRequest,
5966
+ focusToken,
5967
+ clearTokenRequest
5968
+ ]);
5749
5969
  useEffect(() => {
5750
5970
  if (!highlightedToken) return;
5751
5971
  const frame_0 = requestAnimationFrame(() => {
5752
- (editorRef.current?.ownerDocument.getElementById(`token-${highlightedToken}`)?.closest(".studio-token"))?.scrollIntoView({
5972
+ const doc = editorRef.current?.ownerDocument;
5973
+ (doc?.getElementById(`token-${highlightedToken}`)?.closest(".studio-token") ?? doc?.querySelector(`.studio-font-role[data-token="${CSS.escape(highlightedToken)}"]`))?.scrollIntoView({
5753
5974
  block: "center",
5754
5975
  behavior: "smooth"
5755
5976
  });
@@ -5803,7 +6024,7 @@ function ConfigurationModalContent({ memory, windowBounds, poppedOut, floating,
5803
6024
  }));
5804
6025
  setInvalidFields({});
5805
6026
  setResetRevision((value_5) => value_5 + 1);
5806
- setMessage(`${preset.label} preset applied. Apply settings to keep it.`);
6027
+ setMessage(`${preset.label} preset applied. Changes stay in this session.`);
5807
6028
  };
5808
6029
  const setComponent = (key_0, field, value_6) => {
5809
6030
  setDraft((current_9) => ({
@@ -5886,17 +6107,17 @@ function ConfigurationModalContent({ memory, windowBounds, poppedOut, floating,
5886
6107
  const inActiveTab = (key_6) => !tabbed || tabFor(key_6) === activeSectionTab;
5887
6108
  const flatTab = tabbed && section === "Typography" && activeSectionTab !== textStylesTab;
5888
6109
  const orderedGroups = [...visibleGroups].filter(([key_7]) => inActiveTab(key_7)).sort(([a_0], [b_0]) => groupRank(a_0) - groupRank(b_0));
5889
- const collapsibleKeys = sectionKeys.filter(inActiveTab);
6110
+ const collapsibleKeys = sectionKeys.filter((key_8) => inActiveTab(key_8) && !groupedEntries.get(key_8)?.compact);
5890
6111
  const primaryGroup = collapsibleKeys[0];
5891
- const isExpanded = (key_8) => searching || (expandedGroups[`${section}:${key_8}`] ?? key_8 === primaryGroup);
5892
- const toggleGroup = (key_9) => setExpandedGroups((current_10) => ({
6112
+ const isExpanded = (key_9) => searching || (expandedGroups[`${section}:${key_9}`] ?? key_9 === primaryGroup);
6113
+ const toggleGroup = (key_10) => setExpandedGroups((current_10) => ({
5893
6114
  ...current_10,
5894
- [`${section}:${key_9}`]: !isExpanded(key_9)
6115
+ [`${section}:${key_10}`]: !isExpanded(key_10)
5895
6116
  }));
5896
6117
  const allExpanded = collapsibleKeys.every(isExpanded);
5897
6118
  const setAllGroups = (expanded) => setExpandedGroups((current_11) => ({
5898
6119
  ...current_11,
5899
- ...Object.fromEntries(collapsibleKeys.map((key_10) => [`${section}:${key_10}`, expanded]))
6120
+ ...Object.fromEntries(collapsibleKeys.map((key_11) => [`${section}:${key_11}`, expanded]))
5900
6121
  }));
5901
6122
  const groupChanged = (entries_1) => entries_1.some(([name_19]) => {
5902
6123
  const bucket_1 = mode === "dark" && name_19 in defaults.dark ? "dark" : name_19 in defaults.light ? "light" : "theme";
@@ -5970,7 +6191,9 @@ function ConfigurationModalContent({ memory, windowBounds, poppedOut, floating,
5970
6191
  options,
5971
6192
  changed: name_24 in draft.theme.theme,
5972
6193
  onChange: (value_12) => setToken(name_24, value_12),
5973
- onReset: () => setToken(name_24)
6194
+ onReset: () => setToken(name_24),
6195
+ token: name_24,
6196
+ highlighted: highlightedToken === name_24
5974
6197
  }, `${revision}-${resetRevision}-${name_24}`))
5975
6198
  }),
5976
6199
  /* @__PURE__ */ jsx(FontUpload, { onUpload: refreshLoadedFonts }),
@@ -5978,7 +6201,39 @@ function ConfigurationModalContent({ memory, windowBounds, poppedOut, floating,
5978
6201
  ]
5979
6202
  }, "font-families");
5980
6203
  };
6204
+ const textStyleColumns = [
6205
+ "Font size",
6206
+ "Line height",
6207
+ "Letter spacing"
6208
+ ];
6209
+ const textStyleColumn = (name_25) => name_25.endsWith("--line-height") ? 1 : name_25.endsWith("--letter-spacing") ? 2 : 0;
6210
+ const firstTextStyle = orderedGroups.find(([, group_3]) => group_3.compact)?.[0];
6211
+ /** One table row per text style, under a single column header; a style without a token leaves its cell empty. */
6212
+ const renderTextStyleRow = (key_12, group_4) => /* @__PURE__ */ jsxs(Fragment, { children: [key_12 === firstTextStyle && /* @__PURE__ */ jsxs("div", {
6213
+ className: "studio-type-row studio-type-head",
6214
+ "aria-hidden": "true",
6215
+ children: [/* @__PURE__ */ jsx("span", { children: "Style" }), textStyleColumns.map((column) => /* @__PURE__ */ jsx("span", { children: column }, column))]
6216
+ }), /* @__PURE__ */ jsxs("div", {
6217
+ className: "studio-type-row",
6218
+ role: "group",
6219
+ "aria-label": group_4.title,
6220
+ children: [/* @__PURE__ */ jsxs("span", {
6221
+ className: "studio-type-name",
6222
+ children: [group_4.title, groupChanged(group_4.entries) && /* @__PURE__ */ jsx("span", {
6223
+ className: "studio-group-changed",
6224
+ "aria-label": "has changes"
6225
+ })]
6226
+ }), textStyleColumns.map((column_0, index) => {
6227
+ const entry_3 = group_4.entries.find(([name_26]) => textStyleColumn(name_26) === index);
6228
+ return /* @__PURE__ */ jsx("div", {
6229
+ className: "studio-type-cell",
6230
+ children: entry_3 && renderToken(entry_3, true)
6231
+ }, column_0);
6232
+ })]
6233
+ })] }, key_12);
5981
6234
  const showTabs = sectionTabList.length > 1 && isTokenSection(section);
6235
+ const overrideCount = `${changedCount} ${changedCount === 1 ? "override" : "overrides"}`;
6236
+ const footerStatus = Object.keys(invalidFields).length ? "Fix invalid values or reset before exporting." : nothingToReset && !changedCount ? "No active changes to reset." : (popupBlocked ? "Allow pop-ups for this site, then try again." : message) || overrideCount;
5982
6237
  const toggleAllButton = isTokenSection(section) && !flatTab && collapsibleKeys.length > 1 && /* @__PURE__ */ jsxs("button", {
5983
6238
  type: "button",
5984
6239
  className: "studio-toggle-all",
@@ -5989,32 +6244,34 @@ function ConfigurationModalContent({ memory, windowBounds, poppedOut, floating,
5989
6244
  "aria-hidden": "true"
5990
6245
  }), allExpanded ? "Collapse all" : "Expand all"]
5991
6246
  });
5992
- const selectControl = (label, key_11, field_1, options_0) => /* @__PURE__ */ jsxs("label", {
6247
+ const selectControl = (label, key_13, field_1, options_0) => /* @__PURE__ */ jsxs("label", {
5993
6248
  className: "studio-setting",
5994
6249
  children: [/* @__PURE__ */ jsx("span", { children: label }), /* @__PURE__ */ jsx("select", {
5995
6250
  "aria-label": label,
5996
- value: String(config[key_11][field_1]),
5997
- onChange: (event) => setComponent(key_11, field_1, event.target.value),
6251
+ value: String(config[key_13][field_1]),
6252
+ onChange: (event) => setComponent(key_13, field_1, event.target.value),
5998
6253
  children: options_0.map((option) => /* @__PURE__ */ jsx("option", { children: option }, option))
5999
6254
  })]
6000
- }, `${key_11}-${field_1}`);
6255
+ }, `${key_13}-${field_1}`);
6001
6256
  return /* @__PURE__ */ jsx(Overlay, {
6002
6257
  className: `studio-overlay${floating && !poppedOut ? " studio-overlay-floating" : ""}`,
6003
6258
  isOpen,
6004
6259
  onOpenChange: (next_2) => {
6005
- if (!next_2) cancel();
6260
+ if (!next_2) apply();
6006
6261
  },
6007
6262
  isDismissable: false,
6008
6263
  children: /* @__PURE__ */ jsx(Surface, {
6009
6264
  className: `studio-modal${poppedOut ? " studio-modal-popout" : ""}`,
6010
6265
  ref: studioWindow.ref,
6266
+ "data-components-hosted": componentsHosted || void 0,
6011
6267
  children: /* @__PURE__ */ jsxs($f2ff30fde7b014be$export$3ddf2d174ce01153, {
6012
6268
  className: "studio-dialog",
6013
- "data-compact-preview": compactPreview || void 0,
6269
+ "data-compact-preview": compactPreview && !componentsHosted || void 0,
6014
6270
  style: { "--studio-editor-track": editorWidth ? `minmax(260px, ${editorWidth}px)` : void 0 },
6015
6271
  children: [
6016
6272
  /* @__PURE__ */ jsxs("header", {
6017
6273
  className: "studio-topbar",
6274
+ ...poppedOut ? {} : studioWindow.dragArea,
6018
6275
  children: [
6019
6276
  /* @__PURE__ */ jsx("div", {
6020
6277
  className: "studio-title",
@@ -6029,11 +6286,11 @@ function ConfigurationModalContent({ memory, windowBounds, poppedOut, floating,
6029
6286
  children: [/* @__PURE__ */ jsxs("div", {
6030
6287
  className: "studio-section-tabs",
6031
6288
  children: [
6032
- navSections.map((group_3) => /* @__PURE__ */ jsx("button", {
6033
- "aria-current": !compactPreview && (group_3 === "Layout" ? isLayoutKind(section) : section === group_3) ? "page" : void 0,
6034
- onClick: () => changeSection(group_3 === "Layout" ? lastLayoutSection : group_3),
6035
- children: group_3
6036
- }, group_3)),
6289
+ navSections.map((group_5) => /* @__PURE__ */ jsx("button", {
6290
+ "aria-current": !compactPreview && (group_5 === "Layout" ? isLayoutKind(section) : section === group_5) ? "page" : void 0,
6291
+ onClick: () => changeSection(group_5 === "Layout" ? lastLayoutSection : group_5),
6292
+ children: group_5
6293
+ }, group_5)),
6037
6294
  /* @__PURE__ */ jsx("span", {
6038
6295
  className: "studio-nav-divider",
6039
6296
  "aria-hidden": "true"
@@ -6044,7 +6301,7 @@ function ConfigurationModalContent({ memory, windowBounds, poppedOut, floating,
6044
6301
  children: "Advanced"
6045
6302
  })
6046
6303
  ]
6047
- }), /* @__PURE__ */ jsx("button", {
6304
+ }), !componentsHosted && /* @__PURE__ */ jsx("button", {
6048
6305
  type: "button",
6049
6306
  className: "studio-preview-tab",
6050
6307
  "aria-current": compactPreview ? "page" : void 0,
@@ -6053,20 +6310,37 @@ function ConfigurationModalContent({ memory, windowBounds, poppedOut, floating,
6053
6310
  const dialog = bodyRef.current?.parentElement;
6054
6311
  if (dialog) dialog.scrollTop = 0;
6055
6312
  },
6056
- children: "Live preview"
6313
+ children: "Components"
6057
6314
  })]
6058
6315
  }),
6059
6316
  /* @__PURE__ */ jsx("div", {
6060
6317
  className: "studio-topbar-controls",
6061
6318
  children: /* @__PURE__ */ jsxs("label", {
6062
6319
  className: "studio-search",
6063
- children: [/* @__PURE__ */ jsx(Search, { size: 14 }), /* @__PURE__ */ jsx("input", {
6064
- "aria-label": "Search tokens",
6065
- placeholder: "Search tokens",
6066
- value: search,
6067
- disabled: !isTokenSection(section),
6068
- onChange: (event_0) => setSearch(event_0.target.value)
6069
- })]
6320
+ title: "Search tokens",
6321
+ children: [
6322
+ /* @__PURE__ */ jsx(Search, { size: 14 }),
6323
+ /* @__PURE__ */ jsx("input", {
6324
+ "aria-label": "Search tokens",
6325
+ placeholder: "Search tokens",
6326
+ value: search,
6327
+ disabled: !isTokenSection(section),
6328
+ onChange: (event_0) => setSearch(event_0.target.value),
6329
+ onKeyDown: (event_1) => {
6330
+ if (event_1.key !== "Escape") return;
6331
+ event_1.stopPropagation();
6332
+ if (search) setSearch("");
6333
+ else event_1.currentTarget.blur();
6334
+ }
6335
+ }),
6336
+ search && /* @__PURE__ */ jsx("button", {
6337
+ type: "button",
6338
+ className: "studio-search-clear",
6339
+ "aria-label": "Clear search",
6340
+ onClick: () => setSearch(""),
6341
+ children: /* @__PURE__ */ jsx(X, { size: 12 })
6342
+ })
6343
+ ]
6070
6344
  })
6071
6345
  })
6072
6346
  ]
@@ -6074,425 +6348,419 @@ function ConfigurationModalContent({ memory, windowBounds, poppedOut, floating,
6074
6348
  /* @__PURE__ */ jsxs("div", {
6075
6349
  ref: bodyRef,
6076
6350
  className: "studio-body",
6077
- children: [
6078
- /* @__PURE__ */ jsxs("main", {
6079
- ref: editorRef,
6080
- className: "studio-editor",
6081
- onScroll: (event_1) => memory.current.editorScroll = event_1.currentTarget.scrollTop,
6082
- children: [
6083
- layoutSection ? /* @__PURE__ */ jsxs("div", {
6084
- className: "studio-subtabs-bar",
6085
- children: [/* @__PURE__ */ jsx("div", {
6086
- className: "studio-subtabs",
6087
- role: "tablist",
6088
- "aria-label": "Layout tokens",
6089
- children: layoutKinds.map((kind_0) => /* @__PURE__ */ jsxs("button", {
6090
- type: "button",
6091
- role: "tab",
6092
- "aria-selected": kind_0 === section,
6093
- onClick: () => changeSection(kind_0),
6094
- children: [kind_0, Object.keys(draft.theme.theme).some((name_25) => layoutKindFor(name_25) === kind_0) && /* @__PURE__ */ jsx("span", {
6095
- className: "studio-group-changed",
6096
- "aria-label": "has changes"
6097
- })]
6098
- }, kind_0))
6099
- }), toggleAllButton]
6100
- }) : showTabs ? /* @__PURE__ */ jsxs("div", {
6101
- className: "studio-subtabs-bar",
6102
- children: [/* @__PURE__ */ jsx("div", {
6103
- className: "studio-subtabs",
6104
- role: "tablist",
6105
- "aria-label": `${section} tokens`,
6106
- children: sectionTabList.map((tab_0) => /* @__PURE__ */ jsxs("button", {
6107
- type: "button",
6108
- role: "tab",
6109
- "aria-selected": !searching && tab_0 === activeSectionTab,
6110
- disabled: searching,
6111
- onClick: () => setSectionTabs((current_12) => ({
6112
- ...current_12,
6113
- [section]: tab_0
6114
- })),
6115
- children: [tab_0, groupChanged([...groupedEntries].filter(([key_12]) => tabFor(key_12) === tab_0).flatMap(([, group_4]) => group_4.entries)) && /* @__PURE__ */ jsx("span", {
6351
+ children: [/* @__PURE__ */ jsxs("main", {
6352
+ ref: editorRef,
6353
+ className: "studio-editor",
6354
+ onScroll: (event_2) => memory.current.editorScroll = event_2.currentTarget.scrollTop,
6355
+ children: [
6356
+ layoutSection ? /* @__PURE__ */ jsxs("div", {
6357
+ className: "studio-subtabs-bar",
6358
+ children: [/* @__PURE__ */ jsx("div", {
6359
+ className: "studio-subtabs",
6360
+ role: "tablist",
6361
+ "aria-label": "Layout tokens",
6362
+ children: layoutKinds.map((kind_0) => /* @__PURE__ */ jsxs("button", {
6363
+ type: "button",
6364
+ role: "tab",
6365
+ "aria-selected": kind_0 === section,
6366
+ onClick: () => changeSection(kind_0),
6367
+ children: [kind_0, Object.keys(draft.theme.theme).some((name_27) => layoutKindFor(name_27) === kind_0) && /* @__PURE__ */ jsx("span", {
6368
+ className: "studio-group-changed",
6369
+ "aria-label": "has changes"
6370
+ })]
6371
+ }, kind_0))
6372
+ }), toggleAllButton]
6373
+ }) : showTabs ? /* @__PURE__ */ jsxs("div", {
6374
+ className: "studio-subtabs-bar",
6375
+ children: [/* @__PURE__ */ jsx("div", {
6376
+ className: "studio-subtabs",
6377
+ role: "tablist",
6378
+ "aria-label": `${section} tokens`,
6379
+ children: sectionTabList.map((tab_0) => /* @__PURE__ */ jsxs("button", {
6380
+ type: "button",
6381
+ role: "tab",
6382
+ "aria-selected": !searching && tab_0 === activeSectionTab,
6383
+ disabled: searching,
6384
+ onClick: () => setSectionTabs((current_12) => ({
6385
+ ...current_12,
6386
+ [section]: tab_0
6387
+ })),
6388
+ children: [tab_0, groupChanged([...groupedEntries].filter(([key_14]) => tabFor(key_14) === tab_0).flatMap(([, group_6]) => group_6.entries)) && /* @__PURE__ */ jsx("span", {
6389
+ className: "studio-group-changed",
6390
+ "aria-label": "has changes"
6391
+ })]
6392
+ }, tab_0))
6393
+ }), toggleAllButton]
6394
+ }) : advancedSection ? /* @__PURE__ */ jsx("div", {
6395
+ className: "studio-subtabs-bar",
6396
+ children: /* @__PURE__ */ jsx("div", {
6397
+ className: "studio-subtabs",
6398
+ role: "tablist",
6399
+ "aria-label": "Advanced settings",
6400
+ children: advancedSections.map(([key_15, label_0]) => /* @__PURE__ */ jsxs("button", {
6401
+ type: "button",
6402
+ role: "tab",
6403
+ "aria-selected": key_15 === section,
6404
+ onClick: () => changeSection(key_15),
6405
+ children: [label_0, (key_15 === "Components" ? Object.keys(draft.config).length > 0 : key_15 === "Variants & overrides" && Object.keys(draft.overrides ?? {}).length > 0) && /* @__PURE__ */ jsx("span", {
6406
+ className: "studio-group-changed",
6407
+ "aria-label": "has changes"
6408
+ })]
6409
+ }, key_15))
6410
+ })
6411
+ }) : /* @__PURE__ */ jsxs("div", {
6412
+ className: "studio-editor-heading",
6413
+ children: [/* @__PURE__ */ jsx("h2", { children: section }), toggleAllButton]
6414
+ }),
6415
+ isTokenSection(section) && /* @__PURE__ */ jsxs(Fragment$1, { children: [layoutSection && !searching && /* @__PURE__ */ jsx(LayoutScaleControl, {
6416
+ kind: layoutSection,
6417
+ level: layoutLevelFor(defaults, draft.theme.theme, layoutSection),
6418
+ onChange: (level_0) => setLayoutLevel(layoutSection, level_0)
6419
+ }, layoutSection), /* @__PURE__ */ jsxs("div", {
6420
+ className: `studio-token-list ${section !== "Typography" ? "studio-token-list-inline" : "studio-token-list-rows"}`,
6421
+ children: [orderedGroups.map(([key_16, group_7]) => group_7.compact && !flatTab ? renderTextStyleRow(key_16, group_7) : group_7.title && !flatTab ? /* @__PURE__ */ jsxs("fieldset", {
6422
+ className: `studio-token-group ${group_7.compact ? "studio-type-style" : ""} ${!isExpanded(key_16) ? "is-collapsed" : ""}`,
6423
+ children: [/* @__PURE__ */ jsxs("legend", { children: [/* @__PURE__ */ jsxs("button", {
6424
+ type: "button",
6425
+ className: "studio-group-toggle",
6426
+ "aria-expanded": isExpanded(key_16),
6427
+ "aria-controls": `group-${section}-${key_16.replaceAll(" ", "-")}`,
6428
+ onClick: () => toggleGroup(key_16),
6429
+ children: [
6430
+ /* @__PURE__ */ jsx(ChevronRight, {
6431
+ size: 14,
6432
+ "aria-hidden": "true"
6433
+ }),
6434
+ group_7.title,
6435
+ groupChanged(group_7.entries) && /* @__PURE__ */ jsx("span", {
6116
6436
  className: "studio-group-changed",
6117
6437
  "aria-label": "has changes"
6118
- })]
6119
- }, tab_0))
6120
- }), toggleAllButton]
6121
- }) : advancedSection ? /* @__PURE__ */ jsx("div", {
6122
- className: "studio-subtabs-bar",
6123
- children: /* @__PURE__ */ jsx("div", {
6124
- className: "studio-subtabs",
6125
- role: "tablist",
6126
- "aria-label": "Advanced settings",
6127
- children: advancedSections.map(([key_13, label_0]) => /* @__PURE__ */ jsxs("button", {
6438
+ })
6439
+ ]
6440
+ }), section === "Colors" && isPaletteGroup(group_7.entries) && /* @__PURE__ */ jsx("span", {
6441
+ className: "studio-palette-actions",
6442
+ children: /* @__PURE__ */ jsx("button", {
6128
6443
  type: "button",
6129
- role: "tab",
6130
- "aria-selected": key_13 === section,
6131
- onClick: () => changeSection(key_13),
6132
- children: [label_0, (key_13 === "Components" ? Object.keys(draft.config).length > 0 : key_13 === "Variants & overrides" && Object.keys(draft.overrides ?? {}).length > 0) && /* @__PURE__ */ jsx("span", {
6133
- className: "studio-group-changed",
6134
- "aria-label": "has changes"
6444
+ className: "studio-palette-reset",
6445
+ "aria-label": `Reset ${group_7.title} palette`,
6446
+ title: "Reset every shade in this palette to its default",
6447
+ disabled: !groupChanged(group_7.entries),
6448
+ onClick: () => {
6449
+ for (const [name_28] of group_7.entries) setToken(name_28);
6450
+ },
6451
+ children: /* @__PURE__ */ jsx(RotateCcw, {
6452
+ size: 13,
6453
+ "aria-hidden": "true"
6454
+ })
6455
+ })
6456
+ })] }), /* @__PURE__ */ jsxs("div", {
6457
+ id: `group-${section}-${key_16.replaceAll(" ", "-")}`,
6458
+ hidden: !isExpanded(key_16),
6459
+ className: group_7.compact ? "studio-type-fields" : void 0,
6460
+ children: [section === "Colors" && isPaletteGroup(group_7.entries) && renderPaletteShades(group_7.title, group_7.entries), group_7.entries.map((entry_4) => renderToken(entry_4, group_7.compact))]
6461
+ })]
6462
+ }, key_16) : section === "Typography" && key_16 === "Font families" ? renderFontFamilies(group_7.entries) : group_7.entries.map((entry_5) => renderToken(entry_5))), !orderedGroups.length && /* @__PURE__ */ jsx("p", { children: "No matching tokens. Try a component name such as “button”." })]
6463
+ })] }),
6464
+ section === "Variants & overrides" && /* @__PURE__ */ jsx(CvaEditor, {
6465
+ slot: cvaSlot,
6466
+ setSlot: (slot) => {
6467
+ setCvaSlot(slot);
6468
+ setCvaVariants({});
6469
+ },
6470
+ onPreview: setCvaVariants
6471
+ }),
6472
+ section === "Presets" && /* @__PURE__ */ jsxs("div", {
6473
+ className: "studio-presets",
6474
+ children: [/* @__PURE__ */ jsx("p", {
6475
+ className: "studio-presets-intro",
6476
+ children: "A preset replaces your theme edits with its own. Component defaults and overrides stay as they are; Changes stay in this session. Save theme writes CSS settings to the repository."
6477
+ }), [appThemePreset, ...themePresets].map((preset_0) => {
6478
+ const active = isPresetActive(preset_0, defaults, draft.theme);
6479
+ const colors = presetEdits(preset_0, defaults).light;
6480
+ const swatch = (name_29) => `rgb(${colors[name_29] ?? defaults.light[name_29]})`;
6481
+ return /* @__PURE__ */ jsxs("div", {
6482
+ className: `studio-preset ${active ? "is-active" : ""}`,
6483
+ children: [
6484
+ /* @__PURE__ */ jsx("span", {
6485
+ className: "studio-preset-swatches",
6486
+ "aria-hidden": "true",
6487
+ children: [
6488
+ 50,
6489
+ 200,
6490
+ 500,
6491
+ 900,
6492
+ 950
6493
+ ].map((step) => /* @__PURE__ */ jsx("i", { style: { background: swatch(`--neutral-${step}-base`) } }, step))
6494
+ }),
6495
+ /* @__PURE__ */ jsxs("span", {
6496
+ className: "studio-preset-text",
6497
+ children: [/* @__PURE__ */ jsx("strong", { children: preset_0.label }), /* @__PURE__ */ jsx("span", { children: preset_0.description })]
6498
+ }),
6499
+ /* @__PURE__ */ jsx("button", {
6500
+ type: "button",
6501
+ className: active ? void 0 : "studio-primary",
6502
+ disabled: active,
6503
+ onClick: () => applyPreset(preset_0),
6504
+ children: active ? "Active" : "Apply preset"
6505
+ })
6506
+ ]
6507
+ }, preset_0.id);
6508
+ })]
6509
+ }),
6510
+ section === "Components" && /* @__PURE__ */ jsxs("div", {
6511
+ className: "studio-settings",
6512
+ children: [
6513
+ /* @__PURE__ */ jsx("h3", { children: "Editor" }),
6514
+ /* @__PURE__ */ jsxs("label", {
6515
+ className: "studio-setting",
6516
+ children: [/* @__PURE__ */ jsx("span", { children: "Size units" }), /* @__PURE__ */ jsxs("select", {
6517
+ "aria-label": "Size units",
6518
+ value: sizeUnit,
6519
+ onChange: (event_3) => setSizeUnit(event_3.target.value),
6520
+ children: [/* @__PURE__ */ jsx("option", {
6521
+ value: "px",
6522
+ children: "px"
6523
+ }), /* @__PURE__ */ jsx("option", {
6524
+ value: "rem",
6525
+ children: "rem"
6135
6526
  })]
6136
- }, key_13))
6527
+ })]
6528
+ }),
6529
+ /* @__PURE__ */ jsx("h3", { children: "Buttons" }),
6530
+ selectControl("Appearance", "button", "variant", [
6531
+ "contained",
6532
+ "outlined",
6533
+ "subtle",
6534
+ "ghost",
6535
+ "text"
6536
+ ]),
6537
+ selectControl("Button size", "button", "size", [
6538
+ "default",
6539
+ "sm",
6540
+ "s"
6541
+ ]),
6542
+ /* @__PURE__ */ jsx("h3", { children: "Inputs" }),
6543
+ selectControl("Input appearance", "input", "variant", ["outlined", "filled"]),
6544
+ selectControl("Label layout", "input", "as", [
6545
+ "default",
6546
+ "floating",
6547
+ "inline",
6548
+ "filter"
6549
+ ]),
6550
+ selectControl("Input size", "input", "size", ["default", "small"]),
6551
+ [
6552
+ "isClearable",
6553
+ "hideLabel",
6554
+ "alwaysShowClear"
6555
+ ].map((field_2) => /* @__PURE__ */ jsxs("label", {
6556
+ className: "studio-setting",
6557
+ children: [/* @__PURE__ */ jsx("span", { children: {
6558
+ isClearable: "Allow clearing",
6559
+ hideLabel: "Hide labels",
6560
+ alwaysShowClear: "Always show clear button"
6561
+ }[field_2] }), /* @__PURE__ */ jsx("input", {
6562
+ type: "checkbox",
6563
+ checked: config.input[field_2],
6564
+ onChange: (event_4) => setComponent("input", field_2, event_4.target.checked)
6565
+ })]
6566
+ }, field_2)),
6567
+ /* @__PURE__ */ jsx("h3", { children: "Rendering" }),
6568
+ /* @__PURE__ */ jsxs("label", {
6569
+ className: "studio-setting",
6570
+ children: [/* @__PURE__ */ jsxs("span", { children: ["Use static inputs until interaction", /* @__PURE__ */ jsx("small", { children: "Reduce work when rendering large forms." })] }), /* @__PURE__ */ jsx("input", {
6571
+ type: "checkbox",
6572
+ checked: config.renderStaticInput,
6573
+ onChange: (event_5) => setDraft((current_13) => ({
6574
+ ...current_13,
6575
+ config: {
6576
+ ...current_13.config,
6577
+ renderStaticInput: event_5.target.checked
6578
+ }
6579
+ }))
6580
+ })]
6581
+ }),
6582
+ /* @__PURE__ */ jsx("p", {
6583
+ className: "studio-help",
6584
+ children: "Component props override these defaults. The preview uses inherited defaults unless an example needs a specific state."
6137
6585
  })
6138
- }) : /* @__PURE__ */ jsxs("div", {
6139
- className: "studio-editor-heading",
6140
- children: [/* @__PURE__ */ jsx("h2", { children: section }), toggleAllButton]
6141
- }),
6142
- isTokenSection(section) && /* @__PURE__ */ jsxs(Fragment$1, { children: [layoutSection && !searching && /* @__PURE__ */ jsx(LayoutScaleControl, {
6143
- kind: layoutSection,
6144
- level: layoutLevelFor(defaults, draft.theme.theme, layoutSection),
6145
- onChange: (level_0) => setLayoutLevel(layoutSection, level_0)
6146
- }, layoutSection), /* @__PURE__ */ jsxs("div", {
6147
- className: `studio-token-list ${section !== "Typography" ? "studio-token-list-inline" : "studio-token-list-rows"}`,
6148
- children: [orderedGroups.map(([key_14, group_5]) => group_5.title && !flatTab ? /* @__PURE__ */ jsxs("fieldset", {
6149
- className: `studio-token-group ${group_5.compact ? "studio-type-style" : ""} ${!isExpanded(key_14) ? "is-collapsed" : ""}`,
6150
- children: [/* @__PURE__ */ jsxs("legend", { children: [/* @__PURE__ */ jsxs("button", {
6151
- type: "button",
6152
- className: "studio-group-toggle",
6153
- "aria-expanded": isExpanded(key_14),
6154
- "aria-controls": `group-${section}-${key_14.replaceAll(" ", "-")}`,
6155
- onClick: () => toggleGroup(key_14),
6156
- children: [
6157
- /* @__PURE__ */ jsx(ChevronRight, {
6158
- size: 14,
6159
- "aria-hidden": "true"
6160
- }),
6161
- group_5.title,
6162
- groupChanged(group_5.entries) && /* @__PURE__ */ jsx("span", {
6163
- className: "studio-group-changed",
6164
- "aria-label": "has changes"
6165
- })
6166
- ]
6167
- }), section === "Colors" && isPaletteGroup(group_5.entries) && /* @__PURE__ */ jsx("span", {
6168
- className: "studio-palette-actions",
6169
- children: /* @__PURE__ */ jsx("button", {
6170
- type: "button",
6171
- className: "studio-palette-reset",
6172
- "aria-label": `Reset ${group_5.title} palette`,
6173
- title: "Reset every shade in this palette to its default",
6174
- disabled: !groupChanged(group_5.entries),
6586
+ ]
6587
+ }),
6588
+ section === "Export" && /* @__PURE__ */ jsxs("div", {
6589
+ className: "studio-export",
6590
+ children: [
6591
+ /* @__PURE__ */ jsxs("div", {
6592
+ className: "studio-mode",
6593
+ children: [
6594
+ /* @__PURE__ */ jsx("button", {
6595
+ "aria-pressed": exportTab === "css",
6596
+ onClick: () => setExportTab("css"),
6597
+ children: "Tailwind CSS"
6598
+ }),
6599
+ /* @__PURE__ */ jsx("button", {
6600
+ "aria-pressed": exportTab === "config",
6601
+ onClick: () => setExportTab("config"),
6602
+ children: "UIConfig"
6603
+ }),
6604
+ /* @__PURE__ */ jsx("button", {
6605
+ "aria-pressed": exportTab === "overrides",
6606
+ onClick: () => setExportTab("overrides"),
6607
+ children: "UIOverrides"
6608
+ })
6609
+ ]
6610
+ }),
6611
+ /* @__PURE__ */ jsx("p", { children: exportTab === "css" ? "Import after your existing theme. Only changed tokens are included; light and dark colors remain separate." : exportTab === "overrides" ? "Merge these edited slots with your existing app overrides. New Tailwind classes require a rebuild." : "Wrap your application with this provider. Only changed component settings are included." }),
6612
+ /* @__PURE__ */ jsx("textarea", {
6613
+ ref: exportRef,
6614
+ "aria-label": "Exported configuration",
6615
+ readOnly: true,
6616
+ value: exportText,
6617
+ spellCheck: false
6618
+ }),
6619
+ /* @__PURE__ */ jsxs("div", {
6620
+ className: "studio-export-actions",
6621
+ children: [
6622
+ exportTab === "css" && themeWriter && /* @__PURE__ */ jsx("button", {
6623
+ disabled: savingTheme || !!Object.keys(invalidFields).length,
6624
+ title: `Save to ${themeWriter.file}`,
6625
+ onClick: async () => {
6626
+ setSavingTheme(true);
6627
+ setMessage("");
6628
+ try {
6629
+ await saveThemeCss(themeWriter, exportText);
6630
+ setMessage(`Saved theme to ${themeWriter.file}.`);
6631
+ } catch (error) {
6632
+ setMessage(error instanceof Error ? error.message : "Could not save theme.");
6633
+ } finally {
6634
+ setSavingTheme(false);
6635
+ }
6636
+ },
6637
+ children: savingTheme ? "Saving theme…" : "Save theme"
6638
+ }),
6639
+ /* @__PURE__ */ jsx("button", {
6640
+ disabled: !!Object.keys(invalidFields).length,
6641
+ onClick: async () => {
6642
+ try {
6643
+ await navigator.clipboard.writeText(exportText);
6644
+ setMessage("Copied to clipboard.");
6645
+ } catch {
6646
+ exportRef.current?.select();
6647
+ setMessage("Clipboard unavailable. The export is selected for manual copying.");
6648
+ }
6649
+ },
6650
+ children: "Copy code"
6651
+ }),
6652
+ /* @__PURE__ */ jsxs("button", {
6653
+ disabled: !!Object.keys(invalidFields).length,
6175
6654
  onClick: () => {
6176
- for (const [name_26] of group_5.entries) setToken(name_26);
6655
+ const url = URL.createObjectURL(new Blob([exportText], { type: "text/plain" }));
6656
+ const link = document.createElement("a");
6657
+ link.href = url;
6658
+ link.download = exportTab === "css" ? "povio-theme.css" : exportTab === "overrides" ? "povio-ui-overrides.ts" : "povio-ui-config.ts";
6659
+ link.click();
6660
+ setTimeout(() => URL.revokeObjectURL(url), 1e3);
6661
+ setMessage("Export downloaded.");
6177
6662
  },
6178
- children: /* @__PURE__ */ jsx(RotateCcw, {
6179
- size: 13,
6180
- "aria-hidden": "true"
6181
- })
6663
+ children: [/* @__PURE__ */ jsx(ArrowDownToLine, { size: 14 }), " Download"]
6182
6664
  })
6183
- })] }), /* @__PURE__ */ jsxs("div", {
6184
- id: `group-${section}-${key_14.replaceAll(" ", "-")}`,
6185
- hidden: !isExpanded(key_14),
6186
- className: group_5.compact ? "studio-type-fields" : void 0,
6187
- children: [section === "Colors" && isPaletteGroup(group_5.entries) && renderPaletteShades(group_5.title, group_5.entries), group_5.entries.map((entry_3) => renderToken(entry_3, group_5.compact))]
6188
- })]
6189
- }, key_14) : section === "Typography" && key_14 === "Font families" ? renderFontFamilies(group_5.entries) : group_5.entries.map((entry_4) => renderToken(entry_4))), !orderedGroups.length && /* @__PURE__ */ jsx("p", { children: "No matching tokens. Try a component name such as “button”." })]
6190
- })] }),
6191
- section === "Variants & overrides" && /* @__PURE__ */ jsx(CvaEditor, {
6192
- slot: cvaSlot,
6193
- setSlot: (slot) => {
6194
- setCvaSlot(slot);
6195
- setCvaVariants({});
6196
- },
6197
- onPreview: setCvaVariants
6198
- }),
6199
- section === "Presets" && /* @__PURE__ */ jsxs("div", {
6200
- className: "studio-presets",
6201
- children: [/* @__PURE__ */ jsx("p", {
6202
- className: "studio-presets-intro",
6203
- children: "A preset replaces your theme edits with its own. Component defaults and overrides stay as they are; Apply or Save theme keeps it, Cancel discards it."
6204
- }), [appThemePreset, ...themePresets].map((preset_0) => {
6205
- const active = isPresetActive(preset_0, defaults, draft.theme);
6206
- const colors = presetEdits(preset_0, defaults).light;
6207
- const swatch = (name_27) => `rgb(${colors[name_27] ?? defaults.light[name_27]})`;
6208
- return /* @__PURE__ */ jsxs("div", {
6209
- className: `studio-preset ${active ? "is-active" : ""}`,
6210
- children: [
6211
- /* @__PURE__ */ jsx("span", {
6212
- className: "studio-preset-swatches",
6213
- "aria-hidden": "true",
6214
- children: [
6215
- 50,
6216
- 200,
6217
- 500,
6218
- 900,
6219
- 950
6220
- ].map((step) => /* @__PURE__ */ jsx("i", { style: { background: swatch(`--neutral-${step}-base`) } }, step))
6221
- }),
6222
- /* @__PURE__ */ jsxs("span", {
6223
- className: "studio-preset-text",
6224
- children: [/* @__PURE__ */ jsx("strong", { children: preset_0.label }), /* @__PURE__ */ jsx("span", { children: preset_0.description })]
6225
- }),
6226
- /* @__PURE__ */ jsx("button", {
6227
- type: "button",
6228
- className: active ? void 0 : "studio-primary",
6229
- disabled: active,
6230
- onClick: () => applyPreset(preset_0),
6231
- children: active ? "Active" : "Apply preset"
6232
- })
6233
- ]
6234
- }, preset_0.id);
6235
- })]
6236
- }),
6237
- section === "Components" && /* @__PURE__ */ jsxs("div", {
6238
- className: "studio-settings",
6239
- children: [
6240
- /* @__PURE__ */ jsx("h3", { children: "Editor" }),
6241
- /* @__PURE__ */ jsxs("label", {
6242
- className: "studio-setting",
6243
- children: [/* @__PURE__ */ jsx("span", { children: "Size units" }), /* @__PURE__ */ jsxs("select", {
6244
- "aria-label": "Size units",
6245
- value: sizeUnit,
6246
- onChange: (event_2) => setSizeUnit(event_2.target.value),
6247
- children: [/* @__PURE__ */ jsx("option", {
6248
- value: "px",
6249
- children: "px"
6250
- }), /* @__PURE__ */ jsx("option", {
6251
- value: "rem",
6252
- children: "rem"
6253
- })]
6254
- })]
6255
- }),
6256
- /* @__PURE__ */ jsx("h3", { children: "Buttons" }),
6257
- selectControl("Appearance", "button", "variant", [
6258
- "contained",
6259
- "outlined",
6260
- "subtle",
6261
- "ghost",
6262
- "text"
6263
- ]),
6264
- selectControl("Button size", "button", "size", [
6265
- "default",
6266
- "sm",
6267
- "s"
6268
- ]),
6269
- /* @__PURE__ */ jsx("h3", { children: "Inputs" }),
6270
- selectControl("Input appearance", "input", "variant", ["outlined", "filled"]),
6271
- selectControl("Label layout", "input", "as", [
6272
- "default",
6273
- "floating",
6274
- "inline",
6275
- "filter"
6276
- ]),
6277
- selectControl("Input size", "input", "size", ["default", "small"]),
6278
- [
6279
- "isClearable",
6280
- "hideLabel",
6281
- "alwaysShowClear"
6282
- ].map((field_2) => /* @__PURE__ */ jsxs("label", {
6283
- className: "studio-setting",
6284
- children: [/* @__PURE__ */ jsx("span", { children: {
6285
- isClearable: "Allow clearing",
6286
- hideLabel: "Hide labels",
6287
- alwaysShowClear: "Always show clear button"
6288
- }[field_2] }), /* @__PURE__ */ jsx("input", {
6289
- type: "checkbox",
6290
- checked: config.input[field_2],
6291
- onChange: (event_3) => setComponent("input", field_2, event_3.target.checked)
6292
- })]
6293
- }, field_2)),
6294
- /* @__PURE__ */ jsx("h3", { children: "Rendering" }),
6295
- /* @__PURE__ */ jsxs("label", {
6296
- className: "studio-setting",
6297
- children: [/* @__PURE__ */ jsxs("span", { children: ["Use static inputs until interaction", /* @__PURE__ */ jsx("small", { children: "Reduce work when rendering large forms." })] }), /* @__PURE__ */ jsx("input", {
6298
- type: "checkbox",
6299
- checked: config.renderStaticInput,
6300
- onChange: (event_4) => setDraft((current_13) => ({
6301
- ...current_13,
6302
- config: {
6303
- ...current_13.config,
6304
- renderStaticInput: event_4.target.checked
6305
- }
6306
- }))
6307
- })]
6308
- }),
6309
- /* @__PURE__ */ jsx("p", {
6310
- className: "studio-help",
6311
- children: "Component props override these defaults. The preview uses inherited defaults unless an example needs a specific state."
6312
- })
6313
- ]
6314
- }),
6315
- section === "Export" && /* @__PURE__ */ jsxs("div", {
6316
- className: "studio-export",
6317
- children: [
6318
- /* @__PURE__ */ jsxs("div", {
6319
- className: "studio-mode",
6320
- children: [
6321
- /* @__PURE__ */ jsx("button", {
6322
- "aria-pressed": exportTab === "css",
6323
- onClick: () => setExportTab("css"),
6324
- children: "Tailwind CSS"
6325
- }),
6326
- /* @__PURE__ */ jsx("button", {
6327
- "aria-pressed": exportTab === "config",
6328
- onClick: () => setExportTab("config"),
6329
- children: "UIConfig"
6330
- }),
6331
- /* @__PURE__ */ jsx("button", {
6332
- "aria-pressed": exportTab === "overrides",
6333
- onClick: () => setExportTab("overrides"),
6334
- children: "UIOverrides"
6335
- })
6336
- ]
6337
- }),
6338
- /* @__PURE__ */ jsx("p", { children: exportTab === "css" ? "Import after your existing theme. Only changed tokens are included; light and dark colors remain separate." : exportTab === "overrides" ? "Merge these edited slots with your existing app overrides. New Tailwind classes require a rebuild." : "Wrap your application with this provider. Only changed component settings are included." }),
6339
- /* @__PURE__ */ jsx("textarea", {
6340
- ref: exportRef,
6341
- "aria-label": "Exported configuration",
6342
- readOnly: true,
6343
- value: exportText,
6344
- spellCheck: false
6345
- }),
6346
- /* @__PURE__ */ jsxs("div", {
6347
- className: "studio-export-actions",
6348
- children: [
6349
- exportTab === "css" && themeWriter && /* @__PURE__ */ jsx("button", {
6350
- disabled: savingTheme || !!Object.keys(invalidFields).length,
6351
- title: `Save to ${themeWriter.file}`,
6352
- onClick: async () => {
6353
- setSavingTheme(true);
6354
- setMessage("");
6355
- try {
6356
- await saveThemeCss(themeWriter, exportText);
6357
- setMessage(`Saved theme to ${themeWriter.file}.`);
6358
- } catch (error) {
6359
- setMessage(error instanceof Error ? error.message : "Could not save theme.");
6360
- } finally {
6361
- setSavingTheme(false);
6362
- }
6363
- },
6364
- children: savingTheme ? "Saving theme…" : "Save theme"
6365
- }),
6366
- /* @__PURE__ */ jsx("button", {
6367
- disabled: !!Object.keys(invalidFields).length,
6368
- onClick: async () => {
6369
- try {
6370
- await navigator.clipboard.writeText(exportText);
6371
- setMessage("Copied to clipboard.");
6372
- } catch {
6373
- exportRef.current?.select();
6374
- setMessage("Clipboard unavailable. The export is selected for manual copying.");
6375
- }
6376
- },
6377
- children: "Copy code"
6378
- }),
6379
- /* @__PURE__ */ jsxs("button", {
6380
- disabled: !!Object.keys(invalidFields).length,
6381
- onClick: () => {
6382
- const url = URL.createObjectURL(new Blob([exportText], { type: "text/plain" }));
6383
- const link = document.createElement("a");
6384
- link.href = url;
6385
- link.download = exportTab === "css" ? "povio-theme.css" : exportTab === "overrides" ? "povio-ui-overrides.ts" : "povio-ui-config.ts";
6386
- link.click();
6387
- setTimeout(() => URL.revokeObjectURL(url), 1e3);
6388
- setMessage("Export downloaded.");
6389
- },
6390
- children: [/* @__PURE__ */ jsx(ArrowDownToLine, { size: 14 }), " Download"]
6391
- })
6392
- ]
6393
- })
6394
- ]
6395
- })
6396
- ]
6397
- }),
6398
- /* @__PURE__ */ jsxs("aside", {
6399
- ref: previewRef,
6400
- className: "studio-preview",
6401
- onScroll: (event_5) => memory.current.previewScroll = event_5.currentTarget.scrollTop,
6402
- children: [
6403
- /* @__PURE__ */ jsxs("div", {
6404
- className: "studio-preview-heading",
6405
- children: [/* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsx("i", {}), " LIVE PREVIEW"] }), /* @__PURE__ */ jsxs("div", {
6406
- className: "studio-preview-actions",
6407
- children: [/* @__PURE__ */ jsx(ColorModeSwitch, {
6408
- value: mode,
6409
- onChange: setMode
6410
- }), isTokenSection(section) && /* @__PURE__ */ jsxs("div", {
6411
- className: "studio-mode studio-preview-modes",
6412
- role: "group",
6413
- "aria-label": "Preview mode",
6414
- children: [/* @__PURE__ */ jsx("button", {
6415
- type: "button",
6416
- "aria-pressed": previewMode === "gallery",
6417
- onClick: () => setPreviewMode("gallery"),
6418
- children: "Gallery"
6419
- }), /* @__PURE__ */ jsx("button", {
6420
- type: "button",
6421
- "aria-pressed": previewMode === "focused",
6422
- onClick: () => setPreviewMode("focused"),
6423
- children: "Token preview"
6424
- })]
6665
+ ]
6666
+ })
6667
+ ]
6668
+ })
6669
+ ]
6670
+ }), !componentsHosted && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("aside", {
6671
+ ref: previewRef,
6672
+ className: "studio-preview",
6673
+ onScroll: (event_6) => memory.current.previewScroll = event_6.currentTarget.scrollTop,
6674
+ children: [
6675
+ /* @__PURE__ */ jsxs("div", {
6676
+ className: "studio-preview-heading",
6677
+ children: [/* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsx("i", {}), " COMPONENTS"] }), /* @__PURE__ */ jsxs("div", {
6678
+ className: "studio-preview-actions",
6679
+ children: [/* @__PURE__ */ jsx(ColorModeSwitch, {
6680
+ value: mode,
6681
+ onChange: setMode
6682
+ }), isTokenSection(section) && /* @__PURE__ */ jsxs("div", {
6683
+ className: "studio-mode studio-preview-modes",
6684
+ role: "group",
6685
+ "aria-label": "Preview mode",
6686
+ children: [/* @__PURE__ */ jsx("button", {
6687
+ type: "button",
6688
+ "aria-pressed": previewMode === "gallery",
6689
+ onClick: () => setPreviewMode("gallery"),
6690
+ children: "Gallery"
6691
+ }), /* @__PURE__ */ jsx("button", {
6692
+ type: "button",
6693
+ "aria-pressed": previewMode === "focused",
6694
+ onClick: () => setPreviewMode("focused"),
6695
+ children: "Token preview"
6425
6696
  })]
6426
6697
  })]
6427
- }),
6428
- /* @__PURE__ */ jsx(PreviewInspector, {
6429
- revision: draft,
6430
- isKnown: isInspectable,
6431
- onSelect: focusToken,
6432
- onScroll: (scrollTop) => {
6433
- memory.current.previewScroll = scrollTop;
6434
- },
6435
- children: section === "Variants & overrides" || isTokenSection(section) && previewMode === "focused" ? /* @__PURE__ */ jsx(ContextualPreview, {
6436
- variants: cvaVariants,
6437
- setVariants: setCvaVariants,
6438
- section,
6439
- slot: cvaSlot,
6440
- mode,
6441
- entries: visibleGroups.flatMap(([, group_6]) => group_6.entries)
6442
- }) : /* @__PURE__ */ jsx(ComponentPreview, {
6443
- value: draft,
6444
- mode,
6445
- inspector: {
6446
- isKnown: isInspectable,
6447
- describe: describeToken,
6448
- onSelect: focusToken,
6449
- revision: draft
6450
- }
6451
- })
6452
- }),
6453
- /* @__PURE__ */ jsx("p", {
6454
- className: "studio-preview-note",
6455
- children: section === "Variants & overrides" || previewMode === "focused" ? "Preview follows the current section. Variant controls affect only the preview." : "Click to pin or unpin an element. Use Interact to try components."
6698
+ })]
6699
+ }),
6700
+ /* @__PURE__ */ jsx(PreviewInspector, {
6701
+ revision: draft,
6702
+ isKnown: isInspectable,
6703
+ onSelect: focusToken,
6704
+ onScroll: (scrollTop) => {
6705
+ memory.current.previewScroll = scrollTop;
6706
+ },
6707
+ children: section === "Variants & overrides" || isTokenSection(section) && previewMode === "focused" ? /* @__PURE__ */ jsx(ContextualPreview, {
6708
+ variants: cvaVariants,
6709
+ setVariants: setCvaVariants,
6710
+ section,
6711
+ slot: cvaSlot,
6712
+ mode,
6713
+ entries: visibleGroups.flatMap(([, group_8]) => group_8.entries)
6714
+ }) : /* @__PURE__ */ jsx(ComponentPreview, {
6715
+ value: draft,
6716
+ mode,
6717
+ inspector: {
6718
+ isKnown: isInspectable,
6719
+ describe: describeToken,
6720
+ onSelect: focusToken,
6721
+ revision: draft
6722
+ }
6456
6723
  })
6457
- ]
6458
- }),
6459
- /* @__PURE__ */ jsx(PanelResizeHandle, {
6460
- label: "Resize editor and preview",
6461
- column: 2,
6462
- width: editorWidth,
6463
- min: 260,
6464
- max: () => (bodyRef.current?.parentElement?.clientWidth ?? 0) - 320,
6465
- onResize: setEditorWidth,
6466
- onReset: () => setEditorWidth(void 0)
6467
- })
6468
- ]
6724
+ }),
6725
+ /* @__PURE__ */ jsx("p", {
6726
+ className: "studio-preview-note",
6727
+ children: section === "Variants & overrides" || previewMode === "focused" ? "Preview follows the current section. Variant controls affect only the preview." : "Click to pin or unpin an element. Use Interact to try components."
6728
+ })
6729
+ ]
6730
+ }), /* @__PURE__ */ jsx(PanelResizeHandle, {
6731
+ label: "Resize editor and preview",
6732
+ column: 2,
6733
+ width: editorWidth,
6734
+ min: 260,
6735
+ max: () => (bodyRef.current?.parentElement?.clientWidth ?? 0) - 320,
6736
+ onResize: setEditorWidth,
6737
+ onReset: () => setEditorWidth(void 0)
6738
+ })] })]
6469
6739
  }),
6470
6740
  /* @__PURE__ */ jsxs("footer", {
6471
6741
  className: "studio-footer",
6472
6742
  children: [
6473
- /* @__PURE__ */ jsxs("button", {
6743
+ /* @__PURE__ */ jsx("button", {
6744
+ className: "studio-footer-reset",
6745
+ "aria-label": "Reset all",
6746
+ title: "Reset all",
6474
6747
  onClick: () => {
6475
6748
  const hasChanges = !!changedCount || !!Object.keys(invalidFields).length;
6476
6749
  setNothingToReset(!hasChanges);
6477
6750
  setConfirmingReset(hasChanges);
6478
6751
  },
6479
- children: [/* @__PURE__ */ jsx(RotateCcw, { size: 14 }), " Reset all"]
6752
+ children: /* @__PURE__ */ jsx(RotateCcw, { size: 14 })
6480
6753
  }),
6481
6754
  /* @__PURE__ */ jsx("span", {
6482
6755
  role: "status",
6483
- children: Object.keys(invalidFields).length ? "Fix invalid values or reset before applying or exporting." : nothingToReset && !changedCount ? "No active changes to reset." : (popupBlocked ? "Allow pop-ups for this site, then try again." : message) || `${changedCount} overrides · Changes stay in this session`
6756
+ title: footerStatus === overrideCount ? `${overrideCount} · Changes stay in this session` : footerStatus,
6757
+ children: footerStatus
6484
6758
  }),
6485
6759
  /* @__PURE__ */ jsx("button", {
6486
- onClick: () => cancel(),
6487
- children: "Cancel"
6488
- }),
6489
- /* @__PURE__ */ jsxs("button", {
6490
6760
  className: "studio-primary",
6491
- disabled: !!Object.keys(invalidFields).length,
6492
- onClick: () => {
6493
- apply();
6494
- },
6495
- children: [/* @__PURE__ */ jsx(Check, { size: 15 }), " Apply settings"]
6761
+ "aria-label": "Close UI configuration",
6762
+ onClick: apply,
6763
+ children: "Close"
6496
6764
  })
6497
6765
  ]
6498
6766
  }),
@@ -6570,135 +6838,69 @@ function ConfigurationModalContent({ memory, windowBounds, poppedOut, floating,
6570
6838
  })
6571
6839
  });
6572
6840
  }
6841
+ /** Where a floating configurator first opens; an editor-only window (components shown by the host) is narrower. */
6842
+ const floatingDefault = {
6843
+ left: 32,
6844
+ top: 80,
6845
+ width: 640,
6846
+ height: 720
6847
+ };
6848
+ const hostedFloatingWidth = 360;
6573
6849
  function UIConfigurationModal() {
6574
- const $ = c(28);
6575
- const { isOpen, revision, open, openFloating, floating } = useUIConfiguration();
6850
+ const { isOpen, revision, open, openFloating, floating, componentsHosted } = useUIConfiguration();
6576
6851
  const [minimized, setMinimized] = useState(false);
6577
6852
  const [hasLauncher, setHasLauncher] = useState(false);
6578
6853
  const restorePopout = useRef(false);
6579
6854
  const launcherPosition = useRef(null);
6580
- let t0;
6581
- if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
6582
- t0 = () => setMinimized(false);
6583
- $[0] = t0;
6584
- } else t0 = $[0];
6585
- let t1;
6586
- if ($[1] !== revision) {
6587
- t1 = [revision];
6588
- $[1] = revision;
6589
- $[2] = t1;
6590
- } else t1 = $[2];
6591
- useEffect(t0, t1);
6592
- let t2;
6593
- if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
6594
- t2 = {};
6595
- $[3] = t2;
6596
- } else t2 = $[3];
6597
- const memory = useRef(t2);
6855
+ useEffect(() => setMinimized(false), [revision]);
6856
+ const memory = useRef({});
6598
6857
  const windowBounds = useRef(null);
6599
- let t3;
6600
- if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
6601
- t3 = {
6602
- left: 32,
6603
- top: 80,
6604
- width: 640,
6605
- height: 720
6606
- };
6607
- $[4] = t3;
6608
- } else t3 = $[4];
6609
- const floatingBounds = useRef(t3);
6858
+ const floatingBounds = useRef(floatingDefault);
6859
+ if (componentsHosted && floatingBounds.current === floatingDefault) floatingBounds.current = {
6860
+ ...floatingDefault,
6861
+ width: hostedFloatingWidth
6862
+ };
6610
6863
  const popout = useStudioPopout(isOpen && !minimized);
6611
- if ((!isOpen || minimized) && hasLauncher) {
6612
- let t4;
6613
- if ($[5] !== floating || $[6] !== isOpen || $[7] !== open || $[8] !== openFloating || $[9] !== popout) {
6614
- t4 = createPortal(/* @__PURE__ */ jsx(ConfigurationLauncher, {
6615
- position: launcherPosition,
6616
- onOpen: () => {
6617
- setMinimized(false);
6618
- if (!isOpen) {
6619
- if (floating) openFloating();
6620
- else open();
6621
- }
6622
- if (restorePopout.current) popout.open();
6623
- }
6624
- }), document.body);
6625
- $[5] = floating;
6626
- $[6] = isOpen;
6627
- $[7] = open;
6628
- $[8] = openFloating;
6629
- $[9] = popout;
6630
- $[10] = t4;
6631
- } else t4 = $[10];
6632
- return t4;
6633
- }
6634
- if (!isOpen) return null;
6635
- const t4 = floating ? floatingBounds : windowBounds;
6636
- const t5 = !!popout.popup;
6637
- let t6;
6638
- let t7;
6639
- let t8;
6640
- if ($[11] !== popout) {
6641
- t6 = () => {
6864
+ if ((!isOpen || minimized) && hasLauncher && !componentsHosted) return createPortal(/* @__PURE__ */ jsx(ConfigurationLauncher, {
6865
+ position: launcherPosition,
6866
+ onOpen: () => {
6867
+ setMinimized(false);
6868
+ if (!isOpen) {
6869
+ if (floating) openFloating();
6870
+ else open();
6871
+ }
6872
+ if (restorePopout.current) popout.open();
6873
+ }
6874
+ }), document.body);
6875
+ if (!isOpen || minimized) return null;
6876
+ const content = /* @__PURE__ */ jsx(ConfigurationModalContent, {
6877
+ memory,
6878
+ windowBounds: floating ? floatingBounds : windowBounds,
6879
+ floating,
6880
+ poppedOut: !!popout.popup,
6881
+ onPopout: () => {
6642
6882
  restorePopout.current = true;
6643
6883
  popout.open();
6644
- };
6645
- t7 = () => {
6884
+ },
6885
+ onDock: () => {
6646
6886
  restorePopout.current = false;
6647
6887
  popout.dock();
6648
- };
6649
- t8 = () => {
6888
+ },
6889
+ onMinimize: () => {
6650
6890
  restorePopout.current = !!popout.popup;
6651
6891
  setHasLauncher(true);
6652
6892
  setMinimized(true);
6653
6893
  popout.dock();
6654
- };
6655
- $[11] = popout;
6656
- $[12] = t6;
6657
- $[13] = t7;
6658
- $[14] = t8;
6659
- } else {
6660
- t6 = $[12];
6661
- t7 = $[13];
6662
- t8 = $[14];
6663
- }
6664
- let t9;
6665
- if ($[15] !== floating || $[16] !== popout.blocked || $[17] !== revision || $[18] !== t4 || $[19] !== t5 || $[20] !== t6 || $[21] !== t7 || $[22] !== t8) {
6666
- t9 = /* @__PURE__ */ jsx(ConfigurationModalContent, {
6667
- memory,
6668
- windowBounds: t4,
6669
- floating,
6670
- poppedOut: t5,
6671
- onPopout: t6,
6672
- onDock: t7,
6673
- onMinimize: t8,
6674
- popupBlocked: popout.blocked
6675
- }, revision);
6676
- $[15] = floating;
6677
- $[16] = popout.blocked;
6678
- $[17] = revision;
6679
- $[18] = t4;
6680
- $[19] = t5;
6681
- $[20] = t6;
6682
- $[21] = t7;
6683
- $[22] = t8;
6684
- $[23] = t9;
6685
- } else t9 = $[23];
6686
- const content = t9;
6687
- let t10;
6688
- if ($[24] !== content || $[25] !== floating || $[26] !== popout.popup) {
6689
- t10 = popout.popup ? createPortal(/* @__PURE__ */ jsx(StudioPopoutContext, {
6690
- value: true,
6691
- children: /* @__PURE__ */ jsx(UNSAFE_PortalProvider, {
6692
- getContainer: () => popout.popup.document.body,
6693
- children: content
6694
- })
6695
- }), popout.popup.document.body) : floating ? createPortal(content, document.body) : content;
6696
- $[24] = content;
6697
- $[25] = floating;
6698
- $[26] = popout.popup;
6699
- $[27] = t10;
6700
- } else t10 = $[27];
6701
- return t10;
6894
+ },
6895
+ popupBlocked: popout.blocked
6896
+ }, revision);
6897
+ return popout.popup ? createPortal(/* @__PURE__ */ jsx(StudioPopoutContext, {
6898
+ value: true,
6899
+ children: /* @__PURE__ */ jsx(UNSAFE_PortalProvider, {
6900
+ getContainer: () => popout.popup.document.body,
6901
+ children: content
6902
+ })
6903
+ }), popout.popup.document.body) : floating ? createPortal(content, document.body) : content;
6702
6904
  }
6703
6905
  //#endregion
6704
- export { getBoxHighlights as a, UIConfigurationProvider as c, Pin as d, Moon as f, inspectTokens as i, useUIConfiguration as l, ColorModeSwitch as n, HighlightOverlay as o, inspectElement as r, InspectorDetails as s, UIConfigurationModal as t, Sun as u };
6906
+ export { inspectElement as a, HighlightOverlay as c, emptyConfiguration as d, useUIConfiguration as f, Moon as g, Pin as h, saveThemeCss as i, InspectorDetails as l, Plus as m, ColorModeSwitch as n, inspectTokens as o, Sun as p, getThemeWriter as r, getBoxHighlights as s, UIConfigurationModal as t, UIConfigurationProvider as u };