@povio/ui 5.0.0-rc.5 → 5.0.0-rc.7

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.
@@ -3,10 +3,12 @@ import { t as UIConfig } from "../uiConfig.context-BS3r_kTS.js";
3
3
  import { t as Check } from "../check-DYMBkp_Z.js";
4
4
  import { t as ChevronDown } from "../chevron-down-B4Pr8bD3.js";
5
5
  import { t as ChevronRight } from "../chevron-right-3nKJR5Bb.js";
6
+ import { a as tableHeaderTextDefinition, c as GripVertical, i as tableHeadRowDefinition, n as tableDataDefinition, o as tableRowDefinition, r as tableHeadDataDefinition, s as theadDefinition, t as tableCellTextDefinition } from "../table.cva-D5oQ-QvA.js";
6
7
  import { t as Info } from "../info-iUmX3uDk.js";
7
8
  import { a as checkboxDefinition, i as checkboxContentWrapperDefinition, o as checkboxGroupLabelDefinition, r as checkboxContentRowDefinition, s as checkboxIconDefinition, u as Minus } from "../CheckboxCheckmark-CpC3wlMs.js";
8
9
  import { i as Search, n as selectListBoxItemDefinition, r as selectInputTagsContentWrapperDefinition, t as selectPopoverDefinition } from "../selectDesktop.cva-CHAMxhfO.js";
9
10
  import { t as Upload } from "../upload-CXU83BJ4.js";
11
+ import { t as X } from "../x-B6vfz8Ps.js";
10
12
  import { t as clsx } from "../clsx-CnD0nOiA.js";
11
13
  import { n as StyleMergeUtils, r as cva, t as UIOverrides } from "../uiOverrides.context-BTCH9y5a.js";
12
14
  import { c as $7230ffa83bc0c2cf$export$ef03459518577ad4, i as $7230ffa83bc0c2cf$export$9d4c57ee4c6ffdd8, l as $7230ffa83bc0c2cf$export$fabf2dc03a41866e, n as $7230ffa83bc0c2cf$export$29f1550f4b0d4415, r as $7230ffa83bc0c2cf$export$4d86445c2cf5e3, s as $7230ffa83bc0c2cf$export$df3a06d6289f983e, t as $7230ffa83bc0c2cf$export$2881499e37b75b9a } from "../utils-Czcqspm7.js";
