tsquare 0.12.3 → 0.13.0
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.
- package/CHANGELOG.md +13 -0
- package/README.md +1 -1
- package/dist/anchors.d.ts +12 -3
- package/dist/browser/index.js +319 -86
- package/dist/chunks/{chunk-2FU5Z5ON.js → chunk-PGX7ANZH.js} +1 -1
- package/dist/chunks/{chunk-H4Y6VBEX.js → chunk-YOZFCNSK.js} +170 -70
- package/dist/cli.js +1 -1
- package/dist/compile.d.ts +2 -0
- package/dist/flows.d.ts +31 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +166 -3
- package/dist/measure.d.ts +97 -0
- package/dist/playground/index.js +2 -2
- package/dist/render.d.ts +24 -0
- package/dist/tsquare.min.js +68 -68
- package/package.json +2 -2
package/dist/browser/index.js
CHANGED
|
@@ -7675,16 +7675,16 @@ function FDEF(state) {
|
|
|
7675
7675
|
state.ip = ip;
|
|
7676
7676
|
state.funcs[fn] = prog.slice(ipBegin + 1, ip);
|
|
7677
7677
|
}
|
|
7678
|
-
function MDAP(
|
|
7678
|
+
function MDAP(round2, state) {
|
|
7679
7679
|
var pi = state.stack.pop();
|
|
7680
7680
|
var p = state.z0[pi];
|
|
7681
7681
|
var fv = state.fv;
|
|
7682
7682
|
var pv = state.pv;
|
|
7683
7683
|
if (exports.DEBUG) {
|
|
7684
|
-
console.log(state.step, "MDAP[" +
|
|
7684
|
+
console.log(state.step, "MDAP[" + round2 + "]", pi);
|
|
7685
7685
|
}
|
|
7686
7686
|
var d2 = pv.distance(p, HPZero);
|
|
7687
|
-
if (
|
|
7687
|
+
if (round2) {
|
|
7688
7688
|
d2 = state.round(d2);
|
|
7689
7689
|
}
|
|
7690
7690
|
fv.setRelative(p, HPZero, d2, pv);
|
|
@@ -7887,7 +7887,7 @@ function RTDG(state) {
|
|
|
7887
7887
|
}
|
|
7888
7888
|
state.round = roundToDoubleGrid;
|
|
7889
7889
|
}
|
|
7890
|
-
function MIAP(
|
|
7890
|
+
function MIAP(round2, state) {
|
|
7891
7891
|
var stack = state.stack;
|
|
7892
7892
|
var n = stack.pop();
|
|
7893
7893
|
var pi = stack.pop();
|
|
@@ -7898,7 +7898,7 @@ function MIAP(round, state) {
|
|
|
7898
7898
|
if (exports.DEBUG) {
|
|
7899
7899
|
console.log(
|
|
7900
7900
|
state.step,
|
|
7901
|
-
"MIAP[" +
|
|
7901
|
+
"MIAP[" + round2 + "]",
|
|
7902
7902
|
n,
|
|
7903
7903
|
"(",
|
|
7904
7904
|
cv,
|
|
@@ -7907,7 +7907,7 @@ function MIAP(round, state) {
|
|
|
7907
7907
|
);
|
|
7908
7908
|
}
|
|
7909
7909
|
var d2 = pv.distance(p, HPZero);
|
|
7910
|
-
if (
|
|
7910
|
+
if (round2) {
|
|
7911
7911
|
if (Math.abs(d2 - cv) < state.cvCutIn) {
|
|
7912
7912
|
d2 = cv;
|
|
7913
7913
|
}
|
|
@@ -20659,6 +20659,7 @@ function markRoot(root, color) {
|
|
|
20659
20659
|
const kids = Children.toArray(node.props.children);
|
|
20660
20660
|
return cloneElement(node, {}, ...kids, /* @__PURE__ */ jsx3(Marker, { color }, "__marker"));
|
|
20661
20661
|
}
|
|
20662
|
+
var MARKS_ITSELF = /* @__PURE__ */ new Set(["Screen", "Modal", "Drawer", "Toast"]);
|
|
20662
20663
|
function withMarkers(reg) {
|
|
20663
20664
|
return Object.fromEntries(
|
|
20664
20665
|
Object.entries(reg).map(([name, C]) => [
|
|
@@ -20666,7 +20667,7 @@ function withMarkers(reg) {
|
|
|
20666
20667
|
(props) => {
|
|
20667
20668
|
const root = C(props);
|
|
20668
20669
|
const color = props.element?.props?.__mark;
|
|
20669
|
-
return color && name
|
|
20670
|
+
return color && !MARKS_ITSELF.has(name) ? markRoot(root, color) : root;
|
|
20670
20671
|
}
|
|
20671
20672
|
])
|
|
20672
20673
|
);
|
|
@@ -20789,6 +20790,16 @@ function BrowserBar() {
|
|
|
20789
20790
|
}
|
|
20790
20791
|
);
|
|
20791
20792
|
}
|
|
20793
|
+
function mayOverflow(name, width) {
|
|
20794
|
+
let w2 = 0;
|
|
20795
|
+
for (const ch of name) {
|
|
20796
|
+
if (ch.charCodeAt(0) >= 128 || /[MWmw@%&]/.test(ch)) w2 += 16.5;
|
|
20797
|
+
else if (/[A-Z]/.test(ch)) w2 += 12.5;
|
|
20798
|
+
else if (/[ .,:;'!|il1jft()[\]{}"`-]/.test(ch)) w2 += 8.5;
|
|
20799
|
+
else w2 += 11;
|
|
20800
|
+
}
|
|
20801
|
+
return w2 > width;
|
|
20802
|
+
}
|
|
20792
20803
|
function Screen({ element, children }) {
|
|
20793
20804
|
const p = element.props;
|
|
20794
20805
|
const s = screenSize(p);
|
|
@@ -20804,7 +20815,12 @@ function Screen({ element, children }) {
|
|
|
20804
20815
|
else body.push(c2);
|
|
20805
20816
|
}
|
|
20806
20817
|
return /* @__PURE__ */ jsxs(Box, { style: { flexDirection: "column", flexShrink: 0 }, children: [
|
|
20807
|
-
|
|
20818
|
+
mayOverflow(p.name ?? "", s.width) ? (
|
|
20819
|
+
// the board's layout sizes each column by its screen, so a name that may be wider than the
|
|
20820
|
+
// screen gets the screen's width and ends in "…" instead of widening the column. Only then:
|
|
20821
|
+
// the clip changes how the text is antialiased, and names that fit should render as before.
|
|
20822
|
+
/* @__PURE__ */ jsx3(Box, { style: { width: s.width, height: LABEL_H, fontSize: 16, fontWeight: 600, color: theme.text }, children: /* @__PURE__ */ jsx3("div", { style: { overflow: "hidden", whiteSpace: "nowrap", textOverflow: "ellipsis" }, children: p.name }) })
|
|
20823
|
+
) : /* @__PURE__ */ jsx3(Box, { style: { height: LABEL_H, fontSize: 16, fontWeight: 600, color: theme.text }, children: p.name ?? "" }),
|
|
20808
20824
|
/* @__PURE__ */ jsxs(
|
|
20809
20825
|
Box,
|
|
20810
20826
|
{
|
|
@@ -20825,19 +20841,22 @@ function Screen({ element, children }) {
|
|
|
20825
20841
|
s.chrome && s.device === "desktop" ? /* @__PURE__ */ jsx3(BrowserBar, {}) : null,
|
|
20826
20842
|
/* @__PURE__ */ jsxs(Box, { style: { position: "relative", flexGrow: 1, flexBasis: "0px", flexDirection: "column", overflow: "hidden" }, children: [
|
|
20827
20843
|
top,
|
|
20828
|
-
/* @__PURE__ */
|
|
20829
|
-
|
|
20830
|
-
|
|
20831
|
-
|
|
20832
|
-
|
|
20833
|
-
|
|
20834
|
-
|
|
20835
|
-
|
|
20836
|
-
|
|
20837
|
-
|
|
20838
|
-
|
|
20839
|
-
|
|
20840
|
-
|
|
20844
|
+
/* @__PURE__ */ jsxs(Box, { style: { flexGrow: 1, flexBasis: "0px", flexDirection: "column", overflow: "hidden" }, children: [
|
|
20845
|
+
/* @__PURE__ */ jsx3(
|
|
20846
|
+
Box,
|
|
20847
|
+
{
|
|
20848
|
+
style: {
|
|
20849
|
+
flexGrow: 1,
|
|
20850
|
+
flexShrink: 0,
|
|
20851
|
+
flexDirection: "column",
|
|
20852
|
+
padding: s.padding,
|
|
20853
|
+
gap: p.gap ?? 14
|
|
20854
|
+
},
|
|
20855
|
+
children: withDir(body, "column")
|
|
20856
|
+
}
|
|
20857
|
+
),
|
|
20858
|
+
p.__markBody ? /* @__PURE__ */ jsx3(Marker, { color: p.__markBody }) : null
|
|
20859
|
+
] }),
|
|
20841
20860
|
bottom,
|
|
20842
20861
|
overlays.map((o2) => isValidElement(o2) ? cloneElement(o2, { aboveTabBar: bottom.length > 0 }) : o2),
|
|
20843
20862
|
p.__mark ? /* @__PURE__ */ jsx3(Marker, { color: p.__mark }) : null
|
|
@@ -21103,9 +21122,9 @@ function Chart({ element, dir }) {
|
|
|
21103
21122
|
const kind = p.kind ?? "line";
|
|
21104
21123
|
const h2 = p.height ?? 180;
|
|
21105
21124
|
const w2 = p.width ?? (dir === "row" ? void 0 : "100%");
|
|
21106
|
-
const
|
|
21125
|
+
const round2 = kind === "pie" || kind === "donut";
|
|
21107
21126
|
const plot = (() => {
|
|
21108
|
-
if (
|
|
21127
|
+
if (round2) {
|
|
21109
21128
|
const slice = (from, to2, fill, k) => {
|
|
21110
21129
|
const a0 = from / 100 * 2 * Math.PI - Math.PI / 2, a1 = to2 / 100 * 2 * Math.PI - Math.PI / 2;
|
|
21111
21130
|
const x0 = 50 + 46 * Math.cos(a0), y0 = 50 + 46 * Math.sin(a0), x1 = 50 + 46 * Math.cos(a1), y1 = 50 + 46 * Math.sin(a1);
|
|
@@ -21135,7 +21154,7 @@ function Chart({ element, dir }) {
|
|
|
21135
21154
|
})();
|
|
21136
21155
|
return /* @__PURE__ */ jsxs(Box, { style: { flexDirection: "column", gap: 10, width: w2, height: h2, flexShrink: 0, ...dir === "row" ? { flexGrow: 1, flexBasis: "0px" } : {} }, children: [
|
|
21137
21156
|
p.title ? /* @__PURE__ */ jsx3(Box, { style: { fontSize: 13, fontWeight: 600, color: theme.text }, children: p.title }) : null,
|
|
21138
|
-
/* @__PURE__ */ jsx3(Box, { style: { flexGrow: 1, borderBottom:
|
|
21157
|
+
/* @__PURE__ */ jsx3(Box, { style: { flexGrow: 1, borderBottom: round2 ? void 0 : `1.5px solid ${theme.line}`, justifyContent: round2 ? "center" : void 0, alignItems: round2 ? "center" : void 0 }, children: plot })
|
|
21139
21158
|
] });
|
|
21140
21159
|
}
|
|
21141
21160
|
function AvatarCircle({ initials, size = 40 }) {
|
|
@@ -21300,7 +21319,7 @@ function Select({ element, dir }) {
|
|
|
21300
21319
|
] })
|
|
21301
21320
|
] });
|
|
21302
21321
|
}
|
|
21303
|
-
function CheckMark({ checked, round = false, c: c2 = GRAY }) {
|
|
21322
|
+
function CheckMark({ checked, round: round2 = false, c: c2 = GRAY }) {
|
|
21304
21323
|
return /* @__PURE__ */ jsx3(
|
|
21305
21324
|
Box,
|
|
21306
21325
|
{
|
|
@@ -21308,13 +21327,13 @@ function CheckMark({ checked, round = false, c: c2 = GRAY }) {
|
|
|
21308
21327
|
width: 20,
|
|
21309
21328
|
height: 20,
|
|
21310
21329
|
flexShrink: 0,
|
|
21311
|
-
borderRadius:
|
|
21312
|
-
border: `1.5px solid ${checked && !
|
|
21313
|
-
backgroundColor: checked && !
|
|
21330
|
+
borderRadius: round2 ? 10 : 5,
|
|
21331
|
+
border: `1.5px solid ${checked && !round2 ? c2.accent : theme.lineStrong}`,
|
|
21332
|
+
backgroundColor: checked && !round2 ? c2.accent : theme.paper,
|
|
21314
21333
|
alignItems: "center",
|
|
21315
21334
|
justifyContent: "center"
|
|
21316
21335
|
},
|
|
21317
|
-
children: checked ?
|
|
21336
|
+
children: checked ? round2 ? /* @__PURE__ */ jsx3(Box, { style: { width: 10, height: 10, borderRadius: 5, backgroundColor: c2.accent } }) : /* @__PURE__ */ jsx3(IconGlyph, { name: "check", size: 14, color: c2.onAccent, strokeWidth: 3 }) : null
|
|
21318
21337
|
}
|
|
21319
21338
|
);
|
|
21320
21339
|
}
|
|
@@ -21454,7 +21473,7 @@ function Calendar({ element, dir, aligned, colors: c2 = GRAY }) {
|
|
|
21454
21473
|
/* @__PURE__ */ jsx3(Box, { children: ["S", "M", "T", "W", "T", "F", "S"].map((d2, i2) => /* @__PURE__ */ jsx3(Box, { style: { width: CELL, justifyContent: "center", fontSize: 12, color: theme.muted }, children: d2 }, i2)) }),
|
|
21455
21474
|
weeks.map((week, w2) => /* @__PURE__ */ jsx3(Box, { children: week.map((d2, i2) => {
|
|
21456
21475
|
const end = d2 != null && (d2 === from || d2 === to2) && from > 0;
|
|
21457
|
-
const
|
|
21476
|
+
const inside2 = d2 != null && from > 0 && d2 > from && d2 < to2;
|
|
21458
21477
|
const band = d2 != null && from > 0 && to2 > from && d2 >= from && d2 <= to2;
|
|
21459
21478
|
return /* @__PURE__ */ jsxs(Box, { style: { width: CELL, height: CELL, alignItems: "center", justifyContent: "center", position: "relative" }, children: [
|
|
21460
21479
|
band ? /* @__PURE__ */ jsx3(Box, { style: { position: "absolute", top: 4, bottom: 4, left: d2 === from ? CELL / 2 : 0, right: d2 === to2 ? CELL / 2 : 0, backgroundColor: theme.fill } }) : null,
|
|
@@ -21470,7 +21489,7 @@ function Calendar({ element, dir, aligned, colors: c2 = GRAY }) {
|
|
|
21470
21489
|
justifyContent: "center",
|
|
21471
21490
|
fontSize: 14,
|
|
21472
21491
|
backgroundColor: end ? c2.accent : void 0,
|
|
21473
|
-
color: end ? c2.onAccent :
|
|
21492
|
+
color: end ? c2.onAccent : inside2 ? theme.ink : theme.text,
|
|
21474
21493
|
fontWeight: end ? 600 : 400
|
|
21475
21494
|
},
|
|
21476
21495
|
children: [
|
|
@@ -21692,7 +21711,8 @@ function Modal({ element, children }) {
|
|
|
21692
21711
|
},
|
|
21693
21712
|
children: [
|
|
21694
21713
|
p.title ? /* @__PURE__ */ jsx3(Box, { style: { fontSize: 18, fontWeight: 600 }, children: p.title }) : null,
|
|
21695
|
-
withDir(children, "column")
|
|
21714
|
+
withDir(children, "column"),
|
|
21715
|
+
p.__mark ? /* @__PURE__ */ jsx3(Marker, { color: p.__mark }) : null
|
|
21696
21716
|
]
|
|
21697
21717
|
}
|
|
21698
21718
|
) });
|
|
@@ -21727,7 +21747,8 @@ function Drawer({ element, children }) {
|
|
|
21727
21747
|
/* @__PURE__ */ jsx3(Box, { style: { fontSize: 18, fontWeight: 600 }, children: p.title }),
|
|
21728
21748
|
/* @__PURE__ */ jsx3(IconGlyph, { name: "x", size: 22, color: theme.muted })
|
|
21729
21749
|
] }) : null,
|
|
21730
|
-
withDir(children, "column")
|
|
21750
|
+
withDir(children, "column"),
|
|
21751
|
+
p.__mark ? /* @__PURE__ */ jsx3(Marker, { color: p.__mark }) : null
|
|
21731
21752
|
]
|
|
21732
21753
|
}
|
|
21733
21754
|
) });
|
|
@@ -21740,7 +21761,8 @@ function Toast({ element, aboveTabBar }) {
|
|
|
21740
21761
|
return /* @__PURE__ */ jsx3(Box, { style: { position: "absolute", left: 16, right: 16, justifyContent: side, ...top ? { top: 16 } : { bottom: aboveTabBar ? 92 : 24 } }, children: /* @__PURE__ */ jsxs(Box, { style: { alignItems: "center", gap: 12, padding: "12px 16px", borderRadius: 12, backgroundColor: theme.ink, color: theme.onPrimary, fontSize: 14, boxShadow: "0 6px 20px rgba(0,0,0,0.22)", maxWidth: 420 }, children: [
|
|
21741
21762
|
p.icon ? /* @__PURE__ */ jsx3(IconGlyph, { name: p.icon, size: 18, color: theme.onPrimary }) : null,
|
|
21742
21763
|
/* @__PURE__ */ jsx3(Box, { style: { flexShrink: 1 }, children: p.text ?? "" }),
|
|
21743
|
-
p.action ? /* @__PURE__ */ jsx3(Box, { style: { fontWeight: 700, marginLeft: 8, flexShrink: 0 }, children: p.action }) : null
|
|
21764
|
+
p.action ? /* @__PURE__ */ jsx3(Box, { style: { fontWeight: 700, marginLeft: 8, flexShrink: 0 }, children: p.action }) : null,
|
|
21765
|
+
p.__mark ? /* @__PURE__ */ jsx3(Marker, { color: p.__mark }) : null
|
|
21744
21766
|
] }) });
|
|
21745
21767
|
}
|
|
21746
21768
|
function Flow() {
|
|
@@ -21817,22 +21839,23 @@ function findAnchors(spec) {
|
|
|
21817
21839
|
return [...out, ...tips];
|
|
21818
21840
|
}
|
|
21819
21841
|
var MARK = (i2) => `#fe${(i2 >> 8).toString(16).padStart(2, "0")}${(i2 & 255).toString(16).padStart(2, "0")}`;
|
|
21820
|
-
function tagForMeasuring(spec, anchors) {
|
|
21842
|
+
function tagForMeasuring(spec, anchors, bodies = []) {
|
|
21821
21843
|
const tagged = structuredClone(spec);
|
|
21822
21844
|
const colors = /* @__PURE__ */ new Map();
|
|
21823
21845
|
let n = 1;
|
|
21824
|
-
const tag = (id,
|
|
21825
|
-
const key =
|
|
21846
|
+
const tag = (id, part) => {
|
|
21847
|
+
const key = part ? `${id}#${part}` : id;
|
|
21826
21848
|
if (colors.has(key)) return;
|
|
21827
21849
|
const color = MARK(n++);
|
|
21828
21850
|
colors.set(key, color);
|
|
21829
21851
|
const el2 = tagged.elements[id];
|
|
21830
|
-
el2.props = { ...el2.props ?? {}, [field ? "__markField" : "__mark"]: color };
|
|
21852
|
+
el2.props = { ...el2.props ?? {}, [part === "field" ? "__markField" : part === "body" ? "__markBody" : "__mark"]: color };
|
|
21831
21853
|
};
|
|
21832
21854
|
for (const a of anchors) {
|
|
21833
|
-
tag(a.screen,
|
|
21834
|
-
tag(a.id, a.field);
|
|
21855
|
+
tag(a.screen, "");
|
|
21856
|
+
tag(a.id, a.field ? "field" : "");
|
|
21835
21857
|
}
|
|
21858
|
+
for (const id of bodies) tag(id, "body");
|
|
21836
21859
|
return { tagged, colors };
|
|
21837
21860
|
}
|
|
21838
21861
|
function readMarkers(svg, colors) {
|
|
@@ -21891,35 +21914,54 @@ function tooltipSize(text2) {
|
|
|
21891
21914
|
const lines = Math.max(1, Math.ceil(text2.length * 7.4 / 216));
|
|
21892
21915
|
return { w: width, h: lines * 18 + 12 + 6 };
|
|
21893
21916
|
}
|
|
21917
|
+
function placeOverlay(spec, a, boxes) {
|
|
21918
|
+
const screen = boxes[a.screen];
|
|
21919
|
+
const anchor = boxes[a.field ? `${a.id}#field` : a.id];
|
|
21920
|
+
if (!screen || !anchor) return null;
|
|
21921
|
+
const p = propsOf(spec.elements, a.id);
|
|
21922
|
+
if (a.kind === "options") {
|
|
21923
|
+
const options = p.options?.length ? p.options : [p.value ?? "Option 1", "Option 2", "Option 3"];
|
|
21924
|
+
const size2 = { w: anchor.w, h: options.length * ROW + 8 };
|
|
21925
|
+
return { screen, anchor, size: size2, pos: place(anchor, size2, screen, { prefer: "below", align: "start", gap: 4 }), options };
|
|
21926
|
+
}
|
|
21927
|
+
if (a.kind === "menu") {
|
|
21928
|
+
const items = p.menu.map((i2) => typeof i2 === "string" ? { label: i2 } : i2);
|
|
21929
|
+
const width = a.end ? 200 : Math.max(180, anchor.w);
|
|
21930
|
+
const inRightHalf = anchor.x + anchor.w / 2 > screen.x + screen.w / 2;
|
|
21931
|
+
const size2 = { w: width, h: items.length * ROW + 8 };
|
|
21932
|
+
return { screen, anchor, size: size2, pos: place(anchor, size2, screen, { prefer: "below", align: a.end || inRightHalf ? "end" : "start", gap: a.end ? -6 : 4 }), items };
|
|
21933
|
+
}
|
|
21934
|
+
if (a.kind === "calendar") {
|
|
21935
|
+
const date = parseDate(p.value);
|
|
21936
|
+
const { start, days } = monthGrid(date?.month);
|
|
21937
|
+
const weeks = Math.ceil((start + days) / 7);
|
|
21938
|
+
const size2 = { w: 296, h: 92 + weeks * 38 };
|
|
21939
|
+
return { screen, anchor, size: size2, pos: place(anchor, size2, screen, { prefer: "below", align: "start", gap: 4 }), date };
|
|
21940
|
+
}
|
|
21941
|
+
const size = tooltipSize(p.tooltip);
|
|
21942
|
+
return { screen, anchor, size, pos: place(anchor, size, screen, { prefer: "above", align: "center", gap: 4 }) };
|
|
21943
|
+
}
|
|
21944
|
+
function overlayBoxes(spec, anchors, boxes) {
|
|
21945
|
+
return anchors.flatMap((a) => {
|
|
21946
|
+
const o2 = placeOverlay(spec, a, boxes);
|
|
21947
|
+
return o2 ? [{ id: a.id, box: { x: o2.screen.x + o2.pos.x, y: o2.screen.y + o2.pos.y, w: o2.size.w, h: o2.size.h } }] : [];
|
|
21948
|
+
});
|
|
21949
|
+
}
|
|
21894
21950
|
function overlayLayer(spec, anchors, boxes, c2, Calendar2) {
|
|
21895
21951
|
const byScreen = /* @__PURE__ */ new Map();
|
|
21896
21952
|
for (const a of anchors) {
|
|
21897
|
-
const
|
|
21898
|
-
|
|
21899
|
-
|
|
21953
|
+
const o2 = placeOverlay(spec, a, boxes);
|
|
21954
|
+
if (!o2) continue;
|
|
21955
|
+
const { screen, anchor, size, pos } = o2;
|
|
21900
21956
|
const p = propsOf(spec.elements, a.id);
|
|
21901
21957
|
let node = null;
|
|
21902
|
-
let pos = null;
|
|
21903
21958
|
if (a.kind === "options") {
|
|
21904
|
-
|
|
21905
|
-
const size = { w: anchor.w, h: options.length * ROW + 8 };
|
|
21906
|
-
pos = place(anchor, size, screen, { prefer: "below", align: "start", gap: 4 });
|
|
21907
|
-
node = /* @__PURE__ */ jsx4(ListCard, { items: options.map((label) => ({ label })), width: size.w, selected: p.value, c: c2 });
|
|
21959
|
+
node = /* @__PURE__ */ jsx4(ListCard, { items: o2.options.map((label) => ({ label })), width: size.w, selected: p.value, c: c2 });
|
|
21908
21960
|
} else if (a.kind === "menu") {
|
|
21909
|
-
|
|
21910
|
-
const width = a.end ? 200 : Math.max(180, anchor.w);
|
|
21911
|
-
const inRightHalf = anchor.x + anchor.w / 2 > screen.x + screen.w / 2;
|
|
21912
|
-
pos = place(anchor, { w: width, h: items.length * ROW + 8 }, screen, { prefer: "below", align: a.end || inRightHalf ? "end" : "start", gap: a.end ? -6 : 4 });
|
|
21913
|
-
node = /* @__PURE__ */ jsx4(ListCard, { items, width, c: c2 });
|
|
21961
|
+
node = /* @__PURE__ */ jsx4(ListCard, { items: o2.items, width: size.w, c: c2 });
|
|
21914
21962
|
} else if (a.kind === "calendar") {
|
|
21915
|
-
|
|
21916
|
-
const { start, days } = monthGrid(date?.month);
|
|
21917
|
-
const weeks = Math.ceil((start + days) / 7);
|
|
21918
|
-
pos = place(anchor, { w: 296, h: 92 + weeks * 38 }, screen, { prefer: "below", align: "start", gap: 4 });
|
|
21919
|
-
node = /* @__PURE__ */ jsx4("div", { style: { display: "flex", boxShadow: "0 8px 24px rgba(0,0,0,0.18)", borderRadius: 12 }, children: Calendar2({ element: { type: "Calendar", props: { month: date?.month ?? "Month", selected: date?.day } }, colors: c2 }) });
|
|
21963
|
+
node = /* @__PURE__ */ jsx4("div", { style: { display: "flex", boxShadow: "0 8px 24px rgba(0,0,0,0.18)", borderRadius: 12 }, children: Calendar2({ element: { type: "Calendar", props: { month: o2.date?.month ?? "Month", selected: o2.date?.day } }, colors: c2 }) });
|
|
21920
21964
|
} else {
|
|
21921
|
-
const size = tooltipSize(p.tooltip);
|
|
21922
|
-
pos = place(anchor, size, screen, { prefer: "above", align: "center", gap: 4 });
|
|
21923
21965
|
node = /* @__PURE__ */ jsx4(Tooltip, { text: p.tooltip, side: pos.side, width: size.w, arrowX: anchor.x + anchor.w / 2 - (screen.x + pos.x) });
|
|
21924
21966
|
}
|
|
21925
21967
|
const list = byScreen.get(a.screen) ?? [];
|
|
@@ -22061,9 +22103,7 @@ function flowColor(color, palette) {
|
|
|
22061
22103
|
const s = String(color);
|
|
22062
22104
|
return ACCENTS[s] ?? s;
|
|
22063
22105
|
}
|
|
22064
|
-
function
|
|
22065
|
-
const shapes = [];
|
|
22066
|
-
const labels = [];
|
|
22106
|
+
function layoutFlows(spec, flows, screens, gap, palette) {
|
|
22067
22107
|
const placed = [];
|
|
22068
22108
|
const drawn = [];
|
|
22069
22109
|
const tips = flows.flatMap(({ ends: ends2 }) => {
|
|
@@ -22082,20 +22122,16 @@ function flowLayer(spec, flows, screens, gap, palette, size) {
|
|
|
22082
22122
|
return r;
|
|
22083
22123
|
});
|
|
22084
22124
|
const ends = routes.flatMap((r) => [r.points[0], r.points[r.points.length - 1]]);
|
|
22085
|
-
flows.
|
|
22125
|
+
return flows.map(({ key }, i2) => {
|
|
22086
22126
|
const r = routes[i2];
|
|
22087
22127
|
const p = spec.elements[key].props ?? {};
|
|
22088
|
-
const color = flowColor(p.color, palette);
|
|
22089
22128
|
const start = p.start ?? "none", end = p.end ?? "arrow";
|
|
22090
22129
|
const pts = [...r.points];
|
|
22091
22130
|
pts[0] = add(pts[0], DIR[r.from], INSET[start]);
|
|
22092
22131
|
pts[pts.length - 1] = add(pts[pts.length - 1], DIR[r.to], INSET[end]);
|
|
22093
|
-
const
|
|
22094
|
-
|
|
22095
|
-
|
|
22096
|
-
marker(start, r.points[0], DIR[r.from], color, `${key}-start`),
|
|
22097
|
-
marker(end, r.points[r.points.length - 1], DIR[r.to], color, `${key}-end`)
|
|
22098
|
-
);
|
|
22132
|
+
const line = p.line ?? "rounded";
|
|
22133
|
+
const { d: d2, at } = linePath(r, pts, line);
|
|
22134
|
+
const out = { key, route: r, points: pts, d: d2, color: flowColor(p.color, palette), start, end, line, dashed: !!p.dashed };
|
|
22099
22135
|
if (p.label) {
|
|
22100
22136
|
const w2 = flowLabelWidth(String(p.label));
|
|
22101
22137
|
const covers = (c2) => placed.filter((q) => c2.x - w2 / 2 < q.x + q.w && q.x < c2.x + w2 / 2 && c2.y - 14 < q.y + q.h && q.y < c2.y + 14).length + ends.filter((q) => Math.abs(q.x - c2.x) < w2 / 2 + 12 && Math.abs(q.y - c2.y) < 24).length;
|
|
@@ -22105,13 +22141,58 @@ function flowLayer(spec, flows, screens, gap, palette, size) {
|
|
|
22105
22141
|
const c2 = at(t), n = covers(c2);
|
|
22106
22142
|
if (n < best) [mid, best] = [c2, n];
|
|
22107
22143
|
}
|
|
22108
|
-
const
|
|
22109
|
-
placed.push(
|
|
22144
|
+
const box = { x: mid.x - w2 / 2, y: mid.y - 12, w: w2, h: 24 };
|
|
22145
|
+
placed.push(box);
|
|
22146
|
+
out.label = { text: String(p.label), ...box };
|
|
22147
|
+
}
|
|
22148
|
+
return out;
|
|
22149
|
+
});
|
|
22150
|
+
}
|
|
22151
|
+
function flowPolyline(f) {
|
|
22152
|
+
const r = f.route, pts = f.points;
|
|
22153
|
+
const s0 = pts[0], e0 = pts[pts.length - 1];
|
|
22154
|
+
let out;
|
|
22155
|
+
if (r.lane == null && f.line === "straight") out = [s0, e0];
|
|
22156
|
+
else if (r.lane == null && f.line === "curved") {
|
|
22157
|
+
const { at } = linePath(r, pts, f.line);
|
|
22158
|
+
out = Array.from({ length: 25 }, (_, i2) => at(i2 / 24));
|
|
22159
|
+
} else {
|
|
22160
|
+
const radius = f.line === "curved" ? 40 : f.line === "rounded" ? 14 : 0;
|
|
22161
|
+
const q = simplify(pts);
|
|
22162
|
+
out = [q[0]];
|
|
22163
|
+
for (let i2 = 1; i2 < q.length; i2++) {
|
|
22164
|
+
const p = q[i2];
|
|
22165
|
+
if (radius > 0 && i2 < q.length - 1) {
|
|
22166
|
+
const prev = q[i2 - 1], next = q[i2 + 1];
|
|
22167
|
+
const rr2 = Math.min(radius, Math.hypot(p.x - prev.x, p.y - prev.y) / 2, Math.hypot(next.x - p.x, next.y - p.y) / 2);
|
|
22168
|
+
const into = { x: Math.sign(p.x - prev.x), y: Math.sign(p.y - prev.y) }, outd = { x: Math.sign(next.x - p.x), y: Math.sign(next.y - p.y) };
|
|
22169
|
+
const a = { x: p.x - into.x * rr2, y: p.y - into.y * rr2 }, b = { x: p.x + outd.x * rr2, y: p.y + outd.y * rr2 };
|
|
22170
|
+
for (let k = 0; k <= 6; k++) {
|
|
22171
|
+
const t = k / 6;
|
|
22172
|
+
out.push({ x: (1 - t) ** 2 * a.x + 2 * (1 - t) * t * p.x + t ** 2 * b.x, y: (1 - t) ** 2 * a.y + 2 * (1 - t) * t * p.y + t ** 2 * b.y });
|
|
22173
|
+
}
|
|
22174
|
+
} else out.push(p);
|
|
22175
|
+
}
|
|
22176
|
+
}
|
|
22177
|
+
const first = r.points[0], last = r.points[r.points.length - 1];
|
|
22178
|
+
return [first, ...out, last].filter((p, i2, all) => i2 === 0 || Math.hypot(p.x - all[i2 - 1].x, p.y - all[i2 - 1].y) >= 0.01);
|
|
22179
|
+
}
|
|
22180
|
+
function flowLayer(layout, size) {
|
|
22181
|
+
const shapes = [];
|
|
22182
|
+
const labels = [];
|
|
22183
|
+
for (const f of layout) {
|
|
22184
|
+
const r = f.route, { key, color } = f;
|
|
22185
|
+
shapes.push(
|
|
22186
|
+
/* @__PURE__ */ jsx5("path", { d: f.d, fill: "none", stroke: color, strokeWidth: 2, strokeLinejoin: "round", strokeLinecap: "round", ...f.dashed ? { strokeDasharray: "7 6" } : {} }, `${key}-line`),
|
|
22187
|
+
marker(f.start, r.points[0], DIR[r.from], color, `${key}-start`),
|
|
22188
|
+
marker(f.end, r.points[r.points.length - 1], DIR[r.to], color, `${key}-end`)
|
|
22189
|
+
);
|
|
22190
|
+
if (f.label) {
|
|
22110
22191
|
labels.push(
|
|
22111
|
-
/* @__PURE__ */ jsx5("div", { style: { position: "absolute", left:
|
|
22192
|
+
/* @__PURE__ */ jsx5("div", { style: { position: "absolute", left: f.label.x, top: f.label.y, width: f.label.w, height: 24, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: 12, backgroundColor: theme.paper, border: `1.5px solid ${color}`, color, fontSize: 12, fontWeight: 600 }, children: f.label.text }, `${key}-label`)
|
|
22112
22193
|
);
|
|
22113
22194
|
}
|
|
22114
|
-
}
|
|
22195
|
+
}
|
|
22115
22196
|
return /* @__PURE__ */ jsxs3("div", { style: { position: "absolute", top: 0, left: 0, width: size.width, height: size.height, display: "flex" }, children: [
|
|
22116
22197
|
/* @__PURE__ */ jsx5("svg", { width: size.width, height: size.height, viewBox: `0 0 ${size.width} ${size.height}`, style: { position: "absolute", top: 0, left: 0 }, children: shapes }),
|
|
22117
22198
|
labels
|
|
@@ -22902,10 +22983,8 @@ async function renderWireframeSvg(spec, opts = {}) {
|
|
|
22902
22983
|
if (issues.length) throw new SpecError(issues);
|
|
22903
22984
|
}
|
|
22904
22985
|
const flowsOn = opts.flows !== false;
|
|
22905
|
-
const { width, height
|
|
22906
|
-
|
|
22907
|
-
if ((board.props ?? {}).gap == null && gap !== BOARD_GAP)
|
|
22908
|
-
spec = { ...spec, elements: { ...spec.elements, [spec.root]: { ...board, props: { ...board.props, gap } } } };
|
|
22986
|
+
const { width, height } = boardLayout(spec, { flows: opts.flows });
|
|
22987
|
+
spec = withBoardGap(spec, opts.flows);
|
|
22909
22988
|
const palette = paletteFor(spec.elements[spec.root]?.props?.accent);
|
|
22910
22989
|
const registry2 = withPalette(palette);
|
|
22911
22990
|
const draw = async (s, reg) => renderToSvg(s, { registry: reg, includeStandard: false, fonts: await loadFonts(), width, height });
|
|
@@ -22913,13 +22992,17 @@ async function renderWireframeSvg(spec, opts = {}) {
|
|
|
22913
22992
|
const { anchors, boxes } = await measureAnchors(spec, flows?.measure ?? []);
|
|
22914
22993
|
if (!anchors.length && !flows?.list.length) return draw(spec, registry2);
|
|
22915
22994
|
const layers = [];
|
|
22916
|
-
if (flows?.list.length) {
|
|
22917
|
-
const resolved = flows.list.map(({ key, from, to: to2 }) => ({ key, ends: { from: flows.box(from, boxes) ?? flows.screenBox(from), to: flows.box(to2, boxes) ?? flows.screenBox(to2), fromScreen: flows.screenBox(from), toScreen: flows.screenBox(to2) } })).filter((f) => !!(f.ends.from && f.ends.to && f.ends.fromScreen && f.ends.toScreen));
|
|
22918
|
-
layers.push(flowLayer(spec, resolved, flows.screens, flows.gap, palette, { width, height }));
|
|
22919
|
-
}
|
|
22995
|
+
if (flows?.list.length) layers.push(flowLayer(layoutFlows(spec, flows.resolve(boxes), flows.screens, flows.gap, palette), { width, height }));
|
|
22920
22996
|
if (anchors.length) layers.push(overlayLayer(spec, anchors, boxes, palette, registry2.Calendar));
|
|
22921
22997
|
return draw(spec, withTopLayer(registry2, layers));
|
|
22922
22998
|
}
|
|
22999
|
+
function withBoardGap(spec, flows) {
|
|
23000
|
+
const { gap } = boardLayout(spec, { flows });
|
|
23001
|
+
const board = spec.elements[spec.root];
|
|
23002
|
+
if ((board.props ?? {}).gap == null && gap !== BOARD_GAP)
|
|
23003
|
+
return { ...spec, elements: { ...spec.elements, [spec.root]: { ...board, props: { ...board.props, gap } } } };
|
|
23004
|
+
return spec;
|
|
23005
|
+
}
|
|
22923
23006
|
function flowEnds(spec) {
|
|
22924
23007
|
const els = spec.elements;
|
|
22925
23008
|
const byId = /* @__PURE__ */ new Map();
|
|
@@ -22947,9 +23030,12 @@ function flowEnds(spec) {
|
|
|
22947
23030
|
list,
|
|
22948
23031
|
measure,
|
|
22949
23032
|
screens: [...screenRects.values()],
|
|
22950
|
-
screenBox: (key) => screenRects.get(screenOf(key) ?? ""),
|
|
22951
23033
|
gap: (els[spec.root].props ?? {}).gap ?? BOARD_GAP,
|
|
22952
|
-
|
|
23034
|
+
resolve(boxes) {
|
|
23035
|
+
const box = (key) => els[key].type === "Screen" ? screenRects.get(key) : boxes[key];
|
|
23036
|
+
const screenBox = (key) => screenRects.get(screenOf(key) ?? "");
|
|
23037
|
+
return list.map(({ key, from, to: to2 }) => ({ key, ends: { from: box(from) ?? screenBox(from), to: box(to2) ?? screenBox(to2), fromScreen: screenBox(from), toScreen: screenBox(to2) } })).filter((f) => !!(f.ends.from && f.ends.to && f.ends.fromScreen && f.ends.toScreen));
|
|
23038
|
+
}
|
|
22953
23039
|
};
|
|
22954
23040
|
}
|
|
22955
23041
|
async function measureAnchors(spec, extra = []) {
|
|
@@ -22993,7 +23079,7 @@ function compileWireframe(source) {
|
|
|
22993
23079
|
return true;
|
|
22994
23080
|
});
|
|
22995
23081
|
unique.sort((a, b) => a.line - b.line);
|
|
22996
|
-
return { spec: parsed.spec, issues: unique };
|
|
23082
|
+
return { spec: parsed.spec, issues: unique, lines: parsed.lines };
|
|
22997
23083
|
}
|
|
22998
23084
|
function formatIssues(issues) {
|
|
22999
23085
|
return issues.map((i2) => `line ${i2.line}: ${i2.message}`).join("\n");
|
|
@@ -23456,6 +23542,150 @@ function addStyles(doc) {
|
|
|
23456
23542
|
doc.head.append(style);
|
|
23457
23543
|
}
|
|
23458
23544
|
|
|
23545
|
+
// src/measure.ts
|
|
23546
|
+
var isFlow = (e) => e.type === "Flow";
|
|
23547
|
+
var COVERS_SCREEN = /* @__PURE__ */ new Set(["Modal", "Drawer"]);
|
|
23548
|
+
var OVERLAYS = /* @__PURE__ */ new Set(["Modal", "Drawer", "Toast"]);
|
|
23549
|
+
var CONTAINERS = new Set(Object.entries(componentDefinitions).filter(([, d2]) => d2.slots.length).map(([name]) => name));
|
|
23550
|
+
var BARS = /* @__PURE__ */ new Set(["NavBar", "TabBar"]);
|
|
23551
|
+
var toBox = (r) => ({ x: round(r.x), y: round(r.y), width: round(r.w), height: round(r.h) });
|
|
23552
|
+
var round = (n) => Math.round(n * 100) / 100;
|
|
23553
|
+
function clip(r, to2) {
|
|
23554
|
+
if (!to2) return r;
|
|
23555
|
+
const x3 = Math.max(r.x, to2.x), y = Math.max(r.y, to2.y);
|
|
23556
|
+
const w2 = Math.min(r.x + r.w, to2.x + to2.w) - x3, h2 = Math.min(r.y + r.h, to2.y + to2.h) - y;
|
|
23557
|
+
return w2 >= 0 && h2 >= 0 && (w2 > 0 || r.w === 0) && (h2 > 0 || r.h === 0) ? { x: x3, y, w: w2, h: h2 } : null;
|
|
23558
|
+
}
|
|
23559
|
+
async function measureElements(spec, lines, opts = {}) {
|
|
23560
|
+
upgradeSpec(spec);
|
|
23561
|
+
if (!opts.skipValidation) {
|
|
23562
|
+
const issues = checkSpec(spec);
|
|
23563
|
+
if (issues.length) throw new SpecError(issues);
|
|
23564
|
+
}
|
|
23565
|
+
const { width, height } = boardLayout(spec, { flows: opts.flows });
|
|
23566
|
+
spec = withBoardGap(spec, opts.flows);
|
|
23567
|
+
const els = spec.elements;
|
|
23568
|
+
const anchors = findAnchors(spec);
|
|
23569
|
+
const every = Object.keys(els).filter((k) => !["Board", "Screen", "Flow"].includes(els[k].type)).map((id) => ({ id, screen: id, kind: "tooltip", field: false }));
|
|
23570
|
+
const screens = Object.keys(els).filter((k) => els[k].type === "Screen");
|
|
23571
|
+
const { tagged, colors } = tagForMeasuring(spec, [...anchors, ...every], screens);
|
|
23572
|
+
const svg = await renderToSvg(tagged, { registry: withMarkers(withPalette(paletteFor())), includeStandard: false, fonts: await loadFonts(), width, height });
|
|
23573
|
+
const boxes = readMarkers(svg, colors);
|
|
23574
|
+
const { items } = boardLayout(spec, { flows: opts.flows });
|
|
23575
|
+
const laidOut = (els[spec.root].children ?? []).filter((k) => els[k]?.type === "Screen" || els[k]?.type === "Note");
|
|
23576
|
+
const frames = /* @__PURE__ */ new Map(), bands = /* @__PURE__ */ new Map();
|
|
23577
|
+
laidOut.forEach((k, i2) => {
|
|
23578
|
+
const it = items[i2];
|
|
23579
|
+
if (!it || els[k].type !== "Screen") return;
|
|
23580
|
+
frames.set(k, { x: it.x, y: it.y + LABEL_H, w: it.width, h: it.height - LABEL_H });
|
|
23581
|
+
bands.set(k, { x: it.x, y: it.y, w: it.width, h: LABEL_H });
|
|
23582
|
+
});
|
|
23583
|
+
const overlays = /* @__PURE__ */ new Map();
|
|
23584
|
+
for (const o2 of overlayBoxes(spec, anchors, boxes)) overlays.set(o2.id, [...overlays.get(o2.id) ?? [], o2.box]);
|
|
23585
|
+
const lineOf = (k) => k == null ? null : lines[k] ?? 0;
|
|
23586
|
+
const endLine = (k) => Math.max(lines[k] ?? 0, ...(els[k].children ?? []).filter((c2) => els[c2]).map(endLine));
|
|
23587
|
+
const labelOf = (k) => {
|
|
23588
|
+
const p = els[k].props ?? {};
|
|
23589
|
+
const v2 = p[PRIMARY_PROP[els[k].type] ?? ""];
|
|
23590
|
+
return typeof v2 === "string" ? v2 : void 0;
|
|
23591
|
+
};
|
|
23592
|
+
const out = [];
|
|
23593
|
+
const visit = (k, parent, screen, cut) => {
|
|
23594
|
+
const el2 = els[k];
|
|
23595
|
+
if (!el2 || el2.type === "Flow") return;
|
|
23596
|
+
const p = el2.props ?? {};
|
|
23597
|
+
const base = { line: lineOf(k), endLine: endLine(k), ...typeof p.id === "string" ? { id: p.id } : {}, type: el2.type, ...labelOf(k) != null ? { label: labelOf(k) } : {}, screenLine: lineOf(screen), parentLine: lineOf(parent) };
|
|
23598
|
+
let entry = null;
|
|
23599
|
+
if (el2.type === "Board") entry = { ...base, box: { x: 0, y: 0, width, height } };
|
|
23600
|
+
else if (el2.type === "Screen") {
|
|
23601
|
+
const frame = frames.get(k);
|
|
23602
|
+
if (frame) entry = { ...base, box: toBox(frame), labelBox: toBox(bands.get(k)) };
|
|
23603
|
+
} else {
|
|
23604
|
+
const r = boxes[k];
|
|
23605
|
+
const seen = r && clip(r, cut);
|
|
23606
|
+
if (seen) {
|
|
23607
|
+
const view = screen ? boxes[screen] ?? frames.get(screen) : void 0;
|
|
23608
|
+
const os3 = (overlays.get(k) ?? []).map((o2) => clip(o2, view)).filter((o2) => !!o2 && o2.w > 0 && o2.h > 0);
|
|
23609
|
+
entry = { ...base, box: toBox(seen), ...os3.length ? { overlays: os3.map(toBox) } : {}, ...COVERS_SCREEN.has(el2.type) ? { scrim: p.scrim ?? true } : {} };
|
|
23610
|
+
}
|
|
23611
|
+
}
|
|
23612
|
+
if (entry) out.push(entry);
|
|
23613
|
+
const inScreen = el2.type === "Screen" ? k : screen;
|
|
23614
|
+
const kids = el2.children ?? [];
|
|
23615
|
+
if (el2.type === "Screen") {
|
|
23616
|
+
const frame = frames.get(k) ?? null;
|
|
23617
|
+
const body = clip(boxes[`${k}#body`] ?? frame, frame);
|
|
23618
|
+
const over = (c2) => OVERLAYS.has(els[c2]?.type);
|
|
23619
|
+
for (const c2 of [...kids.filter((c3) => !over(c3)), ...kids.filter(over)]) visit(c2, k, k, BARS.has(els[c2]?.type) || over(c2) ? frame : body);
|
|
23620
|
+
} else {
|
|
23621
|
+
const inner = el2.type === "Drawer" && boxes[k] ? clip(boxes[k], cut) : cut;
|
|
23622
|
+
for (const c2 of kids) visit(c2, k, inScreen, inner);
|
|
23623
|
+
}
|
|
23624
|
+
};
|
|
23625
|
+
visit(spec.root, null, null, null);
|
|
23626
|
+
if (opts.flows !== false) {
|
|
23627
|
+
const flows = flowEnds(spec);
|
|
23628
|
+
const resolved = flows.resolve(boxes);
|
|
23629
|
+
const ends = new Map(flows.list.map((f) => [f.key, f]));
|
|
23630
|
+
layoutFlows(spec, resolved, flows.screens, flows.gap, paletteFor()).forEach((f) => {
|
|
23631
|
+
const p = els[f.key].props ?? {};
|
|
23632
|
+
const e = ends.get(f.key);
|
|
23633
|
+
out.push({
|
|
23634
|
+
line: lineOf(f.key),
|
|
23635
|
+
endLine: lineOf(f.key),
|
|
23636
|
+
type: "Flow",
|
|
23637
|
+
...f.label ? { label: f.label.text } : {},
|
|
23638
|
+
from: String(p.from),
|
|
23639
|
+
to: String(p.to),
|
|
23640
|
+
fromLine: lineOf(e.from),
|
|
23641
|
+
toLine: lineOf(e.to),
|
|
23642
|
+
path: flowPolyline(f).map((q) => [round(q.x), round(q.y)]),
|
|
23643
|
+
...f.label ? { labelBox: toBox(f.label) } : {}
|
|
23644
|
+
});
|
|
23645
|
+
});
|
|
23646
|
+
}
|
|
23647
|
+
return out;
|
|
23648
|
+
}
|
|
23649
|
+
var inside = (b, x3, y) => !!b && b.width > 0 && b.height > 0 && x3 >= b.x && x3 <= b.x + b.width && y >= b.y && y <= b.y + b.height;
|
|
23650
|
+
var center = (b) => [b.x + b.width / 2, b.y + b.height / 2];
|
|
23651
|
+
function distanceToPath(path, x3, y) {
|
|
23652
|
+
let best = Infinity;
|
|
23653
|
+
for (let i2 = 1; i2 < path.length; i2++) {
|
|
23654
|
+
const [ax, ay] = path[i2 - 1], [bx, by] = path[i2];
|
|
23655
|
+
const dx = bx - ax, dy = by - ay, len = dx * dx + dy * dy;
|
|
23656
|
+
const t = len ? Math.max(0, Math.min(1, ((x3 - ax) * dx + (y - ay) * dy) / len)) : 0;
|
|
23657
|
+
best = Math.min(best, Math.hypot(x3 - ax - t * dx, y - ay - t * dy));
|
|
23658
|
+
}
|
|
23659
|
+
return best;
|
|
23660
|
+
}
|
|
23661
|
+
var isContainer = (e) => CONTAINERS.has(e.type);
|
|
23662
|
+
function elementsAt(elements, x3, y, opts = {}) {
|
|
23663
|
+
const tolerance = opts.tolerance ?? 6;
|
|
23664
|
+
const order = new Map(elements.map((e, i2) => [e, i2]));
|
|
23665
|
+
const topFirst = (a, b) => order.get(b) - order.get(a);
|
|
23666
|
+
const covered = /* @__PURE__ */ new Set();
|
|
23667
|
+
const screens = elements.filter((e) => e.type === "Screen");
|
|
23668
|
+
const screenAround = (b) => screens.find((s) => inside(s.box, ...center(b)));
|
|
23669
|
+
for (const [i2, m2] of elements.entries()) {
|
|
23670
|
+
if (isFlow(m2) || !OVERLAYS.has(m2.type)) continue;
|
|
23671
|
+
const screen = screenAround(m2.box);
|
|
23672
|
+
if (!screen || !inside(m2.box, x3, y) && !(m2.scrim && inside(screen.box, x3, y))) continue;
|
|
23673
|
+
for (const e of elements.slice(0, i2)) if (!isFlow(e) && e.type !== "Screen" && e.type !== "Board" && screenAround(e.box) === screen) covered.add(e);
|
|
23674
|
+
}
|
|
23675
|
+
const owners = [], labels = [], leaves = [], lines = [], containers = [];
|
|
23676
|
+
for (const e of elements) {
|
|
23677
|
+
if (isFlow(e)) {
|
|
23678
|
+
if (inside(e.labelBox, x3, y)) labels.push(e);
|
|
23679
|
+
else if (distanceToPath(e.path, x3, y) <= tolerance) lines.push(e);
|
|
23680
|
+
} else if (e.overlays?.some((o2) => inside(o2, x3, y))) owners.push(e);
|
|
23681
|
+
else if (!covered.has(e) && (inside(e.box, x3, y) || inside(e.labelBox, x3, y))) (isContainer(e) ? containers : leaves).push(e);
|
|
23682
|
+
}
|
|
23683
|
+
return [owners, labels, leaves, lines, containers].flatMap((g2) => g2.sort(topFirst));
|
|
23684
|
+
}
|
|
23685
|
+
function elementsAtLine(elements, line) {
|
|
23686
|
+
return elements.filter((e) => e.line > 0 && e.line <= line && line <= e.endLine).sort((a, b) => b.line - a.line);
|
|
23687
|
+
}
|
|
23688
|
+
|
|
23459
23689
|
// src/playground/language-data.ts
|
|
23460
23690
|
function unwrap4(t) {
|
|
23461
23691
|
let cur = t;
|
|
@@ -23524,11 +23754,14 @@ export {
|
|
|
23524
23754
|
compileWireframe,
|
|
23525
23755
|
componentDefinitions,
|
|
23526
23756
|
decodeWireframe,
|
|
23757
|
+
elementsAt,
|
|
23758
|
+
elementsAtLine,
|
|
23527
23759
|
encodeWireframe,
|
|
23528
23760
|
formatIssues,
|
|
23529
23761
|
printWireframeText as formatWireframe,
|
|
23530
23762
|
languageData,
|
|
23531
23763
|
mcpTools,
|
|
23764
|
+
measureElements,
|
|
23532
23765
|
parseWireframeText,
|
|
23533
23766
|
registry,
|
|
23534
23767
|
renderAll,
|