@@ -44,11 +46,11 @@ import { a as stepperSeparatorDefinition, i as stepperNumberDefinition, n as ste
44
46
  import { i as dialogOverlayDefinition, n as dialogMainDefinition, t as dialogContentDefinition } from "../dialog.cva-COhDZaVl.js";
45
47
  import { i as alertDefinition, n as statusIconDefinition, r as statusSeparatorDefinition, t as Alert } from "../Alert-CnvEb1D_.js";
46
48
  import { a as toastDefinition, i as toastContainerDefinition } from "../toast.cva-C_L_RffH.js";
47
- import { a as tableHeaderTextDefinition, i as tableHeadRowDefinition, n as tableDataDefinition, o as tableRowDefinition, r as tableHeadDataDefinition, s as theadDefinition, t as tableCellTextDefinition } from "../table.cva-DlMT-zLD.js";
48
49
  import { t as linkDefinition } from "../link.cva-DMTHZiJG.js";
49
50
  import { t as tooltipWrapperTriggerDefinition } from "../tooltipWrapper.cva-BBQ4ic3D.js";
50
51
  import { C as validToken, S as toRgb, _ as parseThemeCss, 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";
51
- import $ahdqC$react, { Suspense, createContext, lazy, use, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
52
+ import { n as splitVariants, t as inspectTokens } from "../token-classes-Bfcx0get.js";
53
+ import $ahdqC$react, { Suspense, createContext, lazy, use, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
52
54
  import { c } from "react/compiler-runtime";
53
55
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
54
56
  import { mergeProps } from "react-aria/mergeProps";
@@ -56,10 +58,12 @@ import { CollectionBuilder } from "react-aria/CollectionBuilder";
56
58
  import { filterDOMProps } from "react-aria/filterDOMProps";
57
59
  import { useFocusRing } from "react-aria/useFocusRing";
58
60
  import { createHideableComponent } from "react-aria/private/collections/Hidden";
61
+ import { createPortal } from "react-dom";
59
62
  import "react-aria/useLocalizedStringFormatter";
60
63
  import "react-aria/useListFormatter";
61
64
  import { HiddenSelect, useSelect } from "react-aria/useSelect";
62
65
  import { useSelectState } from "react-stately/useSelectState";
66
+ import { UNSAFE_PortalProvider } from "react-aria";
63
67
  //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/arrow-down-to-line.mjs
64
68
  /**
65
69
  * @license lucide-react v1.43.0 - ISC
@@ -67,7 +71,7 @@ import { useSelectState } from "react-stately/useSelectState";
67
71
  * This source code is licensed under the ISC license.
68
72
  * See the LICENSE file in the root directory of this source tree.
69
73
  */
70
- const __iconData$5 = {
74
+ const __iconData$9 = {
71
75
  name: "arrow-down-to-line",
72
76
  size: 24,
73
77
  node: [
@@ -85,8 +89,8 @@ const __iconData$5 = {
85
89
  }]
86
90
  ]
87
91
  };
88
- __iconData$5.node;
89
- const ArrowDownToLine = createLucideIcon(__iconData$5);
92
+ __iconData$9.node;
93
+ const ArrowDownToLine = createLucideIcon(__iconData$9);
90
94
  //#endregion
91
95
  //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/chevrons-up-down.mjs
92
96
  /**
@@ -95,7 +99,7 @@ const ArrowDownToLine = createLucideIcon(__iconData$5);
95
99
  * This source code is licensed under the ISC license.
96
100
  * See the LICENSE file in the root directory of this source tree.
97
101
  */
98
- const __iconData$4 = {
102
+ const __iconData$8 = {
99
103
  name: "chevrons-up-down",
100
104
  size: 24,
101
105
  node: [["path", {
@@ -106,8 +110,36 @@ const __iconData$4 = {
106
110
  key: "sgt6xg"
107
111
  }]]
108
112
  };
109
- __iconData$4.node;
110
- const ChevronsUpDown = createLucideIcon(__iconData$4);
113
+ __iconData$8.node;
114
+ const ChevronsUpDown = createLucideIcon(__iconData$8);
115
+ //#endregion
116
+ //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/external-link.mjs
117
+ /**
118
+ * @license lucide-react v1.43.0 - ISC
119
+ *
120
+ * This source code is licensed under the ISC license.
121
+ * See the LICENSE file in the root directory of this source tree.
122
+ */
123
+ const __iconData$7 = {
124
+ name: "external-link",
125
+ size: 24,
126
+ node: [
127
+ ["path", {
128
+ d: "M15 3h6v6",
129
+ key: "1q9fwt"
130
+ }],
131
+ ["path", {
132
+ d: "M10 14 21 3",
133
+ key: "gplh6r"
134
+ }],
135
+ ["path", {
136
+ d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",
137
+ key: "a6xqqp"
138
+ }]
139
+ ]
140
+ };
141
+ __iconData$7.node;
142
+ const ExternalLink = createLucideIcon(__iconData$7);
111
143
  //#endregion
112
144
  //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/moon.mjs
113
145
  /**
@@ -116,7 +148,7 @@ const ChevronsUpDown = createLucideIcon(__iconData$4);
116
148
  * This source code is licensed under the ISC license.
117
149
  * See the LICENSE file in the root directory of this source tree.
118
150
  */
119
- const __iconData$3 = {
151
+ const __iconData$6 = {
120
152
  name: "moon",
121
153
  size: 24,
122
154
  node: [["path", {
@@ -124,8 +156,54 @@ const __iconData$3 = {
124
156
  key: "kfwtm"
125
157
  }]]
126
158
  };
127
- __iconData$3.node;
128
- const Moon = createLucideIcon(__iconData$3);
159
+ __iconData$6.node;
160
+ const Moon = createLucideIcon(__iconData$6);
161
+ //#endregion
162
+ //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/panel-top.mjs
163
+ /**
164
+ * @license lucide-react v1.43.0 - ISC
165
+ *
166
+ * This source code is licensed under the ISC license.
167
+ * See the LICENSE file in the root directory of this source tree.
168
+ */
169
+ const __iconData$5 = {
170
+ name: "panel-top",
171
+ size: 24,
172
+ node: [["rect", {
173
+ width: "18",
174
+ height: "18",
175
+ x: "3",
176
+ y: "3",
177
+ rx: "2",
178
+ key: "afitv7"
179
+ }], ["path", {
180
+ d: "M3 9h18",
181
+ key: "1pudct"
182
+ }]]
183
+ };
184
+ __iconData$5.node;
185
+ const PanelTop = createLucideIcon(__iconData$5);
186
+ //#endregion
187
+ //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/pin.mjs
188
+ /**
189
+ * @license lucide-react v1.43.0 - ISC
190
+ *
191
+ * This source code is licensed under the ISC license.
192
+ * See the LICENSE file in the root directory of this source tree.
193
+ */
194
+ const __iconData$4 = {
195
+ name: "pin",
196
+ size: 24,
197
+ node: [["path", {
198
+ d: "M12 17v5",
199
+ key: "bb1du9"
200
+ }], ["path", {
201
+ d: "M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z",
202
+ key: "1nkz8b"
203
+ }]]
204
+ };
205
+ __iconData$4.node;
206
+ const Pin = createLucideIcon(__iconData$4);
129
207
  //#endregion
130
208
  //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/plus.mjs
131
209
  /**
@@ -134,7 +212,7 @@ const Moon = createLucideIcon(__iconData$3);
134
212
  * This source code is licensed under the ISC license.
135
213
  * See the LICENSE file in the root directory of this source tree.
136
214
  */
137
- const __iconData$2 = {
215
+ const __iconData$3 = {
138
216
  name: "plus",
139
217
  size: 24,
140
218
  node: [["path", {
@@ -145,8 +223,8 @@ const __iconData$2 = {
145
223
  key: "s699le"
146
224
  }]]
147
225
  };
148
- __iconData$2.node;
149
- const Plus = createLucideIcon(__iconData$2);
226
+ __iconData$3.node;
227
+ const Plus = createLucideIcon(__iconData$3);
150
228
  //#endregion
151
229
  //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/rotate-ccw.mjs
152
230
  /**
@@ -155,7 +233,7 @@ const Plus = createLucideIcon(__iconData$2);
155
233
  * This source code is licensed under the ISC license.
156
234
  * See the LICENSE file in the root directory of this source tree.
157
235
  */
158
- const __iconData$1 = {
236
+ const __iconData$2 = {
159
237
  name: "rotate-ccw",
160
238
  size: 24,
161
239
  node: [["path", {
@@ -166,8 +244,60 @@ const __iconData$1 = {
166
244
  key: "1xhq8a"
167
245
  }]]
168
246
  };
247
+ __iconData$2.node;
248
+ const RotateCcw = createLucideIcon(__iconData$2);
249
+ //#endregion
250
+ //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/sliders-horizontal.mjs
251
+ /**
252
+ * @license lucide-react v1.43.0 - ISC
253
+ *
254
+ * This source code is licensed under the ISC license.
255
+ * See the LICENSE file in the root directory of this source tree.
256
+ */
257
+ const __iconData$1 = {
258
+ name: "sliders-horizontal",
259
+ size: 24,
260
+ node: [
261
+ ["path", {
262
+ d: "M10 5H3",
263
+ key: "1qgfaw"
264
+ }],
265
+ ["path", {
266
+ d: "M12 19H3",
267
+ key: "yhmn1j"
268
+ }],
269
+ ["path", {
270
+ d: "M14 3v4",
271
+ key: "1sua03"
272
+ }],
273
+ ["path", {
274
+ d: "M16 17v4",
275
+ key: "1q0r14"
276
+ }],
277
+ ["path", {
278
+ d: "M21 12h-9",
279
+ key: "1o4lsq"
280
+ }],
281
+ ["path", {
282
+ d: "M21 19h-5",
283
+ key: "1rlt1p"
284
+ }],
285
+ ["path", {
286
+ d: "M21 5h-7",
287
+ key: "1oszz2"
288
+ }],
289
+ ["path", {
290
+ d: "M8 10v4",
291
+ key: "tgpxqk"
292
+ }],
293
+ ["path", {
294
+ d: "M8 12H3",
295
+ key: "a7s4jb"
296
+ }]
297
+ ]
298
+ };
169
299
  __iconData$1.node;
170
- const RotateCcw = createLucideIcon(__iconData$1);
300
+ const SlidersHorizontal = createLucideIcon(__iconData$1);
171
301
  //#endregion
172
302
  //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/sun.mjs
173
303
  /**
@@ -492,7 +622,7 @@ function UIConfigurationProvider(t0) {
492
622
  if ($[0] !== applied) {
493
623
  t1 = () => {
494
624
  setDraft(structuredClone(applied));
495
- setRevision(_temp$6);
625
+ setRevision(_temp$7);
496
626
  setOpen(true);
497
627
  };
498
628
  $[0] = applied;
@@ -602,7 +732,7 @@ function UIConfigurationProvider(t0) {
602
732
  } else t10 = $[33];
603
733
  return t10;
604
734
  }
605
- function _temp$6(value) {
735
+ function _temp$7(value) {
606
736
  return value + 1;
607
737
  }
608
738
  function useUIConfiguration() {
@@ -611,6 +741,1468 @@ function useUIConfiguration() {
611
741
  return context;
612
742
  }
613
743
  //#endregion
744
+ //#region src/configurator/inspector/HighlightOverlay.tsx
745
+ const arcs = {
746
+ topLeft: "M0 100 A100 100 0 0 1 100 0",
747
+ topRight: "M0 0 A100 100 0 0 1 100 100",
748
+ bottomRight: "M100 0 A100 100 0 0 1 0 100",
749
+ bottomLeft: "M100 100 A100 100 0 0 1 0 0"
750
+ };
751
+ function HighlightOverlay(t0) {
752
+ const $ = c(17);
753
+ const { highlight, width } = t0;
754
+ const first = highlight.regions[0];
755
+ let t1;
756
+ if ($[0] !== highlight.key) {
757
+ t1 = highlight.key.split(".");
758
+ $[0] = highlight.key;
759
+ $[1] = t1;
760
+ } else t1 = $[1];
761
+ const kind = t1[0];
762
+ const t2 = highlight.key;
763
+ let t3;
764
+ if ($[2] !== highlight.regions || $[3] !== kind) {
765
+ let t4;
766
+ if ($[5] !== kind) {
767
+ t4 = (region) => /* @__PURE__ */ jsx("div", {
768
+ className: `studio-measure-region is-${kind}${region.line ? ` is-${region.line}` : ""}${region.corner ? " is-corner" : ""}`,
769
+ style: {
770
+ left: region.left,
771
+ top: region.top,
772
+ width: region.width,
773
+ height: region.height
774
+ },
775
+ children: region.corner && /* @__PURE__ */ jsx("svg", {
776
+ viewBox: "0 0 100 100",
777
+ preserveAspectRatio: "none",
778
+ "aria-hidden": "true",
779
+ children: /* @__PURE__ */ jsx("path", {
780
+ d: arcs[region.corner],
781
+ fill: "none",
782
+ stroke: "currentColor",
783
+ strokeWidth: "2",
784
+ vectorEffect: "non-scaling-stroke"
785
+ })
786
+ })
787
+ }, `${region.left}:${region.top}:${region.width}:${region.height}`);
788
+ $[5] = kind;
789
+ $[6] = t4;
790
+ } else t4 = $[6];
791
+ t3 = highlight.regions.map(t4);
792
+ $[2] = highlight.regions;
793
+ $[3] = kind;
794
+ $[4] = t3;
795
+ } else t3 = $[4];
796
+ const t4 = Math.max(4, Math.min(first?.left ?? 4, width - 220));
797
+ const t5 = Math.max(4, (first?.top ?? 26) - 22);
798
+ let t6;
799
+ if ($[7] !== t4 || $[8] !== t5) {
800
+ t6 = {
801
+ left: t4,
802
+ top: t5
803
+ };
804
+ $[7] = t4;
805
+ $[8] = t5;
806
+ $[9] = t6;
807
+ } else t6 = $[9];
808
+ let t7;
809
+ if ($[10] !== highlight.label || $[11] !== t6) {
810
+ t7 = /* @__PURE__ */ jsx("span", {
811
+ className: "studio-measure-label",
812
+ style: t6,
813
+ children: highlight.label
814
+ });
815
+ $[10] = highlight.label;
816
+ $[11] = t6;
817
+ $[12] = t7;
818
+ } else t7 = $[12];
819
+ let t8;
820
+ if ($[13] !== highlight.key || $[14] !== t3 || $[15] !== t7) {
821
+ t8 = /* @__PURE__ */ jsxs("div", {
822
+ className: "studio-measure-regions",
823
+ "data-property": t2,
824
+ children: [t3, t7]
825
+ });
826
+ $[13] = highlight.key;
827
+ $[14] = t3;
828
+ $[15] = t7;
829
+ $[16] = t8;
830
+ } else t8 = $[16];
831
+ return t8;
832
+ }
833
+ //#endregion
834
+ //#region src/configurator/inspector/box-highlights.ts
835
+ const sides = [
836
+ "top",
837
+ "right",
838
+ "bottom",
839
+ "left"
840
+ ];
841
+ const corners = [
842
+ "topLeft",
843
+ "topRight",
844
+ "bottomRight",
845
+ "bottomLeft"
846
+ ];
847
+ const numeric = (value) => Number.parseFloat(value) || 0;
848
+ const formatted = (value) => String(Math.round(value * 100) / 100);
849
+ /** Read-only geometry in the inspected element's viewport (including pop-out documents). */
850
+ function getBoxHighlights(element, key) {
851
+ const view = element.ownerDocument.defaultView;
852
+ if (!view) return {
853
+ regions: [],
854
+ label: ""
855
+ };
856
+ const style = view.getComputedStyle(element);
857
+ const rect = element.getBoundingClientRect();
858
+ const sx = element.offsetWidth ? rect.width / element.offsetWidth : 1;
859
+ const sy = element.offsetHeight ? rect.height / element.offsetHeight : 1;
860
+ const read = (name) => style.getPropertyValue(name);
861
+ const scale = (side) => side === "left" || side === "right" ? sx : sy;
862
+ const values = (prefix, suffix = "") => Object.fromEntries(sides.map((side) => [side, numeric(read(`${prefix}-${side}${suffix}`)) * scale(side)]));
863
+ const border = values("border", "-width");
864
+ const padding = values("padding");
865
+ const inner = {
866
+ left: rect.left + border.left,
867
+ top: rect.top + border.top,
868
+ width: Math.max(0, rect.width - border.left - border.right),
869
+ height: Math.max(0, rect.height - border.top - border.bottom)
870
+ };
871
+ const content = {
872
+ left: inner.left + padding.left,
873
+ top: inner.top + padding.top,
874
+ width: Math.max(0, inner.width - padding.left - padding.right),
875
+ height: Math.max(0, inner.height - padding.top - padding.bottom)
876
+ };
877
+ const [kind, part] = key.split(".");
878
+ let regions = [];
879
+ let value = "";
880
+ if (kind === "width" || kind === "height") {
881
+ value = formatted(content[kind] / (kind === "width" ? sx : sy));
882
+ regions = [{
883
+ left: content.left,
884
+ top: content.top,
885
+ width: kind === "width" ? content.width : 1,
886
+ height: kind === "height" ? content.height : 1,
887
+ line: kind === "width" ? "horizontal" : "vertical"
888
+ }];
889
+ } else if (kind === "radius") {
890
+ const radii = corners.map((corner) => {
891
+ const cssCorner = corner.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
892
+ const components = read(`border-${cssCorner}-radius`).trim().split(/\s+/);
893
+ const resolve = (raw, dimension, factor) => raw.endsWith("%") ? numeric(raw) / 100 * dimension : numeric(raw) * factor;
894
+ return [resolve(components[0] || "0", rect.width, sx), resolve(components[1] || components[0] || "0", rect.height, sy)];
895
+ });
896
+ const factor = Math.min(1, rect.width / (radii[0][0] + radii[1][0] || 1), rect.width / (radii[3][0] + radii[2][0] || 1), rect.height / (radii[0][1] + radii[3][1] || 1), rect.height / (radii[1][1] + radii[2][1] || 1));
897
+ const corner = part;
898
+ const radius = radii[corners.indexOf(corner)];
899
+ const width = Math.max(1, radius[0] * factor);
900
+ const height = Math.max(1, radius[1] * factor);
901
+ value = `${formatted(radius[0] * factor / sx)} × ${formatted(radius[1] * factor / sy)}`;
902
+ regions = [{
903
+ left: rect.left + (corner.endsWith("Right") ? rect.width - width : 0),
904
+ top: rect.top + (corner.startsWith("bottom") ? rect.height - height : 0),
905
+ width,
906
+ height,
907
+ corner
908
+ }];
909
+ } else if (kind === "gap") {
910
+ const row = part === "row";
911
+ const rawGap = read(`${part}-gap`);
912
+ const gap = rawGap.endsWith("%") ? numeric(rawGap) / 100 * (row ? content.height / sy : content.width / sx) : numeric(rawGap);
913
+ const size = gap * (row ? sy : sx);
914
+ value = formatted(gap);
915
+ if (size > 0 && /^(inline-)?(flex|grid)$/.test(read("display"))) {
916
+ const children = Array.from(element.children).slice(0, 80).flatMap((child) => {
917
+ const childStyle = view.getComputedStyle(child);
918
+ const box = child.getBoundingClientRect();
919
+ return childStyle.display === "none" || childStyle.visibility === "hidden" || /^(absolute|fixed)$/.test(childStyle.position) || !box.width || !box.height ? [] : [box];
920
+ }).sort((a, b) => row ? a.top - b.top : a.left - b.left);
921
+ const seen = /* @__PURE__ */ new Set();
922
+ for (let i = 0; i < children.length; i++) {
923
+ const a = children[i];
924
+ for (let j = i + 1; j < children.length; j++) {
925
+ const b = children[j];
926
+ const start = row ? a.bottom : a.right;
927
+ const end = row ? b.top : b.left;
928
+ const crossStart = Math.max(row ? a.left : a.top, row ? b.left : b.top, row ? content.left : content.top);
929
+ const crossEnd = Math.min(row ? a.right : a.bottom, row ? b.right : b.bottom, row ? content.left + content.width : content.top + content.height);
930
+ if (end - start < size - .5 || crossEnd <= crossStart) continue;
931
+ if (children.some((c, index) => index !== i && index !== j && (row ? c.top >= start && c.bottom <= end && c.right > crossStart && c.left < crossEnd : c.left >= start && c.right <= end && c.bottom > crossStart && c.top < crossEnd))) continue;
932
+ const axisStart = Math.max((start + end - size) / 2, row ? content.top : content.left);
933
+ const axisEnd = Math.min((start + end + size) / 2, row ? content.top + content.height : content.left + content.width);
934
+ if (axisEnd <= axisStart) continue;
935
+ const region = row ? {
936
+ left: crossStart,
937
+ top: axisStart,
938
+ width: crossEnd - crossStart,
939
+ height: axisEnd - axisStart
940
+ } : {
941
+ left: axisStart,
942
+ top: crossStart,
943
+ width: axisEnd - axisStart,
944
+ height: crossEnd - crossStart
945
+ };
946
+ const id = Object.values(region).map(formatted).join(",");
947
+ if (!seen.has(id)) {
948
+ seen.add(id);
949
+ regions.push(region);
950
+ }
951
+ }
952
+ }
953
+ }
954
+ } else {
955
+ const side = part;
956
+ const horizontal = side === "top" || side === "bottom";
957
+ const raw = read(kind === "position" ? side : `${kind}-${side}${kind === "border" ? "-width" : ""}`);
958
+ const amount = numeric(raw) * scale(side);
959
+ value = formatted(numeric(raw));
960
+ const base = kind === "padding" ? inner : rect;
961
+ const outward = kind === "margin" || kind === "position";
962
+ const thickness = Math.max(1, Math.abs(amount));
963
+ const positiveEdge = side === "bottom" || side === "right";
964
+ const edge = horizontal ? base.top + (positiveEdge ? base.height : 0) : base.left + (positiveEdge ? base.width : 0);
965
+ const offset = outward ? positiveEdge ? amount < 0 ? -thickness : 0 : amount < 0 ? 0 : -thickness : positiveEdge ? -thickness : 0;
966
+ regions = [{
967
+ left: horizontal ? base.left : edge + offset,
968
+ top: horizontal ? edge + offset : base.top,
969
+ width: horizontal ? base.width : thickness,
970
+ height: horizontal ? thickness : base.height
971
+ }];
972
+ if (kind === "position") {
973
+ if (raw === "auto" || read("position") === "static") regions = [];
974
+ else if (read("position") === "absolute" || read("position") === "fixed") {
975
+ const parent = element.offsetParent;
976
+ const parentRect = parent?.getBoundingClientRect();
977
+ const parentStyle = parent ? view.getComputedStyle(parent) : null;
978
+ const parentScale = parent && "offsetWidth" in parent && parent.offsetWidth ? parentRect.width / Number(parent.offsetWidth) : 1;
979
+ const parentScaleY = parent && "offsetHeight" in parent && parent.offsetHeight ? parentRect.height / Number(parent.offsetHeight) : 1;
980
+ const referenceEdge = (parentRect ? {
981
+ left: parentRect.left + numeric(parentStyle.getPropertyValue("border-left-width")) * parentScale,
982
+ right: parentRect.right - numeric(parentStyle.getPropertyValue("border-right-width")) * parentScale,
983
+ top: parentRect.top + numeric(parentStyle.getPropertyValue("border-top-width")) * parentScaleY,
984
+ bottom: parentRect.bottom - numeric(parentStyle.getPropertyValue("border-bottom-width")) * parentScaleY
985
+ } : {
986
+ left: 0,
987
+ top: 0,
988
+ right: view.innerWidth,
989
+ bottom: view.innerHeight
990
+ })[side];
991
+ const targetEdge = edge + (positiveEdge ? 1 : -1) * numeric(read(`margin-${side}`)) * scale(side);
992
+ const start = Math.min(referenceEdge, targetEdge);
993
+ const length = Math.max(1, Math.abs(referenceEdge - targetEdge));
994
+ regions = [{
995
+ left: horizontal ? rect.left : start,
996
+ top: horizontal ? start : rect.top,
997
+ width: horizontal ? rect.width : length,
998
+ height: horizontal ? length : rect.height
999
+ }];
1000
+ }
1001
+ }
1002
+ }
1003
+ const name = key.replace(".", " ").replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase();
1004
+ return {
1005
+ regions,
1006
+ label: `${name}: ${value} px`
1007
+ };
1008
+ }
1009
+ //#endregion
1010
+ //#region src/configurator/inspector/inspection-model.ts
1011
+ function readableColor(value) {
1012
+ const rgb = value.trim().match(/^rgb\(\s*(\d+)\s*[, ]\s*(\d+)\s*[, ]\s*(\d+)\s*\)$/);
1013
+ if (!rgb) return value;
1014
+ return `#${rgb.slice(1).map((channel) => Number(channel).toString(16).padStart(2, "0")).join("")}`;
1015
+ }
1016
+ function resolveToken(style, name, seen = /* @__PURE__ */ new Set()) {
1017
+ if (seen.has(name)) return "";
1018
+ seen.add(name);
1019
+ const value = style.getPropertyValue(name).trim();
1020
+ const reference = value.match(/^var\((--[\w-]+)\)$/);
1021
+ return reference ? resolveToken(style, reference[1], seen) : value;
1022
+ }
1023
+ /** Read-only inspection; always use the element's window, including detached previews. */
1024
+ function inspectElement(element, isKnown) {
1025
+ const view = element.ownerDocument.defaultView;
1026
+ if (!view) throw new Error("The inspected element has no document window.");
1027
+ const style = view.getComputedStyle(element);
1028
+ const rootFontSize = Number.parseFloat(view.getComputedStyle(element.ownerDocument.documentElement).fontSize) || 16;
1029
+ const bounds = element.getBoundingClientRect();
1030
+ const sides = [
1031
+ "top",
1032
+ "right",
1033
+ "bottom",
1034
+ "left"
1035
+ ];
1036
+ const readSides = (prefix, suffix = "") => Object.fromEntries(sides.map((side) => [side, style.getPropertyValue(`${prefix}${side}${suffix}`) || "0px"]));
1037
+ const padding = readSides("padding-");
1038
+ const border = readSides("border-", "-width");
1039
+ const margin = readSides("margin-");
1040
+ const contentDimension = (axis) => {
1041
+ const value = style.getPropertyValue(axis);
1042
+ const dimension = Number.parseFloat(value);
1043
+ const hasPixelDimension = /^\d+(?:\.\d+)?px$/.test(value);
1044
+ if (hasPixelDimension && style.getPropertyValue("box-sizing") !== "border-box") return dimension;
1045
+ const inset = (axis === "width" ? ["left", "right"] : ["top", "bottom"]).reduce((total, side) => total + (Number.parseFloat(padding[side]) || 0) + (Number.parseFloat(border[side]) || 0), 0);
1046
+ return Math.max(0, (hasPixelDimension ? dimension : bounds[axis]) - inset);
1047
+ };
1048
+ const box = {
1049
+ content: {
1050
+ width: contentDimension("width"),
1051
+ height: contentDimension("height")
1052
+ },
1053
+ padding,
1054
+ border,
1055
+ margin,
1056
+ radius: {
1057
+ topLeft: style.getPropertyValue("border-top-left-radius") || "0px",
1058
+ topRight: style.getPropertyValue("border-top-right-radius") || "0px",
1059
+ bottomRight: style.getPropertyValue("border-bottom-right-radius") || "0px",
1060
+ bottomLeft: style.getPropertyValue("border-bottom-left-radius") || "0px"
1061
+ },
1062
+ gap: {
1063
+ row: style.getPropertyValue("row-gap") || "normal",
1064
+ column: style.getPropertyValue("column-gap") || "normal"
1065
+ }
1066
+ };
1067
+ const position = style.getPropertyValue("position");
1068
+ if (position && position !== "static") box.position = readSides("");
1069
+ const classes = Array.from(element.classList);
1070
+ const plainClasses = classes.filter((name) => !splitVariants(name).variants.length && !name.includes("["));
1071
+ const spacing = inspectTokens(plainClasses.join(" "), isKnown);
1072
+ const candidates = (prefix, namespaces) => plainClasses.flatMap((raw) => {
1073
+ const utility = raw.replace(/^!|!$/g, "");
1074
+ if (!utility.startsWith(`${prefix}-`)) return [];
1075
+ const suffix = utility.slice(prefix.length + 1);
1076
+ return namespaces.map((namespace) => `--${namespace}${suffix}`);
1077
+ });
1078
+ const variantsAffect = (prefixes) => classes.some((raw) => {
1079
+ const { variants, utility } = splitVariants(raw);
1080
+ return variants.length > 0 && prefixes.some((prefix) => utility.replace(/^!/, "").startsWith(`${prefix}-`));
1081
+ });
1082
+ const equivalent = (value, computed, property) => {
1083
+ if (!value) return false;
1084
+ if (property.includes("color")) {
1085
+ if (value.match(/^\d+(?:\.\d+)?\s+\d+(?:\.\d+)?\s+\d+(?:\.\d+)?$/)) value = `rgb(${value})`;
1086
+ return readableColor(value).toLowerCase() === readableColor(computed).toLowerCase();
1087
+ }
1088
+ const length = value.match(/^(-?\d+(?:\.\d+)?)(rem|px|em)$/);
1089
+ if (length && computed.endsWith("px")) {
1090
+ let factor = 1;
1091
+ if (length[2] === "rem") factor = rootFontSize;
1092
+ if (length[2] === "em") factor = Number.parseFloat(style.fontSize);
1093
+ return Math.abs(Number(length[1]) * factor - Number.parseFloat(computed)) < .02;
1094
+ }
1095
+ return value.replace(/["']/g, "").replace(/\s+/g, " ") === computed.replace(/["']/g, "").replace(/\s+/g, " ");
1096
+ };
1097
+ const property = (label, css, tokens = [], prefixes = []) => {
1098
+ const computed = style.getPropertyValue(css);
1099
+ const matching = variantsAffect(prefixes) ? [] : tokens.filter((token) => !!token && isKnown(token) && equivalent(resolveToken(style, token), computed, css));
1100
+ const token = [...new Set(matching)][0];
1101
+ const isColor = css.includes("color");
1102
+ return {
1103
+ label,
1104
+ value: isColor ? readableColor(computed) : computed,
1105
+ ...token ? { token } : {},
1106
+ ...isColor ? { color: computed } : {}
1107
+ };
1108
+ };
1109
+ const tag = element.tagName.toLowerCase();
1110
+ const role = element.getAttribute("role");
1111
+ const context = element.closest("[data-inspector-name]")?.getAttribute("data-inspector-name") || element.closest(".studio-gallery-card")?.querySelector(".studio-gallery-card-title")?.textContent?.trim();
1112
+ const description = (element.getAttribute("aria-label") || element.innerText || element.textContent || "").trim().replace(/\s+/g, " ").slice(0, 100);
1113
+ const name = context || role || tag;
1114
+ const paddingPrefixes = [
1115
+ "p",
1116
+ "px",
1117
+ "py",
1118
+ "pt",
1119
+ "pr",
1120
+ "pb",
1121
+ "pl",
1122
+ "ps",
1123
+ "pe"
1124
+ ];
1125
+ const layout = [
1126
+ {
1127
+ label: "Width",
1128
+ value: style.getPropertyValue("width") || `${bounds.width}px`
1129
+ },
1130
+ {
1131
+ label: "Height",
1132
+ value: style.getPropertyValue("height") || `${bounds.height}px`
1133
+ },
1134
+ property("Display", "display"),
1135
+ property("Position", "position"),
1136
+ ...sides.map((side) => property(`Padding ${side}`, `padding-${side}`, [spacing.padding[side]], paddingPrefixes)),
1137
+ ...sides.map((side) => property(`Margin ${side}`, `margin-${side}`)),
1138
+ property("Row gap", "row-gap", [spacing.gap.row], ["gap"]),
1139
+ property("Column gap", "column-gap", [spacing.gap.column], ["gap"]),
1140
+ property("Radius", "border-radius", [spacing.radius], ["rounded"]),
1141
+ ...sides.map((side) => property(`Border ${side} width`, `border-${side}-width`))
1142
+ ];
1143
+ const typography = [
1144
+ property("Font", "font-family", candidates("font", ["font-"]), ["font"]),
1145
+ property("Size", "font-size", candidates("text", ["text-"]), ["text"]),
1146
+ property("Weight", "font-weight", candidates("font", ["font-weight-"]), ["font"]),
1147
+ property("Line height", "line-height"),
1148
+ property("Letter spacing", "letter-spacing"),
1149
+ property("Alignment", "text-align")
1150
+ ];
1151
+ const appearance = [
1152
+ property("Text", "color", candidates("text", ["color-", ""]).flatMap((token) => [token, `${token}-base`]), ["text"]),
1153
+ property("Fill", "background-color", candidates("bg", ["color-", ""]).flatMap((token) => [token, `${token}-base`]), ["bg"]),
1154
+ property("Border", "border-top-color", candidates("border", ["color-", ""]).flatMap((token) => [token, `${token}-base`]), ["border"]),
1155
+ property("Opacity", "opacity"),
1156
+ property("Shadow", "box-shadow")
1157
+ ];
1158
+ const isZero = (value) => value.split(/\s+/).every((part) => /^-?0(?:\.0+)?(?:px|rem|em|%)?$/.test(part));
1159
+ const visibleProperty = (row) => {
1160
+ if (row.label === "Width" || row.label === "Height" || row.token) return true;
1161
+ const value = row.value.trim();
1162
+ if (!value) return false;
1163
+ if (/^(Padding|Margin|Border .* width|Row gap|Column gap|Radius)/.test(row.label) && (isZero(value) || value === "normal")) return false;
1164
+ if (row.label === "Position" && value === "static") return false;
1165
+ if (row.label === "Display" && ["inline", "block"].includes(value)) return false;
1166
+ if (row.label === "Shadow" && value === "none") return false;
1167
+ if (row.label === "Opacity" && Number(value) === 1) return false;
1168
+ if (row.label === "Fill" && (value === "transparent" || /^rgba?\([^)]*[,/]\s*0(?:\.0+)?%?\s*\)$/.test(value))) return false;
1169
+ if (row.label === "Border" && !(Number.parseFloat(border.top) > 0)) return false;
1170
+ if (row.label === "Line height" && value === "normal") return false;
1171
+ if (row.label === "Letter spacing" && (value === "normal" || isZero(value))) return false;
1172
+ if (row.label === "Alignment" && [
1173
+ "normal",
1174
+ "start",
1175
+ "left"
1176
+ ].includes(value)) return false;
1177
+ if (row.label === "Weight" && ["400", "normal"].includes(value)) return false;
1178
+ return true;
1179
+ };
1180
+ return {
1181
+ name,
1182
+ display: style.display,
1183
+ tag,
1184
+ description,
1185
+ width: bounds.width,
1186
+ height: bounds.height,
1187
+ box,
1188
+ groups: [
1189
+ {
1190
+ name: "Layout",
1191
+ properties: layout
1192
+ },
1193
+ {
1194
+ name: "Typography",
1195
+ properties: typography
1196
+ },
1197
+ {
1198
+ name: "Appearance",
1199
+ properties: appearance
1200
+ }
1201
+ ].map((group) => ({
1202
+ name: group.name,
1203
+ properties: group.properties.filter(visibleProperty)
1204
+ })).filter((group) => group.properties.length > 0)
1205
+ };
1206
+ }
1207
+ //#endregion
1208
+ //#region src/configurator/inspector/PreviewInspector.tsx
1209
+ /** Read the real element underneath the inert gallery's stretched zoom button. */
1210
+ function elementAtPoint(root, x, y) {
1211
+ const direct = root.ownerDocument.elementsFromPoint(x, y).find((element) => root.contains(element));
1212
+ if (!direct || direct.closest(".studio-inspect-layer")) return null;
1213
+ const demo = direct.closest(".studio-gallery-card")?.querySelector(".studio-gallery-demo");
1214
+ let hit = direct;
1215
+ if (demo) {
1216
+ const found = [demo, ...demo.querySelectorAll("*")].reverse().find((element) => {
1217
+ if (element.namespaceURI !== "http://www.w3.org/1999/xhtml" || element.closest(".sr-only")) return false;
1218
+ const rect = element.getBoundingClientRect();
1219
+ return rect.width > 1 && rect.height > 1 && x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
1220
+ });
1221
+ if (!found) return null;
1222
+ hit = found;
1223
+ }
1224
+ const semantic = hit.closest("button,input,textarea,select,a,label,[role],h1,h2,h3,h4,h5,h6,p");
1225
+ if (semantic && root.contains(semantic) && (!demo || demo.contains(semantic))) hit = semantic;
1226
+ if (hit.namespaceURI !== "http://www.w3.org/1999/xhtml" || hit === root || hit.classList.contains("studio-gallery-card-hit")) return null;
1227
+ return hit;
1228
+ }
1229
+ function PreviewInspector({ children, revision, isKnown, onSelect, onScroll }) {
1230
+ const selectionDescriptionId = useId();
1231
+ const rootRef = useRef(null);
1232
+ const targetRef = useRef(null);
1233
+ const frameRef = useRef(null);
1234
+ const pendingPoint = useRef(null);
1235
+ const pinnedRef = useRef(false);
1236
+ const [pinned, setPinned] = useState(false);
1237
+ const [inspectMode, setInspectMode] = useState(true);
1238
+ const [snapshot, setSnapshot] = useState(null);
1239
+ const [outline, setOutline] = useState(null);
1240
+ const highlightKey = useRef(null);
1241
+ const [highlight, setHighlight] = useState(null);
1242
+ const measure = useCallback(() => {
1243
+ const root = rootRef.current;
1244
+ const target = targetRef.current;
1245
+ if (!root || !target?.isConnected || !root.contains(target)) {
1246
+ targetRef.current = null;
1247
+ pinnedRef.current = false;
1248
+ setPinned(false);
1249
+ setSnapshot(null);
1250
+ setOutline(null);
1251
+ highlightKey.current = null;
1252
+ setHighlight(null);
1253
+ return;
1254
+ }
1255
+ const rect = target.getBoundingClientRect();
1256
+ if (!rect.width || !rect.height) {
1257
+ setSnapshot(null);
1258
+ setOutline(null);
1259
+ highlightKey.current = null;
1260
+ setHighlight(null);
1261
+ return;
1262
+ }
1263
+ const origin = root.getBoundingClientRect();
1264
+ const next = inspectElement(target, isKnown);
1265
+ setSnapshot((current) => JSON.stringify(current) === JSON.stringify(next) ? current : next);
1266
+ setOutline({
1267
+ left: rect.left - origin.left,
1268
+ top: rect.top - origin.top,
1269
+ width: rect.width,
1270
+ height: rect.height
1271
+ });
1272
+ if (highlightKey.current) {
1273
+ const details = getBoxHighlights(target, highlightKey.current);
1274
+ setHighlight({
1275
+ key: highlightKey.current,
1276
+ label: details.label,
1277
+ regions: details.regions.map((region) => ({
1278
+ width: region.width,
1279
+ height: region.height,
1280
+ corner: region.corner,
1281
+ line: region.line,
1282
+ left: region.left - origin.left,
1283
+ top: region.top - origin.top
1284
+ }))
1285
+ });
1286
+ }
1287
+ }, [isKnown]);
1288
+ const schedule = useCallback(() => {
1289
+ const owner = rootRef.current?.ownerDocument.defaultView;
1290
+ if (!owner || frameRef.current !== null) return;
1291
+ frameRef.current = owner.requestAnimationFrame(() => {
1292
+ frameRef.current = null;
1293
+ const root_0 = rootRef.current;
1294
+ const point = pendingPoint.current;
1295
+ pendingPoint.current = null;
1296
+ if (root_0 && point && !pinnedRef.current) {
1297
+ const hit = elementAtPoint(root_0, point.x, point.y);
1298
+ if (hit) targetRef.current = hit;
1299
+ }
1300
+ measure();
1301
+ });
1302
+ }, [measure]);
1303
+ useLayoutEffect(schedule, [schedule, revision]);
1304
+ useEffect(() => {
1305
+ const root_1 = rootRef.current;
1306
+ const owner_0 = root_1?.ownerDocument.defaultView;
1307
+ if (!root_1 || !owner_0) return;
1308
+ const observer = new ResizeObserver(schedule);
1309
+ observer.observe(root_1);
1310
+ const modal = root_1.closest(".studio-modal");
1311
+ if (modal) observer.observe(modal);
1312
+ const mutations = new MutationObserver((records) => {
1313
+ if (records.some((record) => {
1314
+ return !(record.target.nodeType === 1 ? record.target : record.target.parentElement)?.closest(".studio-hover-outline-layer");
1315
+ })) schedule();
1316
+ });
1317
+ mutations.observe(root_1, {
1318
+ subtree: true,
1319
+ childList: true,
1320
+ attributes: true,
1321
+ characterData: true
1322
+ });
1323
+ owner_0.addEventListener("scroll", schedule, true);
1324
+ owner_0.addEventListener("resize", schedule);
1325
+ return () => {
1326
+ observer.disconnect();
1327
+ mutations.disconnect();
1328
+ owner_0.removeEventListener("scroll", schedule, true);
1329
+ owner_0.removeEventListener("resize", schedule);
1330
+ if (frameRef.current !== null) owner_0.cancelAnimationFrame(frameRef.current);
1331
+ frameRef.current = null;
1332
+ };
1333
+ }, [schedule]);
1334
+ const showHighlight = useCallback((key) => {
1335
+ highlightKey.current = key;
1336
+ if (!key) {
1337
+ setHighlight(null);
1338
+ return;
1339
+ }
1340
+ const target_0 = targetRef.current;
1341
+ const canvas = rootRef.current;
1342
+ if (target_0 && canvas) {
1343
+ const rect_0 = target_0.getBoundingClientRect();
1344
+ const view = canvas.getBoundingClientRect();
1345
+ if (rect_0.bottom < view.top || rect_0.top > view.bottom || rect_0.right < view.left || rect_0.left > view.right) target_0.scrollIntoView({
1346
+ block: "nearest",
1347
+ inline: "nearest"
1348
+ });
1349
+ }
1350
+ schedule();
1351
+ }, [schedule]);
1352
+ const dismiss = () => {
1353
+ targetRef.current = null;
1354
+ pendingPoint.current = null;
1355
+ pinnedRef.current = false;
1356
+ setPinned(false);
1357
+ setSnapshot(null);
1358
+ setOutline(null);
1359
+ highlightKey.current = null;
1360
+ setHighlight(null);
1361
+ };
1362
+ return /* @__PURE__ */ jsxs("div", {
1363
+ className: `studio-hover-inspector${inspectMode || snapshot ? " has-inspector" : ""}`,
1364
+ onPointerMoveCapture: (event) => {
1365
+ if (event.target.closest(".studio-inspector-panel, .studio-inspector-toolbar")) return;
1366
+ if (!inspectMode) return;
1367
+ if (!pinnedRef.current) pendingPoint.current = {
1368
+ x: event.clientX,
1369
+ y: event.clientY
1370
+ };
1371
+ schedule();
1372
+ },
1373
+ onFocusCapture: (event_0) => {
1374
+ if (event_0.target.closest(".studio-inspector-panel, .studio-inspector-toolbar") || !inspectMode) return;
1375
+ if (pinnedRef.current || !rootRef.current) return;
1376
+ const element_0 = event_0.target;
1377
+ const rect_1 = element_0.getBoundingClientRect();
1378
+ targetRef.current = elementAtPoint(rootRef.current, rect_1.left + rect_1.width / 2, rect_1.top + rect_1.height / 2) ?? element_0;
1379
+ schedule();
1380
+ },
1381
+ onPointerDownCapture: (event_1) => {
1382
+ if (!inspectMode || event_1.target.closest(".studio-inspector-panel, .studio-inspector-toolbar, .studio-inspect-region")) return;
1383
+ event_1.preventDefault();
1384
+ event_1.stopPropagation();
1385
+ },
1386
+ onClickCapture: (event_2) => {
1387
+ const element_1 = event_2.target;
1388
+ if (!inspectMode || element_1.closest(".studio-inspector-panel, .studio-inspector-toolbar, .studio-inspect-region")) return;
1389
+ const root_2 = rootRef.current;
1390
+ if (!root_2) return;
1391
+ const rect_2 = element_1.getBoundingClientRect();
1392
+ const hit_0 = elementAtPoint(root_2, event_2.detail ? event_2.clientX : rect_2.left + rect_2.width / 2, event_2.detail ? event_2.clientY : rect_2.top + rect_2.height / 2);
1393
+ if (!hit_0) return;
1394
+ event_2.preventDefault();
1395
+ event_2.stopPropagation();
1396
+ if (pinnedRef.current && targetRef.current === hit_0) {
1397
+ pinnedRef.current = false;
1398
+ setPinned(false);
1399
+ schedule();
1400
+ return;
1401
+ }
1402
+ targetRef.current = hit_0;
1403
+ pendingPoint.current = null;
1404
+ pinnedRef.current = true;
1405
+ setPinned(true);
1406
+ schedule();
1407
+ },
1408
+ onKeyDownCapture: (event_3) => {
1409
+ if (inspectMode && rootRef.current?.contains(event_3.target) && [
1410
+ "ArrowLeft",
1411
+ "ArrowRight",
1412
+ "ArrowUp",
1413
+ "ArrowDown",
1414
+ "Home",
1415
+ "End",
1416
+ "PageUp",
1417
+ "PageDown"
1418
+ ].includes(event_3.key)) {
1419
+ event_3.preventDefault();
1420
+ event_3.stopPropagation();
1421
+ return;
1422
+ }
1423
+ if (event_3.key === "Escape" && snapshot && inspectMode) {
1424
+ event_3.preventDefault();
1425
+ event_3.stopPropagation();
1426
+ dismiss();
1427
+ }
1428
+ },
1429
+ children: [
1430
+ /* @__PURE__ */ jsxs("div", {
1431
+ className: "studio-inspector-toolbar",
1432
+ children: [/* @__PURE__ */ jsx("span", { children: pinned ? "Selection pinned" : "Hover to inspect · click to select" }), /* @__PURE__ */ jsxs("div", {
1433
+ className: "studio-mode",
1434
+ role: "group",
1435
+ "aria-label": "Preview interaction",
1436
+ children: [/* @__PURE__ */ jsx("button", {
1437
+ type: "button",
1438
+ "aria-pressed": inspectMode,
1439
+ onClick: () => setInspectMode(true),
1440
+ children: "Inspect"
1441
+ }), /* @__PURE__ */ jsx("button", {
1442
+ type: "button",
1443
+ "aria-pressed": !inspectMode,
1444
+ onClick: () => setInspectMode(false),
1445
+ children: "Interact"
1446
+ })]
1447
+ })]
1448
+ }),
1449
+ /* @__PURE__ */ jsxs("div", {
1450
+ className: "studio-inspector-canvas-shell",
1451
+ children: [/* @__PURE__ */ jsx("div", {
1452
+ ref: rootRef,
1453
+ className: "studio-inspector-canvas",
1454
+ onScroll: (event_4) => onScroll?.(event_4.currentTarget.scrollTop),
1455
+ children
1456
+ }), /* @__PURE__ */ jsxs("div", {
1457
+ className: "studio-hover-outline-layer",
1458
+ "aria-hidden": "true",
1459
+ children: [outline && snapshot && /* @__PURE__ */ jsx("div", {
1460
+ className: "studio-hover-outline",
1461
+ style: outline,
1462
+ children: !highlight && /* @__PURE__ */ jsxs("span", { children: [
1463
+ snapshot.name,
1464
+ " · ",
1465
+ Math.round(snapshot.width),
1466
+ " × ",
1467
+ Math.round(snapshot.height)
1468
+ ] })
1469
+ }), highlight && /* @__PURE__ */ jsx(HighlightOverlay, {
1470
+ highlight,
1471
+ width: rootRef.current?.clientWidth ?? 0
1472
+ })]
1473
+ })]
1474
+ }),
1475
+ (inspectMode || snapshot) && /* @__PURE__ */ jsxs("aside", {
1476
+ className: "studio-inspector-panel",
1477
+ "aria-label": "Inspector view",
1478
+ "aria-describedby": selectionDescriptionId,
1479
+ children: [
1480
+ /* @__PURE__ */ jsx("span", {
1481
+ id: selectionDescriptionId,
1482
+ hidden: true,
1483
+ children: snapshot ? `Inspecting ${snapshot.name}` : "No selected element"
1484
+ }),
1485
+ /* @__PURE__ */ jsxs("header", { children: [
1486
+ /* @__PURE__ */ jsx("strong", { children: "Inspector view" }),
1487
+ /* @__PURE__ */ jsx("button", {
1488
+ type: "button",
1489
+ "aria-label": "Pin inspected element",
1490
+ "aria-pressed": pinned,
1491
+ disabled: !snapshot,
1492
+ title: "Pin inspected element",
1493
+ onClick: () => {
1494
+ pinnedRef.current = !pinned;
1495
+ setPinned(!pinned);
1496
+ },
1497
+ children: /* @__PURE__ */ jsx(Pin, { size: 14 })
1498
+ }),
1499
+ /* @__PURE__ */ jsx("button", {
1500
+ type: "button",
1501
+ "aria-label": "Close inspector view",
1502
+ onClick: () => {
1503
+ dismiss();
1504
+ setInspectMode(false);
1505
+ },
1506
+ children: /* @__PURE__ */ jsx(X, { size: 15 })
1507
+ })
1508
+ ] }),
1509
+ snapshot ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("section", {
1510
+ className: "studio-inspector-layout",
1511
+ children: [/* @__PURE__ */ jsxs("div", {
1512
+ className: "studio-inspector-section-heading",
1513
+ children: [/* @__PURE__ */ jsx("h3", { children: "Layout" }), /* @__PURE__ */ jsx("span", {
1514
+ title: "CSS display",
1515
+ children: snapshot.display
1516
+ })]
1517
+ }), /* @__PURE__ */ jsx(BoxModel, {
1518
+ snapshot,
1519
+ onSelect,
1520
+ onHighlight: showHighlight
1521
+ })]
1522
+ }), snapshot.groups.map((group) => ({
1523
+ name: group.name,
1524
+ properties: group.properties.filter((property) => group.name !== "Layout" || ![
1525
+ "Width",
1526
+ "Height",
1527
+ "Margin",
1528
+ "Border width",
1529
+ "Radius",
1530
+ "Row gap",
1531
+ "Column gap",
1532
+ "Display"
1533
+ ].includes(property.label) && !/^(Padding |Margin |Border .* width$)/.test(property.label))
1534
+ })).filter((group_0) => group_0.properties.length).map((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: [
1535
+ property_0.color && /* @__PURE__ */ jsx("i", { style: { background: property_0.color } }),
1536
+ /* @__PURE__ */ jsx("span", { children: property_0.value }),
1537
+ property_0.token && /* @__PURE__ */ jsx("button", {
1538
+ type: "button",
1539
+ title: `Edit ${property_0.token}`,
1540
+ onClick: () => onSelect(property_0.token),
1541
+ children: property_0.token.replace(/^--/, "")
1542
+ })
1543
+ ] })] }, property_0.label)) })] }, group_1.name))] }) : /* @__PURE__ */ jsx("p", {
1544
+ className: "studio-inspector-empty",
1545
+ children: "Hover an element in the preview to inspect it. Click to pin your selection."
1546
+ })
1547
+ ]
1548
+ })
1549
+ ]
1550
+ });
1551
+ }
1552
+ function BoxModel(t0) {
1553
+ const $ = c(39);
1554
+ const { snapshot, onSelect, onHighlight } = t0;
1555
+ const box = snapshot.box;
1556
+ const number = _temp2$4;
1557
+ let t1;
1558
+ let t2;
1559
+ let t3;
1560
+ let t4;
1561
+ if ($[0] !== box.border || $[1] !== box.content.height || $[2] !== box.content.width || $[3] !== box.gap.column || $[4] !== box.gap.row || $[5] !== box.margin || $[6] !== box.padding || $[7] !== box.position || $[8] !== box.radius || $[9] !== onHighlight || $[10] !== onSelect || $[11] !== snapshot.groups) {
1562
+ const properties = snapshot.groups.flatMap(_temp3$3);
1563
+ const tokenFor = (label) => properties.find((property) => property.label === label)?.token;
1564
+ const nonzero = _temp5$1;
1565
+ let t5;
1566
+ if ($[16] !== onHighlight || $[17] !== onSelect) {
1567
+ t5 = (text, label_0, className, token, key) => /* @__PURE__ */ jsx("button", {
1568
+ type: "button",
1569
+ className,
1570
+ title: token ? `Edit ${token}` : `${label_0}: ${text}`,
1571
+ "aria-label": `${label_0}: ${text}`,
1572
+ "data-token": token,
1573
+ "data-box-highlight": key,
1574
+ onPointerEnter: () => onHighlight(key ?? null),
1575
+ onPointerLeave: () => onHighlight(null),
1576
+ onFocus: () => onHighlight(key ?? null),
1577
+ onBlur: () => onHighlight(null),
1578
+ onClick: () => token ? onSelect(token) : onHighlight(key ?? null),
1579
+ children: number(text)
1580
+ });
1581
+ $[16] = onHighlight;
1582
+ $[17] = onSelect;
1583
+ $[18] = t5;
1584
+ } else t5 = $[18];
1585
+ const value_1 = t5;
1586
+ const layer = (name, values, children) => /* @__PURE__ */ jsxs("div", {
1587
+ className: `studio-box-layer is-${name}`,
1588
+ style: name === "border" ? { borderRadius: [
1589
+ box.radius.topLeft,
1590
+ box.radius.topRight,
1591
+ box.radius.bottomRight,
1592
+ box.radius.bottomLeft
1593
+ ].map((radius) => nonzero(radius) ? "12px" : "0px").join(" ") } : void 0,
1594
+ children: [
1595
+ /* @__PURE__ */ jsx("span", {
1596
+ className: "studio-box-name",
1597
+ children: name
1598
+ }),
1599
+ [
1600
+ "top",
1601
+ "right",
1602
+ "bottom",
1603
+ "left"
1604
+ ].map((side) => /* @__PURE__ */ jsx("span", { children: value_1(values[side], `${name} ${side}`, `studio-box-value is-${side}`, tokenFor(`${name[0].toUpperCase()}${name.slice(1)} ${side}`), `${name}.${side}`) }, side)),
1605
+ name === "border" && Object.values(box.radius).some(nonzero) && Object.entries(box.radius).map((t6) => {
1606
+ const [corner, radius_0] = t6;
1607
+ return /* @__PURE__ */ jsx("span", { children: value_1(radius_0, `Radius ${corner}`, `studio-box-radius is-${corner}`, tokenFor("Radius"), `radius.${corner}`) }, corner);
1608
+ }),
1609
+ children
1610
+ ]
1611
+ });
1612
+ let t7;
1613
+ if ($[19] !== box.gap.row) {
1614
+ t7 = nonzero(box.gap.row);
1615
+ $[19] = box.gap.row;
1616
+ $[20] = t7;
1617
+ } else t7 = $[20];
1618
+ const hasRowGap = t7;
1619
+ let t8;
1620
+ if ($[21] !== box.gap.column) {
1621
+ t8 = nonzero(box.gap.column);
1622
+ $[21] = box.gap.column;
1623
+ $[22] = t8;
1624
+ } else t8 = $[22];
1625
+ const hasColumnGap = t8;
1626
+ const t9 = `${Math.round(box.content.width * 10) / 10}px`;
1627
+ let t10;
1628
+ if ($[23] !== t9 || $[24] !== value_1) {
1629
+ t10 = value_1(t9, "Content width", "studio-box-dimension-value", void 0, "width");
1630
+ $[23] = t9;
1631
+ $[24] = value_1;
1632
+ $[25] = t10;
1633
+ } else t10 = $[25];
1634
+ let t11;
1635
+ if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
1636
+ t11 = /* @__PURE__ */ jsx("span", { children: "×" });
1637
+ $[26] = t11;
1638
+ } else t11 = $[26];
1639
+ const t12 = `${Math.round(box.content.height * 10) / 10}px`;
1640
+ let t13;
1641
+ if ($[27] !== t12 || $[28] !== value_1) {
1642
+ t13 = value_1(t12, "Content height", "studio-box-dimension-value", void 0, "height");
1643
+ $[27] = t12;
1644
+ $[28] = value_1;
1645
+ $[29] = t13;
1646
+ } else t13 = $[29];
1647
+ let t14;
1648
+ if ($[30] !== t10 || $[31] !== t13) {
1649
+ t14 = /* @__PURE__ */ jsx("div", {
1650
+ className: "studio-box-content",
1651
+ title: "Content width × height",
1652
+ children: /* @__PURE__ */ jsxs("div", {
1653
+ className: "studio-box-dimensions",
1654
+ children: [
1655
+ t10,
1656
+ t11,
1657
+ t13
1658
+ ]
1659
+ })
1660
+ });
1661
+ $[30] = t10;
1662
+ $[31] = t13;
1663
+ $[32] = t14;
1664
+ } else t14 = $[32];
1665
+ const content = t14;
1666
+ const diagram = layer("margin", box.margin, layer("border", box.border, layer("padding", box.padding, content)));
1667
+ t1 = "studio-box-model";
1668
+ t2 = "Box model";
1669
+ t3 = box.position ? layer("position", box.position, diagram) : diagram;
1670
+ t4 = (hasRowGap || hasColumnGap) && /* @__PURE__ */ jsx("div", {
1671
+ className: "studio-box-gaps",
1672
+ "aria-label": "Layout gaps",
1673
+ children: /* @__PURE__ */ jsxs("div", {
1674
+ className: "studio-gap-grid",
1675
+ style: {
1676
+ gridTemplateColumns: `minmax(0,1fr) ${hasColumnGap ? 28 : 0}px minmax(0,1fr)`,
1677
+ gridTemplateRows: `20px ${hasRowGap ? 22 : 0}px 20px`
1678
+ },
1679
+ children: [
1680
+ /* @__PURE__ */ jsx("i", {}),
1681
+ /* @__PURE__ */ jsx("i", {}),
1682
+ /* @__PURE__ */ jsx("i", {}),
1683
+ /* @__PURE__ */ jsx("i", {}),
1684
+ hasColumnGap && value_1(box.gap.column, "Column gap", "studio-gap-number is-column", tokenFor("Column gap"), "gap.column"),
1685
+ hasRowGap && value_1(box.gap.row, "Row gap", "studio-gap-number is-row", tokenFor("Row gap"), "gap.row")
1686
+ ]
1687
+ })
1688
+ });
1689
+ $[0] = box.border;
1690
+ $[1] = box.content.height;
1691
+ $[2] = box.content.width;
1692
+ $[3] = box.gap.column;
1693
+ $[4] = box.gap.row;
1694
+ $[5] = box.margin;
1695
+ $[6] = box.padding;
1696
+ $[7] = box.position;
1697
+ $[8] = box.radius;
1698
+ $[9] = onHighlight;
1699
+ $[10] = onSelect;
1700
+ $[11] = snapshot.groups;
1701
+ $[12] = t1;
1702
+ $[13] = t2;
1703
+ $[14] = t3;
1704
+ $[15] = t4;
1705
+ } else {
1706
+ t1 = $[12];
1707
+ t2 = $[13];
1708
+ t3 = $[14];
1709
+ t4 = $[15];
1710
+ }
1711
+ let t5;
1712
+ if ($[33] === Symbol.for("react.memo_cache_sentinel")) {
1713
+ t5 = /* @__PURE__ */ jsx("figcaption", { children: "Box model · px" });
1714
+ $[33] = t5;
1715
+ } else t5 = $[33];
1716
+ let t6;
1717
+ if ($[34] !== t1 || $[35] !== t2 || $[36] !== t3 || $[37] !== t4) {
1718
+ t6 = /* @__PURE__ */ jsxs("figure", {
1719
+ className: t1,
1720
+ "aria-label": t2,
1721
+ children: [
1722
+ t3,
1723
+ t4,
1724
+ t5
1725
+ ]
1726
+ });
1727
+ $[34] = t1;
1728
+ $[35] = t2;
1729
+ $[36] = t3;
1730
+ $[37] = t4;
1731
+ $[38] = t6;
1732
+ } else t6 = $[38];
1733
+ return t6;
1734
+ }
1735
+ function _temp5$1(value_0) {
1736
+ return value_0 !== "normal" && value_0.split(/\s+/).some(_temp4$3);
1737
+ }
1738
+ function _temp4$3(part) {
1739
+ return parseFloat(part) !== 0 && Number.isFinite(parseFloat(part));
1740
+ }
1741
+ function _temp3$3(group) {
1742
+ return group.properties;
1743
+ }
1744
+ function _temp2$4(value) {
1745
+ return value.replace(/(-?\d*\.?\d+)px/g, _temp$6);
1746
+ }
1747
+ function _temp$6(_, amount) {
1748
+ return String(Math.round(Number(amount) * 10) / 10);
1749
+ }
1750
+ //#endregion
1751
+ //#region src/configurator/ConfigurationLauncher.tsx
1752
+ function ConfigurationLauncher({ position, onOpen }) {
1753
+ const ref = useRef(null);
1754
+ const gesture = useRef(null);
1755
+ const dragged = useRef(false);
1756
+ const pending = useRef(null);
1757
+ const frame = useRef(null);
1758
+ const place = useCallback((next) => {
1759
+ const element = ref.current;
1760
+ if (!element) return;
1761
+ const left = Math.max(8, Math.min(next.left, window.innerWidth - element.offsetWidth - 8));
1762
+ const top = Math.max(8, Math.min(next.top, window.innerHeight - element.offsetHeight - 8));
1763
+ position.current = {
1764
+ left,
1765
+ top
1766
+ };
1767
+ element.style.left = `${left}px`;
1768
+ element.style.top = `${top}px`;
1769
+ }, [position]);
1770
+ function finish() {
1771
+ if (frame.current !== null) cancelAnimationFrame(frame.current);
1772
+ frame.current = null;
1773
+ if (pending.current) place(pending.current);
1774
+ pending.current = null;
1775
+ gesture.current = null;
1776
+ }
1777
+ useLayoutEffect(() => {
1778
+ const element_0 = ref.current;
1779
+ if (!element_0) return;
1780
+ const resize = () => place(position.current ?? {
1781
+ left: window.innerWidth - element_0.offsetWidth - 24,
1782
+ top: window.innerHeight - element_0.offsetHeight - 24
1783
+ });
1784
+ resize();
1785
+ window.addEventListener("resize", resize);
1786
+ return () => {
1787
+ window.removeEventListener("resize", resize);
1788
+ if (frame.current !== null) cancelAnimationFrame(frame.current);
1789
+ if (pending.current) position.current = pending.current;
1790
+ };
1791
+ }, [place, position]);
1792
+ return /* @__PURE__ */ jsxs("button", {
1793
+ ref,
1794
+ type: "button",
1795
+ className: "studio-floating-launcher",
1796
+ "aria-label": "Open Povio UI configuration",
1797
+ title: "Open Povio UI · Drag to move",
1798
+ onClick: (event) => {
1799
+ if (dragged.current && event.detail !== 0) {
1800
+ dragged.current = false;
1801
+ return;
1802
+ }
1803
+ onOpen();
1804
+ },
1805
+ onPointerDown: (event_0) => {
1806
+ if (event_0.button !== 0) return;
1807
+ const rect = event_0.currentTarget.getBoundingClientRect();
1808
+ dragged.current = false;
1809
+ gesture.current = {
1810
+ x: event_0.clientX,
1811
+ y: event_0.clientY,
1812
+ left: rect.left,
1813
+ top: rect.top,
1814
+ pointerId: event_0.pointerId
1815
+ };
1816
+ event_0.currentTarget.setPointerCapture(event_0.pointerId);
1817
+ },
1818
+ onPointerMove: (event_1) => {
1819
+ const start = gesture.current;
1820
+ if (!start || start.pointerId !== event_1.pointerId) return;
1821
+ const x = event_1.clientX - start.x;
1822
+ const y = event_1.clientY - start.y;
1823
+ if (!dragged.current && Math.hypot(x, y) < 5) return;
1824
+ dragged.current = true;
1825
+ pending.current = {
1826
+ left: start.left + x,
1827
+ top: start.top + y
1828
+ };
1829
+ if (frame.current !== null) return;
1830
+ frame.current = requestAnimationFrame(() => {
1831
+ frame.current = null;
1832
+ if (pending.current) place(pending.current);
1833
+ });
1834
+ },
1835
+ onPointerUp: (event_2) => {
1836
+ if (gesture.current?.pointerId !== event_2.pointerId) return;
1837
+ finish();
1838
+ if (event_2.currentTarget.hasPointerCapture(event_2.pointerId)) event_2.currentTarget.releasePointerCapture(event_2.pointerId);
1839
+ },
1840
+ onPointerCancel: finish,
1841
+ onLostPointerCapture: finish,
1842
+ onKeyDown: (event_3) => {
1843
+ const move = {
1844
+ ArrowLeft: [-1, 0],
1845
+ ArrowRight: [1, 0],
1846
+ ArrowUp: [0, -1],
1847
+ ArrowDown: [0, 1]
1848
+ }[event_3.key];
1849
+ if (!move || !position.current) return;
1850
+ event_3.preventDefault();
1851
+ const step = event_3.shiftKey ? 40 : 10;
1852
+ place({
1853
+ left: position.current.left + move[0] * step,
1854
+ top: position.current.top + move[1] * step
1855
+ });
1856
+ },
1857
+ children: [
1858
+ /* @__PURE__ */ jsx(SlidersHorizontal, { size: 18 }),
1859
+ /* @__PURE__ */ jsx("span", { children: "Povio UI" }),
1860
+ /* @__PURE__ */ jsx(GripVertical, { size: 16 })
1861
+ ]
1862
+ });
1863
+ }
1864
+ //#endregion
1865
+ //#region src/configurator/useStudioPopout.ts
1866
+ const StudioPopoutContext = createContext(false);
1867
+ /** Keep the popup's styles current without copying scripts or starting a second app. */
1868
+ function mirrorStyles(source, target) {
1869
+ const base = target.createElement("base");
1870
+ base.href = source.baseURI;
1871
+ target.head.append(base);
1872
+ const copies = /* @__PURE__ */ new Map();
1873
+ const sync = () => {
1874
+ target.documentElement.className = source.documentElement.className;
1875
+ target.documentElement.style.cssText = source.documentElement.style.cssText;
1876
+ const originals = new Set(source.querySelectorAll("style, link[rel=\"stylesheet\"]"));
1877
+ for (const [original, copy] of copies) if (!originals.has(original)) {
1878
+ copy.remove();
1879
+ copies.delete(original);
1880
+ }
1881
+ for (const original of originals) {
1882
+ let copy = copies.get(original);
1883
+ if (!copy) {
1884
+ copy = original.cloneNode(true);
1885
+ copies.set(original, copy);
1886
+ target.head.append(copy);
1887
+ } else if (!copy.isEqualNode(original)) {
1888
+ const replacement = original.cloneNode(true);
1889
+ copy.replaceWith(replacement);
1890
+ copies.set(original, replacement);
1891
+ }
1892
+ }
1893
+ source.fonts.forEach((font) => target.fonts.add(font));
1894
+ };
1895
+ sync();
1896
+ const observer = new MutationObserver((records) => {
1897
+ if (records.some((record) => {
1898
+ const element = record.target.nodeType === 1 ? record.target : record.target.parentElement;
1899
+ return element === source.documentElement || element?.closest("style, link[rel=\"stylesheet\"]") || [...record.addedNodes, ...record.removedNodes].some((node) => node.nodeType === 1 && (node.matches("style, link[rel=\"stylesheet\"]") || node.querySelector("style, link[rel=\"stylesheet\"]")));
1900
+ })) sync();
1901
+ });
1902
+ observer.observe(source.documentElement, {
1903
+ childList: true,
1904
+ subtree: true,
1905
+ characterData: true,
1906
+ attributes: true,
1907
+ attributeFilter: [
1908
+ "class",
1909
+ "style",
1910
+ "href",
1911
+ "media",
1912
+ "disabled"
1913
+ ]
1914
+ });
1915
+ source.fonts.addEventListener("loadingdone", sync);
1916
+ return () => {
1917
+ observer.disconnect();
1918
+ source.fonts.removeEventListener("loadingdone", sync);
1919
+ };
1920
+ }
1921
+ function useStudioPopout(isOpen) {
1922
+ const $ = c(11);
1923
+ const geometry = useRef(null);
1924
+ const [popup, setPopup] = useState(null);
1925
+ const [blocked, setBlocked] = useState(false);
1926
+ let t0;
1927
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
1928
+ t0 = () => {
1929
+ const saved = geometry.current;
1930
+ const dimensions = saved ? `width=${saved.width},height=${saved.height},left=${saved.left},top=${saved.top}` : "width=1200,height=850";
1931
+ const child = window.open("", "_blank", `popup=yes,${dimensions},resizable=yes,scrollbars=yes`);
1932
+ if (!child) {
1933
+ setBlocked(true);
1934
+ return;
1935
+ }
1936
+ child.document.title = "Povio UI Configuration";
1937
+ child.document.documentElement.dataset.povioUiPopout = "";
1938
+ child.document.body.style.margin = "0";
1939
+ setBlocked(false);
1940
+ setPopup(child);
1941
+ child.focus();
1942
+ };
1943
+ $[0] = t0;
1944
+ } else t0 = $[0];
1945
+ const open = t0;
1946
+ let t1;
1947
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
1948
+ t1 = () => setPopup(null);
1949
+ $[1] = t1;
1950
+ } else t1 = $[1];
1951
+ const dock = t1;
1952
+ let t2;
1953
+ let t3;
1954
+ if ($[2] !== popup) {
1955
+ t2 = () => {
1956
+ if (!popup) return;
1957
+ const stopMirroring = mirrorStyles(document, popup.document);
1958
+ const remember = () => {
1959
+ if (!popup.closed && popup.innerWidth > 0 && popup.innerHeight > 0) geometry.current = {
1960
+ width: popup.innerWidth,
1961
+ height: popup.innerHeight,
1962
+ left: popup.screenX,
1963
+ top: popup.screenY
1964
+ };
1965
+ };
1966
+ const close = () => {
1967
+ remember();
1968
+ setPopup(null);
1969
+ };
1970
+ const closeWithHost = () => popup.close();
1971
+ popup.addEventListener("pagehide", close);
1972
+ popup.addEventListener("resize", remember);
1973
+ popup.addEventListener("blur", remember);
1974
+ window.addEventListener("pagehide", closeWithHost);
1975
+ return () => {
1976
+ remember();
1977
+ stopMirroring();
1978
+ popup.removeEventListener("pagehide", close);
1979
+ popup.removeEventListener("resize", remember);
1980
+ popup.removeEventListener("blur", remember);
1981
+ window.removeEventListener("pagehide", closeWithHost);
1982
+ if (!popup.closed) popup.close();
1983
+ };
1984
+ };
1985
+ t3 = [popup];
1986
+ $[2] = popup;
1987
+ $[3] = t2;
1988
+ $[4] = t3;
1989
+ } else {
1990
+ t2 = $[3];
1991
+ t3 = $[4];
1992
+ }
1993
+ useEffect(t2, t3);
1994
+ let t4;
1995
+ let t5;
1996
+ if ($[5] !== isOpen) {
1997
+ t4 = () => {
1998
+ if (!isOpen) setPopup(null);
1999
+ };
2000
+ t5 = [isOpen];
2001
+ $[5] = isOpen;
2002
+ $[6] = t4;
2003
+ $[7] = t5;
2004
+ } else {
2005
+ t4 = $[6];
2006
+ t5 = $[7];
2007
+ }
2008
+ useEffect(t4, t5);
2009
+ let t6;
2010
+ if ($[8] !== blocked || $[9] !== popup) {
2011
+ t6 = {
2012
+ popup,
2013
+ blocked,
2014
+ open,
2015
+ dock
2016
+ };
2017
+ $[8] = blocked;
2018
+ $[9] = popup;
2019
+ $[10] = t6;
2020
+ } else t6 = $[10];
2021
+ return t6;
2022
+ }
2023
+ //#endregion
2024
+ //#region src/configurator/useStudioWindow.ts
2025
+ const windowEdges = [
2026
+ "n",
2027
+ "e",
2028
+ "s",
2029
+ "w",
2030
+ "ne",
2031
+ "se",
2032
+ "sw",
2033
+ "nw"
2034
+ ];
2035
+ function constrain(bounds) {
2036
+ const margin = 8;
2037
+ const width = Math.min(Math.max(360, bounds.width), window.innerWidth - 16);
2038
+ const height = Math.min(Math.max(360, bounds.height), window.innerHeight - 16);
2039
+ return {
2040
+ width,
2041
+ height,
2042
+ left: Math.max(margin, Math.min(bounds.left, window.innerWidth - width - margin)),
2043
+ top: Math.max(margin, Math.min(bounds.top, window.innerHeight - height - margin))
2044
+ };
2045
+ }
2046
+ function writeBounds(element, bounds) {
2047
+ Object.assign(element.style, {
2048
+ position: "fixed",
2049
+ left: `${bounds.left}px`,
2050
+ top: `${bounds.top}px`,
2051
+ width: `${bounds.width}px`,
2052
+ height: `${bounds.height}px`,
2053
+ transform: "",
2054
+ willChange: ""
2055
+ });
2056
+ }
2057
+ function adjust(start, action, x, y) {
2058
+ if (action === "move") return constrain({
2059
+ ...start,
2060
+ left: start.left + x,
2061
+ top: start.top + y
2062
+ });
2063
+ const margin = 8;
2064
+ const minWidth = Math.min(360, window.innerWidth - 16);
2065
+ const minHeight = Math.min(360, window.innerHeight - 16);
2066
+ const clamp = (value, min, max) => Math.max(min, Math.min(max, value));
2067
+ let { left, top } = start;
2068
+ let right = left + start.width;
2069
+ let bottom = top + start.height;
2070
+ if (action.includes("w")) left = clamp(left + x, margin, right - minWidth);
2071
+ if (action.includes("e")) right = clamp(right + x, left + minWidth, window.innerWidth - margin);
2072
+ if (action.includes("n")) top = clamp(top + y, margin, bottom - minHeight);
2073
+ if (action.includes("s")) bottom = clamp(bottom + y, top + minHeight, window.innerHeight - margin);
2074
+ return {
2075
+ left,
2076
+ top,
2077
+ width: right - left,
2078
+ height: bottom - top
2079
+ };
2080
+ }
2081
+ function useStudioWindow(bounds, enabled = true) {
2082
+ const ref = useRef(null);
2083
+ const gesture = useRef(null);
2084
+ const frame = useRef(null);
2085
+ useLayoutEffect(() => {
2086
+ const element = ref.current;
2087
+ if (!enabled || !element) return;
2088
+ if (bounds.current) {
2089
+ bounds.current = constrain(bounds.current);
2090
+ writeBounds(element, bounds.current);
2091
+ }
2092
+ return () => {
2093
+ const rect = element.getBoundingClientRect();
2094
+ bounds.current = gesture.current?.latest ?? {
2095
+ left: rect.left,
2096
+ top: rect.top,
2097
+ width: rect.width,
2098
+ height: rect.height
2099
+ };
2100
+ };
2101
+ }, [bounds, enabled]);
2102
+ useEffect(() => {
2103
+ if (!enabled) return;
2104
+ const resize = () => {
2105
+ if (frame.current !== null) cancelAnimationFrame(frame.current);
2106
+ frame.current = null;
2107
+ const current = gesture.current?.latest ?? bounds.current;
2108
+ gesture.current = null;
2109
+ if (current && ref.current) {
2110
+ bounds.current = constrain(current);
2111
+ writeBounds(ref.current, bounds.current);
2112
+ }
2113
+ };
2114
+ window.addEventListener("resize", resize);
2115
+ return () => {
2116
+ window.removeEventListener("resize", resize);
2117
+ if (frame.current !== null) cancelAnimationFrame(frame.current);
2118
+ };
2119
+ }, [bounds, enabled]);
2120
+ function currentBounds() {
2121
+ const rect_0 = ref.current?.getBoundingClientRect();
2122
+ return rect_0 ? {
2123
+ left: rect_0.left,
2124
+ top: rect_0.top,
2125
+ width: rect_0.width,
2126
+ height: rect_0.height
2127
+ } : null;
2128
+ }
2129
+ function finish() {
2130
+ if (frame.current !== null) cancelAnimationFrame(frame.current);
2131
+ frame.current = null;
2132
+ const current_0 = gesture.current;
2133
+ gesture.current = null;
2134
+ if (!current_0 || !ref.current) return;
2135
+ bounds.current = current_0.latest;
2136
+ writeBounds(ref.current, current_0.latest);
2137
+ }
2138
+ function controls(action) {
2139
+ return {
2140
+ onPointerDown(event) {
2141
+ if (event.button !== 0 || gesture.current) return;
2142
+ const start = currentBounds();
2143
+ if (!start || !ref.current) return;
2144
+ event.preventDefault();
2145
+ event.currentTarget.focus({ preventScroll: true });
2146
+ event.currentTarget.setPointerCapture(event.pointerId);
2147
+ writeBounds(ref.current, start);
2148
+ if (action === "move") ref.current.style.willChange = "transform";
2149
+ gesture.current = {
2150
+ action,
2151
+ x: event.clientX,
2152
+ y: event.clientY,
2153
+ bounds: start,
2154
+ latest: start,
2155
+ pointerId: event.pointerId
2156
+ };
2157
+ },
2158
+ onPointerMove(event_0) {
2159
+ const start_0 = gesture.current;
2160
+ if (!start_0 || start_0.pointerId !== event_0.pointerId) return;
2161
+ start_0.latest = adjust(start_0.bounds, start_0.action, event_0.clientX - start_0.x, event_0.clientY - start_0.y);
2162
+ if (frame.current !== null) return;
2163
+ frame.current = requestAnimationFrame(() => {
2164
+ frame.current = null;
2165
+ const current_1 = gesture.current;
2166
+ if (!current_1 || !ref.current) return;
2167
+ if (current_1.action === "move") {
2168
+ const x = current_1.latest.left - current_1.bounds.left;
2169
+ const y = current_1.latest.top - current_1.bounds.top;
2170
+ ref.current.style.transform = `translate3d(${x}px, ${y}px, 0)`;
2171
+ } else writeBounds(ref.current, current_1.latest);
2172
+ });
2173
+ },
2174
+ onPointerUp(event_1) {
2175
+ if (gesture.current?.pointerId !== event_1.pointerId) return;
2176
+ finish();
2177
+ if (event_1.currentTarget.hasPointerCapture(event_1.pointerId)) event_1.currentTarget.releasePointerCapture(event_1.pointerId);
2178
+ },
2179
+ onLostPointerCapture: finish,
2180
+ onPointerCancel: finish,
2181
+ onKeyDown(event_2) {
2182
+ const direction = {
2183
+ ArrowLeft: [-1, 0],
2184
+ ArrowRight: [1, 0],
2185
+ ArrowUp: [0, -1],
2186
+ ArrowDown: [0, 1]
2187
+ }[event_2.key];
2188
+ if (!direction || gesture.current) return;
2189
+ event_2.preventDefault();
2190
+ const start_1 = currentBounds();
2191
+ const step = event_2.shiftKey ? 40 : 10;
2192
+ if (start_1 && ref.current) {
2193
+ bounds.current = adjust(start_1, action, direction[0] * step, direction[1] * step);
2194
+ writeBounds(ref.current, bounds.current);
2195
+ }
2196
+ }
2197
+ };
2198
+ }
2199
+ return {
2200
+ ref,
2201
+ move: controls("move"),
2202
+ resize: (edge) => controls(edge)
2203
+ };
2204
+ }
2205
+ //#endregion
614
2206
  //#region src/configurator/ContextualPreview.tsx
615
2207
  function CvaPreview(t0) {
616
2208
  const $ = c(84);
@@ -630,7 +2222,7 @@ function CvaPreview(t0) {
630
2222
  component = slot.split(".")[0];
631
2223
  const props = {
632
2224
  ...definition?.config.defaultVariants,
633
- ...Object.fromEntries(Object.entries(variants).filter(_temp$5).map(_temp2$2))
2225
+ ...Object.fromEntries(Object.entries(variants).filter(_temp$5).map(_temp2$3))
634
2226
  };
635
2227
  const classes = (key, t4) => {
636
2228
  const extra = t4 === void 0 ? {} : t4;
@@ -1395,7 +2987,7 @@ function _temp4$2(value_2) {
1395
2987
  function _temp3$2(event_1) {
1396
2988
  return event_1.preventDefault();
1397
2989
  }
1398
- function _temp2$2(t0) {
2990
+ function _temp2$3(t0) {
1399
2991
  const [name, value_0] = t0;
1400
2992
  return [name, value_0 === "true" ? true : value_0 === "false" ? false : value_0];
1401
2993
  }
@@ -1607,7 +3199,7 @@ function CvaEditor(t0) {
1607
3199
  let update;
1608
3200
  if ($[2] !== component || $[3] !== draft.overrides || $[4] !== inheritedOverrides || $[5] !== setDraft || $[6] !== setSlot || $[7] !== slot) {
1609
3201
  slots = Object.keys(cvaDefinitions);
1610
- const components = [...new Set(slots.map(_temp2$1))];
3202
+ const components = [...new Set(slots.map(_temp2$2))];
1611
3203
  let t10;
1612
3204
  if ($[20] !== inheritedOverrides || $[21] !== slot) {
1613
3205
  t10 = resolveCvaDefinition(slot, inheritedOverrides);
@@ -1911,7 +3503,7 @@ function _temp3$1(name) {
1911
3503
  children: title(name)
1912
3504
  }, name);
1913
3505
  }
1914
- function _temp2$1(key) {
3506
+ function _temp2$2(key) {
1915
3507
  return key.split(".")[0];
1916
3508
  }
1917
3509
  //#endregion
@@ -2153,8 +3745,9 @@ function scrollSelectedIntoView(list) {
2153
3745
  }
2154
3746
  /** Picks a base palette color for a semantic token, showing each option's swatch, step and hex value. */
2155
3747
  function PaletteSelect(t0) {
2156
- const $ = c(28);
3748
+ const $ = c(50);
2157
3749
  const { id, label, options, selected, onSelect } = t0;
3750
+ const poppedOut = use(StudioPopoutContext);
2158
3751
  let current;
2159
3752
  let t1;
2160
3753
  if ($[0] !== options || $[1] !== selected) {
@@ -2175,15 +3768,99 @@ function PaletteSelect(t0) {
2175
3768
  t1 = $[3];
2176
3769
  }
2177
3770
  const [, family, step] = t1;
3771
+ if (poppedOut) {
3772
+ const t2 = `studio-palette-picker studio-palette-native ${current ? "" : "is-custom"}`;
3773
+ let t3;
3774
+ if ($[6] !== current || $[7] !== family || $[8] !== step) {
3775
+ t3 = current && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
3776
+ className: "studio-palette-swatch",
3777
+ style: { backgroundColor: `rgb(${current.value})` }
3778
+ }), /* @__PURE__ */ jsxs("span", {
3779
+ className: "studio-palette-trigger-label",
3780
+ children: [
3781
+ family,
3782
+ " ",
3783
+ step
3784
+ ]
3785
+ })] });
3786
+ $[6] = current;
3787
+ $[7] = family;
3788
+ $[8] = step;
3789
+ $[9] = t3;
3790
+ } else t3 = $[9];
3791
+ let t4;
3792
+ if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
3793
+ t4 = /* @__PURE__ */ jsx(ChevronDown, { size: 13 });
3794
+ $[10] = t4;
3795
+ } else t4 = $[10];
3796
+ let t5;
3797
+ if ($[11] !== t3) {
3798
+ t5 = /* @__PURE__ */ jsxs("div", {
3799
+ className: "studio-palette-trigger",
3800
+ "aria-hidden": "true",
3801
+ children: [t3, t4]
3802
+ });
3803
+ $[11] = t3;
3804
+ $[12] = t5;
3805
+ } else t5 = $[12];
3806
+ let t6;
3807
+ if ($[13] !== onSelect) {
3808
+ t6 = (event) => onSelect(event.target.value);
3809
+ $[13] = onSelect;
3810
+ $[14] = t6;
3811
+ } else t6 = $[14];
3812
+ let t7;
3813
+ if ($[15] !== options) {
3814
+ t7 = paletteFamilies(options).map(_temp$2);
3815
+ $[15] = options;
3816
+ $[16] = t7;
3817
+ } else t7 = $[16];
3818
+ let t8;
3819
+ if ($[17] === Symbol.for("react.memo_cache_sentinel")) {
3820
+ t8 = /* @__PURE__ */ jsx("option", {
3821
+ value: customPaletteKey,
3822
+ children: "Custom value…"
3823
+ });
3824
+ $[17] = t8;
3825
+ } else t8 = $[17];
3826
+ let t9;
3827
+ if ($[18] !== id || $[19] !== label || $[20] !== selected || $[21] !== t6 || $[22] !== t7) {
3828
+ t9 = /* @__PURE__ */ jsxs("select", {
3829
+ id,
3830
+ "aria-label": label,
3831
+ value: selected,
3832
+ onChange: t6,
3833
+ children: [t7, t8]
3834
+ });
3835
+ $[18] = id;
3836
+ $[19] = label;
3837
+ $[20] = selected;
3838
+ $[21] = t6;
3839
+ $[22] = t7;
3840
+ $[23] = t9;
3841
+ } else t9 = $[23];
3842
+ let t10;
3843
+ if ($[24] !== t2 || $[25] !== t5 || $[26] !== t9) {
3844
+ t10 = /* @__PURE__ */ jsxs("div", {
3845
+ className: t2,
3846
+ children: [t5, t9]
3847
+ });
3848
+ $[24] = t2;
3849
+ $[25] = t5;
3850
+ $[26] = t9;
3851
+ $[27] = t10;
3852
+ } else t10 = $[27];
3853
+ return t10;
3854
+ }
2178
3855
  const t2 = `studio-palette-picker ${current ? "" : "is-custom"}`;
2179
3856
  let t3;
2180
- if ($[6] !== onSelect) {
3857
+ if ($[28] !== onSelect) {
2181
3858
  t3 = (key) => key !== null && onSelect(String(key));
2182
- $[6] = onSelect;
2183
- $[7] = t3;
2184
- } else t3 = $[7];
3859
+ $[28] = onSelect;
3860
+ $[29] = t3;
3861
+ } else t3 = $[29];
2185
3862
  let t4;
2186
- if ($[8] !== current || $[9] !== family || $[10] !== step) {
3863
+ if ($[30] !== current || $[31] !== family || $[32] !== step) {
2187
3864
  t4 = current && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
2188
3865
  className: "studio-palette-swatch",
2189
3866
  style: { backgroundColor: `rgb(${current.value})` },
@@ -2196,36 +3873,36 @@ function PaletteSelect(t0) {
2196
3873
  step
2197
3874
  ]
2198
3875
  })] });
2199
- $[8] = current;
2200
- $[9] = family;
2201
- $[10] = step;
2202
- $[11] = t4;
2203
- } else t4 = $[11];
3876
+ $[30] = current;
3877
+ $[31] = family;
3878
+ $[32] = step;
3879
+ $[33] = t4;
3880
+ } else t4 = $[33];
2204
3881
  let t5;
2205
- if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
3882
+ if ($[34] === Symbol.for("react.memo_cache_sentinel")) {
2206
3883
  t5 = /* @__PURE__ */ jsx(ChevronDown, {
2207
3884
  size: 13,
2208
3885
  "aria-hidden": "true"
2209
3886
  });
2210
- $[12] = t5;
2211
- } else t5 = $[12];
3887
+ $[34] = t5;
3888
+ } else t5 = $[34];
2212
3889
  let t6;
2213
- if ($[13] !== t4) {
3890
+ if ($[35] !== t4) {
2214
3891
  t6 = /* @__PURE__ */ jsxs($7705c033048f6da7$export$353f5b6fc5456de1, {
2215
3892
  className: "studio-palette-trigger",
2216
3893
  children: [t4, t5]
2217
3894
  });
2218
- $[13] = t4;
2219
- $[14] = t6;
2220
- } else t6 = $[14];
3895
+ $[35] = t4;
3896
+ $[36] = t6;
3897
+ } else t6 = $[36];
2221
3898
  let t7;
2222
- if ($[15] !== options) {
2223
- t7 = paletteFamilies(options).map(_temp$2);
2224
- $[15] = options;
2225
- $[16] = t7;
2226
- } else t7 = $[16];
3899
+ if ($[37] !== options) {
3900
+ t7 = paletteFamilies(options).map(_temp2$1);
3901
+ $[37] = options;
3902
+ $[38] = t7;
3903
+ } else t7 = $[38];
2227
3904
  let t8;
2228
- if ($[17] === Symbol.for("react.memo_cache_sentinel")) {
3905
+ if ($[39] === Symbol.for("react.memo_cache_sentinel")) {
2229
3906
  t8 = /* @__PURE__ */ jsx($928221da08ecbc62$export$dca12b0bb56e4fc, {
2230
3907
  id: "other",
2231
3908
  children: /* @__PURE__ */ jsx($928221da08ecbc62$export$a11e76429ed99b4, {
@@ -2234,10 +3911,10 @@ function PaletteSelect(t0) {
2234
3911
  children: "Custom value…"
2235
3912
  })
2236
3913
  });
2237
- $[17] = t8;
2238
- } else t8 = $[17];
3914
+ $[39] = t8;
3915
+ } else t8 = $[39];
2239
3916
  let t9;
2240
- if ($[18] !== t7) {
3917
+ if ($[40] !== t7) {
2241
3918
  t9 = /* @__PURE__ */ jsx($542a13ca2fa5b484$export$5b6b19405a83ff9d, {
2242
3919
  className: "studio-palette-popover",
2243
3920
  placement: "bottom end",
@@ -2247,11 +3924,11 @@ function PaletteSelect(t0) {
2247
3924
  children: [t7, t8]
2248
3925
  })
2249
3926
  });
2250
- $[18] = t7;
2251
- $[19] = t9;
2252
- } else t9 = $[19];
3927
+ $[40] = t7;
3928
+ $[41] = t9;
3929
+ } else t9 = $[41];
2253
3930
  let t10;
2254
- if ($[20] !== id || $[21] !== label || $[22] !== selected || $[23] !== t2 || $[24] !== t3 || $[25] !== t6 || $[26] !== t9) {
3931
+ if ($[42] !== id || $[43] !== label || $[44] !== selected || $[45] !== t2 || $[46] !== t3 || $[47] !== t6 || $[48] !== t9) {
2255
3932
  t10 = /* @__PURE__ */ jsxs($c8bb816105474884$export$ef9b1a59e592288f, {
2256
3933
  id,
2257
3934
  "aria-label": label,
@@ -2260,39 +3937,56 @@ function PaletteSelect(t0) {
2260
3937
  onSelectionChange: t3,
2261
3938
  children: [t6, t9]
2262
3939
  });
2263
- $[20] = id;
2264
- $[21] = label;
2265
- $[22] = selected;
2266
- $[23] = t2;
2267
- $[24] = t3;
2268
- $[25] = t6;
2269
- $[26] = t9;
2270
- $[27] = t10;
2271
- } else t10 = $[27];
3940
+ $[42] = id;
3941
+ $[43] = label;
3942
+ $[44] = selected;
3943
+ $[45] = t2;
3944
+ $[46] = t3;
3945
+ $[47] = t6;
3946
+ $[48] = t9;
3947
+ $[49] = t10;
3948
+ } else t10 = $[49];
2272
3949
  return t10;
2273
3950
  }
2274
- function _temp$2(t0) {
2275
- const { family: name, steps } = t0;
3951
+ function _temp2$1(t0) {
3952
+ const { family: name_0, steps: steps_0 } = t0;
2276
3953
  return /* @__PURE__ */ jsxs($928221da08ecbc62$export$dca12b0bb56e4fc, {
2277
- id: name,
2278
- children: [/* @__PURE__ */ jsxs($53e61d82d8b8611d$export$8b251419efc915eb, { children: ["Base palette / ", name] }), steps.map((t1) => {
2279
- const { step: value, option: option_0 } = t1;
3954
+ id: name_0,
3955
+ children: [/* @__PURE__ */ jsxs($53e61d82d8b8611d$export$8b251419efc915eb, { children: ["Base palette / ", name_0] }), steps_0.map((t1) => {
3956
+ const { step: value_0, option: option_1 } = t1;
2280
3957
  return /* @__PURE__ */ jsxs($928221da08ecbc62$export$a11e76429ed99b4, {
2281
- id: option_0.name,
2282
- textValue: `${name} ${value}`,
2283
- "aria-label": `${name} ${value}`,
3958
+ id: option_1.name,
3959
+ textValue: `${name_0} ${value_0}`,
3960
+ "aria-label": `${name_0} ${value_0}`,
2284
3961
  className: "studio-palette-item",
2285
3962
  children: [
2286
3963
  /* @__PURE__ */ jsx("span", {
2287
3964
  className: "studio-palette-swatch",
2288
- style: { backgroundColor: `rgb(${option_0.value})` },
3965
+ style: { backgroundColor: `rgb(${option_1.value})` },
2289
3966
  "aria-hidden": "true"
2290
3967
  }),
2291
- /* @__PURE__ */ jsx("span", { children: value }),
2292
- /* @__PURE__ */ jsx("code", { children: toHex(option_0.value).toUpperCase() })
3968
+ /* @__PURE__ */ jsx("span", { children: value_0 }),
3969
+ /* @__PURE__ */ jsx("code", { children: toHex(option_1.value).toUpperCase() })
2293
3970
  ]
2294
- }, option_0.name);
3971
+ }, option_1.name);
2295
3972
  })]
3973
+ }, name_0);
3974
+ }
3975
+ function _temp$2(t0) {
3976
+ const { family: name, steps } = t0;
3977
+ return /* @__PURE__ */ jsx("optgroup", {
3978
+ label: `Base palette / ${name}`,
3979
+ children: steps.map((t1) => {
3980
+ const { step: value, option: option_0 } = t1;
3981
+ return /* @__PURE__ */ jsxs("option", {
3982
+ value: option_0.name,
3983
+ children: [
3984
+ name,
3985
+ " ",
3986
+ value
3987
+ ]
3988
+ }, option_0.name);
3989
+ })
2296
3990
  }, name);
2297
3991
  }
2298
3992
  //#endregion
@@ -3402,7 +5096,7 @@ function groupKeyFor(section, name, defaults) {
3402
5096
  const textStyle = section === "Typography" ? name.match(/^--text-(.+?)(?:--.+)?$/)?.[1] : void 0;
3403
5097
  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";
3404
5098
  }
3405
- const ComponentGallery = lazy(() => import("../ComponentGallery-BWiPGUL8.js"));
5099
+ const ComponentGallery = lazy(() => import("../ComponentGallery-Dp0kZVZM.js"));
3406
5100
  function ComponentPreview(t0) {
3407
5101
  const $ = c(14);
3408
5102
  const { value, mode, inspector } = t0;
@@ -3646,7 +5340,34 @@ function TokenField({ name, value, original, changed, onChange, onReset, onValid
3646
5340
  ]
3647
5341
  });
3648
5342
  }
3649
- function ConfigurationModalContent({ memory }) {
5343
+ function PopoutOverlay(t0) {
5344
+ const $ = c(2);
5345
+ const { children } = t0;
5346
+ let t1;
5347
+ if ($[0] !== children) {
5348
+ t1 = /* @__PURE__ */ jsx("div", {
5349
+ className: "studio-overlay",
5350
+ children
5351
+ });
5352
+ $[0] = children;
5353
+ $[1] = t1;
5354
+ } else t1 = $[1];
5355
+ return t1;
5356
+ }
5357
+ function ConfigurationModalContent({ memory, windowBounds, poppedOut, onPopout, onDock, onMinimize, popupBlocked }) {
5358
+ const Overlay = poppedOut ? PopoutOverlay : $8b8d26808cb8cb53$export$8948f78d83984c69;
5359
+ const Surface = poppedOut ? "div" : $8b8d26808cb8cb53$export$2b77a92f1a5ad772;
5360
+ const studioWindow = useStudioWindow(windowBounds, !poppedOut);
5361
+ const [compactPreview, setCompactPreview] = useState(false);
5362
+ useEffect(() => {
5363
+ const modal = studioWindow.ref.current;
5364
+ if (!modal) return;
5365
+ const observer = new ResizeObserver(([entry]) => {
5366
+ if (entry && entry.contentRect.width > 800) setCompactPreview(false);
5367
+ });
5368
+ observer.observe(modal);
5369
+ return () => observer.disconnect();
5370
+ }, [studioWindow.ref]);
3650
5371
  const inherited = UIConfig.useConfig();
3651
5372
  const { defaults, draft, setDraft, isOpen, cancel, apply, revision } = useUIConfiguration();
3652
5373
  const remembered = memory.current;
@@ -3665,7 +5386,15 @@ function ConfigurationModalContent({ memory }) {
3665
5386
  const [expandedGroups, setExpandedGroups] = useState(remembered.expandedGroups ?? {});
3666
5387
  const [sectionTabs, setSectionTabs] = useState(remembered.sectionTabs ?? {});
3667
5388
  const [resetRevision, setResetRevision] = useState(0);
3668
- const [invalidFields, setInvalidFields] = useState({});
5389
+ const [invalidFields, setInvalidFields] = useState(remembered.invalidRevision === revision ? remembered.invalidFields ?? {} : {});
5390
+ useLayoutEffect(() => {
5391
+ memory.current.invalidRevision = revision;
5392
+ memory.current.invalidFields = invalidFields;
5393
+ }, [
5394
+ memory,
5395
+ revision,
5396
+ invalidFields
5397
+ ]);
3669
5398
  const [message, setMessage] = useState("");
3670
5399
  const [themeWriter, setThemeWriter] = useState(null);
3671
5400
  const [savingTheme, setSavingTheme] = useState(false);
@@ -3702,7 +5431,7 @@ function ConfigurationModalContent({ memory }) {
3702
5431
  useLayoutEffect(() => {
3703
5432
  const frame = requestAnimationFrame(() => {
3704
5433
  editorRef.current?.scrollTo({ top: memory.current.editorScroll ?? 0 });
3705
- previewRef.current?.scrollTo({ top: memory.current.previewScroll ?? 0 });
5434
+ previewRef.current?.querySelector(".studio-inspector-canvas")?.scrollTo({ top: memory.current.previewScroll ?? 0 });
3706
5435
  });
3707
5436
  return () => cancelAnimationFrame(frame);
3708
5437
  }, [memory]);
@@ -3711,6 +5440,8 @@ function ConfigurationModalContent({ memory }) {
3711
5440
  const config = inherited;
3712
5441
  const exportText = exportTab === "css" ? exportCss(draft.theme, defaults) : exportTab === "overrides" ? exportCvaEdits(draft.overrides) : `import { UIConfig } from "@povio/ui/ui-config";\n\nconst config = ${JSON.stringify(draft.config, null, 2)} satisfies Partial<UIConfig.Options>;\n\n// Wrap your application:\n// <UIConfig.Provider config={config}>{children}</UIConfig.Provider>\n`;
3713
5442
  const changeSection = (next) => {
5443
+ if (compactPreview && bodyRef.current?.parentElement) bodyRef.current.parentElement.scrollTop = 0;
5444
+ setCompactPreview(false);
3714
5445
  if (isLayoutKind(next)) setSectionTabs((current) => ({
3715
5446
  ...current,
3716
5447
  Layout: next
@@ -3738,6 +5469,7 @@ function ConfigurationModalContent({ memory }) {
3738
5469
  ]);
3739
5470
  /** Opens the editor on a token picked in the inspector: its section, its group, scrolled into view and highlighted. */
3740
5471
  const focusToken = useCallback((picked) => {
5472
+ setCompactPreview(false);
3741
5473
  const name_1 = listedLayoutToken(picked, defaults);
3742
5474
  const next_0 = sectionFor(name_1);
3743
5475
  if (isLayoutKind(next_0)) setSectionTabs((current_1) => ({
@@ -3765,7 +5497,7 @@ function ConfigurationModalContent({ memory }) {
3765
5497
  useEffect(() => {
3766
5498
  if (!highlightedToken) return;
3767
5499
  const frame_0 = requestAnimationFrame(() => {
3768
- (document.getElementById(`token-${highlightedToken}`)?.closest(".studio-token"))?.scrollIntoView({
5500
+ (editorRef.current?.ownerDocument.getElementById(`token-${highlightedToken}`)?.closest(".studio-token"))?.scrollIntoView({
3769
5501
  block: "center",
3770
5502
  behavior: "smooth"
3771
5503
  });
@@ -3858,8 +5590,8 @@ function ConfigurationModalContent({ memory }) {
3858
5590
  ...defaults.theme
3859
5591
  }).filter(([name_9]) => (section === "Font size" ? isFontSizeToken(name_9) : section === "Spacing" || section === "Sizing" ? layoutKindFor(name_9) === section && listedLayoutToken(name_9, defaults) === name_9 : groupFor(name_9) === section) && !name_9.startsWith("--color-"));
3860
5592
  const groupedEntries = /* @__PURE__ */ new Map();
3861
- for (const entry of sectionEntries) {
3862
- const [name_10] = entry;
5593
+ for (const entry_0 of sectionEntries) {
5594
+ const [name_10] = entry_0;
3863
5595
  const textStyle = section === "Typography" ? name_10.match(/^--text-(.+?)(?:--.+)?$/)?.[1] : void 0;
3864
5596
  const key_1 = groupKeyFor(section, name_10, defaults);
3865
5597
  if (!groupedEntries.has(key_1)) groupedEntries.set(key_1, {
@@ -3867,7 +5599,7 @@ function ConfigurationModalContent({ memory }) {
3867
5599
  compact: !!textStyle,
3868
5600
  entries: []
3869
5601
  });
3870
- groupedEntries.get(key_1).entries.push(entry);
5602
+ groupedEntries.get(key_1).entries.push(entry_0);
3871
5603
  }
3872
5604
  const paletteStep = (name_11) => Number(name_11.match(/-(\d+)-base$/)?.[1]);
3873
5605
  const isPaletteGroup = (entries) => entries.every(([name_12]) => palette.has(name_12));
@@ -3959,7 +5691,7 @@ function ConfigurationModalContent({ memory }) {
3959
5691
  const renderFontFamilies = (entries_2) => {
3960
5692
  const isFamily = ([name_22, value_10]) => value_10.includes(`var(${name_22}-base)`);
3961
5693
  const families = entries_2.filter(isFamily);
3962
- const roles = entries_2.filter((entry_0) => !isFamily(entry_0));
5694
+ const roles = entries_2.filter((entry_1) => !isFamily(entry_1));
3963
5695
  const themeFonts = families.map(([name_23]) => ({
3964
5696
  name: name_23,
3965
5697
  label: familyName(name_23.replace(/^--font-/, "")),
@@ -3990,7 +5722,7 @@ function ConfigurationModalContent({ memory }) {
3990
5722
  }, `${revision}-${resetRevision}-${name_24}`))
3991
5723
  }),
3992
5724
  /* @__PURE__ */ jsx(FontUpload, { onUpload: refreshLoadedFonts }),
3993
- !!families.length && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("hr", { className: "studio-font-divider" }), families.map((entry_1) => renderToken(entry_1))] })
5725
+ !!families.length && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("hr", { className: "studio-font-divider" }), families.map((entry_2) => renderToken(entry_2))] })
3994
5726
  ]
3995
5727
  }, "font-families");
3996
5728
  };
@@ -4014,17 +5746,19 @@ function ConfigurationModalContent({ memory }) {
4014
5746
  children: options_0.map((option) => /* @__PURE__ */ jsx("option", { children: option }, option))
4015
5747
  })]
4016
5748
  }, `${key_11}-${field_1}`);
4017
- return /* @__PURE__ */ jsx($8b8d26808cb8cb53$export$8948f78d83984c69, {
5749
+ return /* @__PURE__ */ jsx(Overlay, {
4018
5750
  className: "studio-overlay",
4019
5751
  isOpen,
4020
5752
  onOpenChange: (next_2) => {
4021
5753
  if (!next_2) cancel();
4022
5754
  },
4023
5755
  isDismissable: false,
4024
- children: /* @__PURE__ */ jsx($8b8d26808cb8cb53$export$2b77a92f1a5ad772, {
4025
- className: "studio-modal",
5756
+ children: /* @__PURE__ */ jsx(Surface, {
5757
+ className: `studio-modal${poppedOut ? " studio-modal-popout" : ""}`,
5758
+ ref: studioWindow.ref,
4026
5759
  children: /* @__PURE__ */ jsxs($f2ff30fde7b014be$export$3ddf2d174ce01153, {
4027
5760
  className: "studio-dialog",
5761
+ "data-compact-preview": compactPreview || void 0,
4028
5762
  style: { "--studio-editor-track": editorWidth ? `minmax(260px, ${editorWidth}px)` : void 0 },
4029
5763
  children: [
4030
5764
  /* @__PURE__ */ jsxs("header", {
@@ -4040,22 +5774,35 @@ function ConfigurationModalContent({ memory }) {
4040
5774
  /* @__PURE__ */ jsxs("nav", {
4041
5775
  className: "studio-nav",
4042
5776
  "aria-label": "Configuration sections",
4043
- children: [
4044
- navSections.map((group_3) => /* @__PURE__ */ jsx("button", {
4045
- "aria-current": (group_3 === "Layout" ? isLayoutKind(section) : section === group_3) ? "page" : void 0,
4046
- onClick: () => changeSection(group_3 === "Layout" ? lastLayoutSection : group_3),
4047
- children: group_3
4048
- }, group_3)),
4049
- /* @__PURE__ */ jsx("span", {
4050
- className: "studio-nav-divider",
4051
- "aria-hidden": "true"
4052
- }),
4053
- /* @__PURE__ */ jsx("button", {
4054
- "aria-current": advancedSection ? "page" : void 0,
4055
- onClick: () => changeSection(isAdvancedSection(sectionTabs.Advanced ?? "") ? sectionTabs.Advanced : advancedSections[0][0]),
4056
- children: "Advanced"
4057
- })
4058
- ]
5777
+ children: [/* @__PURE__ */ jsxs("div", {
5778
+ className: "studio-section-tabs",
5779
+ children: [
5780
+ navSections.map((group_3) => /* @__PURE__ */ jsx("button", {
5781
+ "aria-current": !compactPreview && (group_3 === "Layout" ? isLayoutKind(section) : section === group_3) ? "page" : void 0,
5782
+ onClick: () => changeSection(group_3 === "Layout" ? lastLayoutSection : group_3),
5783
+ children: group_3
5784
+ }, group_3)),
5785
+ /* @__PURE__ */ jsx("span", {
5786
+ className: "studio-nav-divider",
5787
+ "aria-hidden": "true"
5788
+ }),
5789
+ /* @__PURE__ */ jsx("button", {
5790
+ "aria-current": !compactPreview && advancedSection ? "page" : void 0,
5791
+ onClick: () => changeSection(isAdvancedSection(sectionTabs.Advanced ?? "") ? sectionTabs.Advanced : advancedSections[0][0]),
5792
+ children: "Advanced"
5793
+ })
5794
+ ]
5795
+ }), /* @__PURE__ */ jsx("button", {
5796
+ type: "button",
5797
+ className: "studio-preview-tab",
5798
+ "aria-current": compactPreview ? "page" : void 0,
5799
+ onClick: () => {
5800
+ setCompactPreview(true);
5801
+ const dialog = bodyRef.current?.parentElement;
5802
+ if (dialog) dialog.scrollTop = 0;
5803
+ },
5804
+ children: "Live preview"
5805
+ })]
4059
5806
  }),
4060
5807
  /* @__PURE__ */ jsx("div", {
4061
5808
  className: "studio-topbar-controls",
@@ -4185,9 +5932,9 @@ function ConfigurationModalContent({ memory }) {
4185
5932
  id: `group-${section}-${key_14.replaceAll(" ", "-")}`,
4186
5933
  hidden: !isExpanded(key_14),
4187
5934
  className: group_5.compact ? "studio-type-fields" : void 0,
4188
- children: [section === "Colors" && isPaletteGroup(group_5.entries) && renderPaletteShades(group_5.title, group_5.entries), group_5.entries.map((entry_2) => renderToken(entry_2, group_5.compact))]
5935
+ 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))]
4189
5936
  })]
4190
- }, key_14) : section === "Typography" && key_14 === "Font families" ? renderFontFamilies(group_5.entries) : group_5.entries.map((entry_3) => renderToken(entry_3))), !orderedGroups.length && /* @__PURE__ */ jsx("p", { children: "No matching tokens. Try a component name such as “button”." })]
5937
+ }, 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”." })]
4191
5938
  })] }),
4192
5939
  section === "Variants & overrides" && /* @__PURE__ */ jsx(CvaEditor, {
4193
5940
  slot: cvaSlot,
@@ -4426,26 +6173,34 @@ function ConfigurationModalContent({ memory }) {
4426
6173
  })]
4427
6174
  })]
4428
6175
  }),
4429
- section === "Variants & overrides" || isTokenSection(section) && previewMode === "focused" ? /* @__PURE__ */ jsx(ContextualPreview, {
4430
- variants: cvaVariants,
4431
- setVariants: setCvaVariants,
4432
- section,
4433
- slot: cvaSlot,
4434
- mode,
4435
- entries: visibleGroups.flatMap(([, group_6]) => group_6.entries)
4436
- }) : /* @__PURE__ */ jsx(ComponentPreview, {
4437
- value: draft,
4438
- mode,
4439
- inspector: {
4440
- isKnown: isInspectable,
4441
- describe: describeToken,
4442
- onSelect: focusToken,
4443
- revision: draft
4444
- }
6176
+ /* @__PURE__ */ jsx(PreviewInspector, {
6177
+ revision: draft,
6178
+ isKnown: isInspectable,
6179
+ onSelect: focusToken,
6180
+ onScroll: (scrollTop) => {
6181
+ memory.current.previewScroll = scrollTop;
6182
+ },
6183
+ children: section === "Variants & overrides" || isTokenSection(section) && previewMode === "focused" ? /* @__PURE__ */ jsx(ContextualPreview, {
6184
+ variants: cvaVariants,
6185
+ setVariants: setCvaVariants,
6186
+ section,
6187
+ slot: cvaSlot,
6188
+ mode,
6189
+ entries: visibleGroups.flatMap(([, group_6]) => group_6.entries)
6190
+ }) : /* @__PURE__ */ jsx(ComponentPreview, {
6191
+ value: draft,
6192
+ mode,
6193
+ inspector: {
6194
+ isKnown: isInspectable,
6195
+ describe: describeToken,
6196
+ onSelect: focusToken,
6197
+ revision: draft
6198
+ }
6199
+ })
4445
6200
  }),
4446
6201
  /* @__PURE__ */ jsx("p", {
4447
6202
  className: "studio-preview-note",
4448
- children: section === "Variants & overrides" || previewMode === "focused" ? "Preview follows the current section. Variant controls affect only the preview." : "Click a component to inspect its padding, gaps and radius."
6203
+ 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."
4449
6204
  })
4450
6205
  ]
4451
6206
  }),
@@ -4473,7 +6228,7 @@ function ConfigurationModalContent({ memory }) {
4473
6228
  }),
4474
6229
  /* @__PURE__ */ jsx("span", {
4475
6230
  role: "status",
4476
- children: Object.keys(invalidFields).length ? "Fix invalid values or reset before applying or exporting." : nothingToReset && !changedCount ? "No active changes to reset." : message || `${changedCount} overrides · Changes stay in this session`
6231
+ 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`
4477
6232
  }),
4478
6233
  /* @__PURE__ */ jsx("button", {
4479
6234
  onClick: () => cancel(),
@@ -4489,6 +6244,36 @@ function ConfigurationModalContent({ memory }) {
4489
6244
  })
4490
6245
  ]
4491
6246
  }),
6247
+ /* @__PURE__ */ jsx("button", {
6248
+ type: "button",
6249
+ className: "studio-window-minimize",
6250
+ "aria-label": "Minimize UI configuration",
6251
+ title: "Minimize to floating button",
6252
+ onClick: onMinimize,
6253
+ children: /* @__PURE__ */ jsx(Minus, { size: 17 })
6254
+ }),
6255
+ /* @__PURE__ */ jsx("button", {
6256
+ type: "button",
6257
+ className: "studio-window-popout",
6258
+ "aria-label": poppedOut ? "Dock configuration back in page" : "Pop out UI configuration",
6259
+ title: poppedOut ? "Dock back in page" : "Open in a separate window",
6260
+ onClick: poppedOut ? onDock : onPopout,
6261
+ children: poppedOut ? /* @__PURE__ */ jsx(PanelTop, { size: 17 }) : /* @__PURE__ */ jsx(ExternalLink, { size: 17 })
6262
+ }),
6263
+ !poppedOut && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("button", {
6264
+ type: "button",
6265
+ className: "studio-window-grip",
6266
+ "aria-label": "Move UI configuration",
6267
+ title: "Drag to move, or use arrow keys",
6268
+ ...studioWindow.move,
6269
+ children: /* @__PURE__ */ jsx(GripVertical, { size: 20 })
6270
+ }), windowEdges.map((edge) => /* @__PURE__ */ jsx("button", {
6271
+ type: "button",
6272
+ className: `studio-window-resize studio-window-resize-${edge}`,
6273
+ "aria-label": `Resize UI configuration ${edge}`,
6274
+ title: "Drag to resize, or use arrow keys",
6275
+ ...studioWindow.resize(edge)
6276
+ }, edge))] }),
4492
6277
  /* @__PURE__ */ jsx($8b8d26808cb8cb53$export$8948f78d83984c69, {
4493
6278
  className: "studio-overlay studio-confirm-overlay",
4494
6279
  isOpen: confirmingReset,
@@ -4534,22 +6319,113 @@ function ConfigurationModalContent({ memory }) {
4534
6319
  });
4535
6320
  }
4536
6321
  function UIConfigurationModal() {
4537
- const $ = c(4);
4538
- const { isOpen, revision } = useUIConfiguration();
6322
+ const $ = c(22);
6323
+ const { isOpen, revision, open } = useUIConfiguration();
6324
+ const [minimized, setMinimized] = useState(false);
6325
+ const [hasLauncher, setHasLauncher] = useState(false);
6326
+ const restorePopout = useRef(false);
6327
+ const launcherPosition = useRef(null);
4539
6328
  let t0;
4540
6329
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
4541
- t0 = {};
6330
+ t0 = () => setMinimized(false);
4542
6331
  $[0] = t0;
4543
6332
  } else t0 = $[0];
4544
- const memory = useRef(t0);
4545
6333
  let t1;
4546
- if ($[1] !== isOpen || $[2] !== revision) {
4547
- t1 = isOpen ? /* @__PURE__ */ jsx(ConfigurationModalContent, { memory }, revision) : null;
4548
- $[1] = isOpen;
4549
- $[2] = revision;
4550
- $[3] = t1;
4551
- } else t1 = $[3];
4552
- return t1;
6334
+ if ($[1] !== revision) {
6335
+ t1 = [revision];
6336
+ $[1] = revision;
6337
+ $[2] = t1;
6338
+ } else t1 = $[2];
6339
+ useEffect(t0, t1);
6340
+ let t2;
6341
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
6342
+ t2 = {};
6343
+ $[3] = t2;
6344
+ } else t2 = $[3];
6345
+ const memory = useRef(t2);
6346
+ const windowBounds = useRef(null);
6347
+ const popout = useStudioPopout(isOpen && !minimized);
6348
+ if ((!isOpen || minimized) && hasLauncher) {
6349
+ let t3;
6350
+ if ($[4] !== isOpen || $[5] !== open || $[6] !== popout) {
6351
+ t3 = createPortal(/* @__PURE__ */ jsx(ConfigurationLauncher, {
6352
+ position: launcherPosition,
6353
+ onOpen: () => {
6354
+ setMinimized(false);
6355
+ if (!isOpen) open();
6356
+ if (restorePopout.current) popout.open();
6357
+ }
6358
+ }), document.body);
6359
+ $[4] = isOpen;
6360
+ $[5] = open;
6361
+ $[6] = popout;
6362
+ $[7] = t3;
6363
+ } else t3 = $[7];
6364
+ return t3;
6365
+ }
6366
+ if (!isOpen) return null;
6367
+ const t3 = !!popout.popup;
6368
+ let t4;
6369
+ let t5;
6370
+ let t6;
6371
+ if ($[8] !== popout) {
6372
+ t4 = () => {
6373
+ restorePopout.current = true;
6374
+ popout.open();
6375
+ };
6376
+ t5 = () => {
6377
+ restorePopout.current = false;
6378
+ popout.dock();
6379
+ };
6380
+ t6 = () => {
6381
+ restorePopout.current = !!popout.popup;
6382
+ setHasLauncher(true);
6383
+ setMinimized(true);
6384
+ popout.dock();
6385
+ };
6386
+ $[8] = popout;
6387
+ $[9] = t4;
6388
+ $[10] = t5;
6389
+ $[11] = t6;
6390
+ } else {
6391
+ t4 = $[9];
6392
+ t5 = $[10];
6393
+ t6 = $[11];
6394
+ }
6395
+ let t7;
6396
+ if ($[12] !== popout.blocked || $[13] !== revision || $[14] !== t3 || $[15] !== t4 || $[16] !== t5 || $[17] !== t6) {
6397
+ t7 = /* @__PURE__ */ jsx(ConfigurationModalContent, {
6398
+ memory,
6399
+ windowBounds,
6400
+ poppedOut: t3,
6401
+ onPopout: t4,
6402
+ onDock: t5,
6403
+ onMinimize: t6,
6404
+ popupBlocked: popout.blocked
6405
+ }, revision);
6406
+ $[12] = popout.blocked;
6407
+ $[13] = revision;
6408
+ $[14] = t3;
6409
+ $[15] = t4;
6410
+ $[16] = t5;
6411
+ $[17] = t6;
6412
+ $[18] = t7;
6413
+ } else t7 = $[18];
6414
+ const content = t7;
6415
+ let t8;
6416
+ if ($[19] !== content || $[20] !== popout.popup) {
6417
+ t8 = popout.popup ? createPortal(/* @__PURE__ */ jsx(StudioPopoutContext, {
6418
+ value: true,
6419
+ children: /* @__PURE__ */ jsx(UNSAFE_PortalProvider, {
6420
+ getContainer: () => popout.popup.document.body,
6421
+ children: content
6422
+ })
6423
+ }), popout.popup.document.body) : content;
6424
+ $[19] = content;
6425
+ $[20] = popout.popup;
6426
+ $[21] = t8;
6427
+ } else t8 = $[21];
6428
+ return t8;
4553
6429
  }
4554
6430
  //#endregion
4555
6431
  export { ColorModeSwitch, UIConfigurationModal, UIConfigurationProvider, exportCss, parseThemeCss, useUIConfiguration };