@weasel-js/ui 1.4.0 → 1.4.1
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/dist/chunks/{Badge-BXTDs-zi.js → Badge-7yQseqZb.js} +233 -263
- package/dist/chunks/Badge-7yQseqZb.js.map +1 -0
- package/dist/chunks/BandEditor-DjOi4ldl.js +252 -0
- package/dist/chunks/BandEditor-DjOi4ldl.js.map +1 -0
- package/dist/chunks/{CurveEditor-Cpuvl_iN.js → CurveEditor-DoX5Q0_V.js} +192 -195
- package/dist/chunks/CurveEditor-DoX5Q0_V.js.map +1 -0
- package/dist/chunks/{DataGrid-BWZZUekH.js → DataGrid-DHV0chfL.js} +2 -5
- package/dist/chunks/DataGrid-DHV0chfL.js.map +1 -0
- package/dist/chunks/{DetentSlider--tQdVQj_.js → DetentSlider-Cd5360U3.js} +2 -2
- package/dist/chunks/{DetentSlider--tQdVQj_.js.map → DetentSlider-Cd5360U3.js.map} +1 -1
- package/dist/chunks/{GradientEditor-C5pPbMa_.js → GradientEditor-CPeTbkFE.js} +11 -9
- package/dist/chunks/{GradientEditor-C5pPbMa_.js.map → GradientEditor-CPeTbkFE.js.map} +1 -1
- package/dist/chunks/{LayerStack-htMwIsJ6.js → LayerStack-BVdwhAhG.js} +2 -5
- package/dist/chunks/{LayerStack-htMwIsJ6.js.map → LayerStack-BVdwhAhG.js.map} +1 -1
- package/dist/chunks/{PaintInput-DtCSGda0.js → PaintInput-6HTUAFL1.js} +2 -2
- package/dist/chunks/{PaintInput-DtCSGda0.js.map → PaintInput-6HTUAFL1.js.map} +1 -1
- package/dist/chunks/{PointPlotter-CR-QGCIf.js → PointPlotter-CZJE8Ccu.js} +2 -2
- package/dist/chunks/{PointPlotter-CR-QGCIf.js.map → PointPlotter-CZJE8Ccu.js.map} +1 -1
- package/dist/chunks/{Powerline--gx4j0Zr.js → Powerline-BY_ADnqq.js} +2 -2
- package/dist/chunks/{Powerline--gx4j0Zr.js.map → Powerline-BY_ADnqq.js.map} +1 -1
- package/dist/chunks/{Properties-BEGlt0Z2.js → Properties-BuNzy7Hb.js} +2 -2
- package/dist/chunks/{Properties-BEGlt0Z2.js.map → Properties-BuNzy7Hb.js.map} +1 -1
- package/dist/chunks/ResizeHandle-DfqqfaZz.js +79 -0
- package/dist/chunks/ResizeHandle-DfqqfaZz.js.map +1 -0
- package/dist/chunks/{SelectionPanel-OfbtyDJH.js → SelectionPanel-BU2cmRtp.js} +2 -2
- package/dist/chunks/{SelectionPanel-OfbtyDJH.js.map → SelectionPanel-BU2cmRtp.js.map} +1 -1
- package/dist/chunks/Slider-BE6jaxyU.js +303 -0
- package/dist/chunks/Slider-BE6jaxyU.js.map +1 -0
- package/dist/chunks/{Timeline-BE7UWajy.js → Timeline-CWuh0nV0.js} +219 -205
- package/dist/chunks/Timeline-CWuh0nV0.js.map +1 -0
- package/dist/chunks/useReorderDragList-UvHJFjTZ.js +106 -0
- package/dist/chunks/useReorderDragList-UvHJFjTZ.js.map +1 -0
- package/dist/components/Badge/Badge.d.ts.map +1 -1
- package/dist/components/Badge/index.js +1 -1
- package/dist/components/Badge/shapes/Perforated.d.ts.map +1 -1
- package/dist/components/Badge/shapes/Shield.d.ts.map +1 -1
- package/dist/components/Badge/useSvgBox.d.ts +10 -0
- package/dist/components/Badge/useSvgBox.d.ts.map +1 -0
- package/dist/components/BandEditor/BandEditor.d.ts.map +1 -1
- package/dist/components/BandEditor/index.js +1 -1
- package/dist/components/CurveEditor/LayeredCurveEditor.d.ts.map +1 -1
- package/dist/components/CurveEditor/index.js +1 -1
- package/dist/components/DataGrid/DataGrid.d.ts.map +1 -1
- package/dist/components/DataGrid/index.js +1 -1
- package/dist/components/DetentSlider/index.js +1 -1
- package/dist/components/GradientEditor/index.js +1 -1
- package/dist/components/LayerStack/LayerStack.d.ts.map +1 -1
- package/dist/components/LayerStack/index.js +1 -1
- package/dist/components/PaintInput/index.js +1 -1
- package/dist/components/PointPlotter/index.js +1 -1
- package/dist/components/Powerline/index.js +2 -2
- package/dist/components/Properties/index.js +1 -1
- package/dist/components/ResizeHandle/ResizeHandle.d.ts.map +1 -1
- package/dist/components/ResizeHandle/index.js +1 -1
- package/dist/components/SelectionPanel/index.js +1 -1
- package/dist/components/Slider/Slider.d.ts.map +1 -1
- package/dist/components/Slider/index.js +1 -1
- package/dist/components/Timeline/Lane.d.ts.map +1 -1
- package/dist/components/Timeline/Ruler.d.ts.map +1 -1
- package/dist/components/Timeline/index.js +1 -1
- package/dist/index.js +16 -16
- package/dist/useReorderDragList.d.ts +20 -7
- package/dist/useReorderDragList.d.ts.map +1 -1
- package/package.json +6 -6
- package/dist/chunks/Badge-BXTDs-zi.js.map +0 -1
- package/dist/chunks/BandEditor-CfLW44uR.js +0 -248
- package/dist/chunks/BandEditor-CfLW44uR.js.map +0 -1
- package/dist/chunks/CurveEditor-Cpuvl_iN.js.map +0 -1
- package/dist/chunks/DataGrid-BWZZUekH.js.map +0 -1
- package/dist/chunks/ResizeHandle-DjGZkPpx.js +0 -81
- package/dist/chunks/ResizeHandle-DjGZkPpx.js.map +0 -1
- package/dist/chunks/Slider-CSwL-Nj9.js +0 -296
- package/dist/chunks/Slider-CSwL-Nj9.js.map +0 -1
- package/dist/chunks/Timeline-BE7UWajy.js.map +0 -1
- package/dist/chunks/useReorderDragList-nQMVwNBd.js +0 -109
- package/dist/chunks/useReorderDragList-nQMVwNBd.js.map +0 -1
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { jsx as e, jsxs as t } from "react/jsx-runtime";
|
|
2
|
+
import { openPointerSession as n } from "@weasel-js/core";
|
|
3
|
+
import { Fragment as r, useEffect as i, useId as a, useRef as o } from "react";
|
|
4
|
+
var s = {
|
|
5
|
+
root: "_root_1mpyk_1",
|
|
6
|
+
label: "_label_1mpyk_11",
|
|
7
|
+
ruler: "_ruler_1mpyk_19",
|
|
8
|
+
tick: "_tick_1mpyk_25",
|
|
9
|
+
tickLabel: "_tickLabel_1mpyk_35",
|
|
10
|
+
bands: "_bands_1mpyk_45",
|
|
11
|
+
band: "_band_1mpyk_45",
|
|
12
|
+
selected: "_selected_1mpyk_92",
|
|
13
|
+
bandContent: "_bandContent_1mpyk_99",
|
|
14
|
+
seam: "_seam_1mpyk_107"
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/components/BandEditor/scale.ts
|
|
18
|
+
function c(e) {
|
|
19
|
+
return e < 0 ? 0 : e > 1 ? 1 : e;
|
|
20
|
+
}
|
|
21
|
+
var l = {
|
|
22
|
+
toUnit: (e, t, n) => n === t ? 0 : (e - t) / (n - t),
|
|
23
|
+
fromUnit: (e, t, n) => t + e * (n - t)
|
|
24
|
+
}, u = {
|
|
25
|
+
toUnit: (e, t, n) => {
|
|
26
|
+
let r = Math.log(t), i = Math.log(n);
|
|
27
|
+
return i === r ? 0 : (Math.log(e) - r) / (i - r);
|
|
28
|
+
},
|
|
29
|
+
fromUnit: (e, t, n) => {
|
|
30
|
+
let r = Math.log(t);
|
|
31
|
+
return Math.exp(r + e * (Math.log(n) - r));
|
|
32
|
+
}
|
|
33
|
+
}, d = !1;
|
|
34
|
+
function f() {
|
|
35
|
+
return typeof process < "u" ? process.env.NODE_ENV !== "production" : !0;
|
|
36
|
+
}
|
|
37
|
+
function p(e, t) {
|
|
38
|
+
let n = e === void 0 || e === "log" ? u : e === "linear" ? l : e;
|
|
39
|
+
return n !== u || t > 0 ? n : (f() && !d && (d = !0, console.warn(`BandEditor: a log scale needs min > 0, but min is ${t}. Falling back to a linear scale. Pass scale="linear" to silence this.`)), l);
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/components/BandEditor/bands.ts
|
|
43
|
+
function m(e, t) {
|
|
44
|
+
let n = e.map((e) => ({ ...e }));
|
|
45
|
+
return n.length > 0 && (n[0].from = t), n;
|
|
46
|
+
}
|
|
47
|
+
function h(e, t, n, r) {
|
|
48
|
+
return [t === 0 ? n : e[t].from, t === e.length - 1 ? r : e[t + 1].from];
|
|
49
|
+
}
|
|
50
|
+
function g(e, t, n, r) {
|
|
51
|
+
return [t === 0 ? n : e[t].from, t + 2 <= e.length - 1 ? e[t + 2].from : r];
|
|
52
|
+
}
|
|
53
|
+
function _(e, t, n, r, i) {
|
|
54
|
+
let [a, o] = g(e, t, r, i);
|
|
55
|
+
return Math.max(a, Math.min(o, n));
|
|
56
|
+
}
|
|
57
|
+
function v(e, t, n) {
|
|
58
|
+
if (e[t + 1] === void 0 || e[t + 1].from === n) return e;
|
|
59
|
+
let r = e.map((e) => ({ ...e }));
|
|
60
|
+
return r[t + 1].from = n, r;
|
|
61
|
+
}
|
|
62
|
+
function y(e, t, n, r) {
|
|
63
|
+
let i = e.map((e, i) => i === 0 ? 0 : c(t.toUnit(e.from, n, r)));
|
|
64
|
+
return i.push(1), i;
|
|
65
|
+
}
|
|
66
|
+
function b(e, t, n) {
|
|
67
|
+
let r = t === 0, i = t === e.length - 2;
|
|
68
|
+
if (r || i) return 0;
|
|
69
|
+
let a = e[t - 1] - e[t], o = e[t + 2] - e[t + 1];
|
|
70
|
+
return Math.max(a, Math.min(o, n));
|
|
71
|
+
}
|
|
72
|
+
function x(e, t, n, r) {
|
|
73
|
+
let i = e.map((e) => ({ ...e }));
|
|
74
|
+
return i[t].from = n, i[t + 1] !== void 0 && (i[t + 1].from = r), i;
|
|
75
|
+
}
|
|
76
|
+
function S(e, t, n, r, i) {
|
|
77
|
+
if (e.length === 0 || t <= n || t >= r) return e;
|
|
78
|
+
let a = -1;
|
|
79
|
+
for (let i = 0; i < e.length; i++) {
|
|
80
|
+
let [o, s] = h(e, i, n, r);
|
|
81
|
+
if (t > o && t < s) {
|
|
82
|
+
a = i;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (a < 0) return e;
|
|
87
|
+
let o = e.map((e) => ({ ...e }));
|
|
88
|
+
return o.splice(a + 1, 0, {
|
|
89
|
+
from: t,
|
|
90
|
+
data: i(t, e[a].data)
|
|
91
|
+
}), o;
|
|
92
|
+
}
|
|
93
|
+
function C(e, t) {
|
|
94
|
+
return t <= 0 || t >= e.length ? e : e.filter((e, n) => n !== t).map((e) => ({ ...e }));
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
//#region src/components/BandEditor/BandEditor.tsx
|
|
98
|
+
var w = 6, T = .01;
|
|
99
|
+
function E(e) {
|
|
100
|
+
return `${c(e) * 100}%`;
|
|
101
|
+
}
|
|
102
|
+
function D(e, t) {
|
|
103
|
+
return t;
|
|
104
|
+
}
|
|
105
|
+
function O(e) {
|
|
106
|
+
if (!(e instanceof HTMLElement)) return !1;
|
|
107
|
+
if (e.isContentEditable) return !0;
|
|
108
|
+
let t = e.tagName;
|
|
109
|
+
return t === "INPUT" || t === "TEXTAREA" || t === "SELECT";
|
|
110
|
+
}
|
|
111
|
+
function k(l) {
|
|
112
|
+
let { value: u, onInput: d, onChange: f, min: k, max: A, scale: j, ticks: M, renderBand: N, selectedIndex: P, onSelect: F, label: I, className: L } = l, R = l.snap ?? !0, z = l.splitBand ?? D, B = o(null), V = o(null);
|
|
113
|
+
i(() => () => {
|
|
114
|
+
V.current?.cancel();
|
|
115
|
+
}, []);
|
|
116
|
+
let H = a(), U = m(u, k), W = p(j, k), G = (e) => c(W.toUnit(e, k, A)), K = (e) => W.fromUnit(c(e), k, A), q = () => B.current?.getBoundingClientRect().width ?? 0, J = (e) => {
|
|
117
|
+
let t = B.current?.getBoundingClientRect();
|
|
118
|
+
return !t || t.width === 0 ? 0 : c((e - t.left) / t.width);
|
|
119
|
+
}, Y = (e, t) => {
|
|
120
|
+
if (!R || t || !M || M.length === 0) return e;
|
|
121
|
+
let n = q();
|
|
122
|
+
if (n === 0) return e;
|
|
123
|
+
let r = e, i = w / n;
|
|
124
|
+
for (let t of M) {
|
|
125
|
+
let n = G(t.at), a = Math.abs(n - e);
|
|
126
|
+
a <= i && (i = a, r = n);
|
|
127
|
+
}
|
|
128
|
+
return r;
|
|
129
|
+
}, X = (e, t, r) => {
|
|
130
|
+
V.current?.cancel(), V.current = n(e.currentTarget, e, {
|
|
131
|
+
onMove: t,
|
|
132
|
+
onEnd: () => {
|
|
133
|
+
V.current = null, r();
|
|
134
|
+
},
|
|
135
|
+
onCancel: () => {
|
|
136
|
+
V.current = null;
|
|
137
|
+
}
|
|
138
|
+
}, { capture: !1 });
|
|
139
|
+
}, Z = (e) => (t) => {
|
|
140
|
+
if (typeof t.button == "number" && t.button > 0) return;
|
|
141
|
+
t.preventDefault(), t.stopPropagation();
|
|
142
|
+
let n = U, r = null;
|
|
143
|
+
X(t, (t) => {
|
|
144
|
+
r = v(n, e, _(n, e, K(Y(J(t.clientX), t.altKey)), k, A)), d?.(r);
|
|
145
|
+
}, () => {
|
|
146
|
+
r && f(r);
|
|
147
|
+
});
|
|
148
|
+
}, Q = (e) => (t) => {
|
|
149
|
+
let [n, r] = g(U, e, k, A), i;
|
|
150
|
+
if (t.key === "Home") i = n;
|
|
151
|
+
else if (t.key === "End") i = r;
|
|
152
|
+
else {
|
|
153
|
+
let n = 0;
|
|
154
|
+
if (t.key === "ArrowRight" || t.key === "ArrowUp") n = t.shiftKey ? T * 10 : T;
|
|
155
|
+
else if (t.key === "ArrowLeft" || t.key === "ArrowDown") n = t.shiftKey ? -T * 10 : -T;
|
|
156
|
+
else return;
|
|
157
|
+
i = K(G(U[e + 1].from) + n);
|
|
158
|
+
}
|
|
159
|
+
t.preventDefault();
|
|
160
|
+
let a = v(U, e, _(U, e, i, k, A));
|
|
161
|
+
a !== U && f(a);
|
|
162
|
+
}, $ = (e) => (t) => {
|
|
163
|
+
if (typeof t.button == "number" && t.button > 0 || (e !== P && F?.(e), e === 0 || e === U.length - 1)) return;
|
|
164
|
+
let n = U, r = y(n, W, k, A), i = J(t.clientX), a = null;
|
|
165
|
+
X(t, (t) => {
|
|
166
|
+
let o = b(r, e, J(t.clientX) - i);
|
|
167
|
+
a = x(n, e, K(r[e] + o), K(r[e + 1] + o)), d?.(a);
|
|
168
|
+
}, () => {
|
|
169
|
+
a && f(a);
|
|
170
|
+
});
|
|
171
|
+
}, ee = (e) => () => {
|
|
172
|
+
e !== P && F?.(e);
|
|
173
|
+
};
|
|
174
|
+
return /* @__PURE__ */ t("div", {
|
|
175
|
+
className: [s.root, L].filter(Boolean).join(" "),
|
|
176
|
+
role: "group",
|
|
177
|
+
"aria-label": typeof I == "string" ? I : void 0,
|
|
178
|
+
"aria-labelledby": I !== void 0 && typeof I != "string" ? H : void 0,
|
|
179
|
+
onKeyDown: (e) => {
|
|
180
|
+
if (e.key !== "x" && e.key !== "Delete" || e.metaKey || e.ctrlKey || e.altKey || O(e.target) || P == null) return;
|
|
181
|
+
let t = C(U, P);
|
|
182
|
+
t !== U && (e.preventDefault(), f(t), F?.(P - 1));
|
|
183
|
+
},
|
|
184
|
+
children: [
|
|
185
|
+
I !== void 0 && /* @__PURE__ */ e("div", {
|
|
186
|
+
id: H,
|
|
187
|
+
className: s.label,
|
|
188
|
+
children: I
|
|
189
|
+
}),
|
|
190
|
+
/* @__PURE__ */ e("div", {
|
|
191
|
+
className: s.ruler,
|
|
192
|
+
ref: B,
|
|
193
|
+
"data-band-ruler": "",
|
|
194
|
+
onPointerDown: (e) => {
|
|
195
|
+
if (typeof e.button == "number" && e.button > 0) return;
|
|
196
|
+
e.preventDefault();
|
|
197
|
+
let t = S(U, K(J(e.clientX)), k, A, z);
|
|
198
|
+
t !== U && f(t);
|
|
199
|
+
},
|
|
200
|
+
children: M?.map((t, n) => /* @__PURE__ */ e("span", {
|
|
201
|
+
className: s.tick,
|
|
202
|
+
"data-tick-at": t.at,
|
|
203
|
+
style: { "--be-at": E(G(t.at)) },
|
|
204
|
+
children: t.label !== void 0 && /* @__PURE__ */ e("span", {
|
|
205
|
+
className: s.tickLabel,
|
|
206
|
+
children: t.label
|
|
207
|
+
})
|
|
208
|
+
}, n))
|
|
209
|
+
}),
|
|
210
|
+
/* @__PURE__ */ e("div", {
|
|
211
|
+
className: s.bands,
|
|
212
|
+
children: U.map((n, i) => {
|
|
213
|
+
let [a, o] = h(U, i, k, A), c = P === i;
|
|
214
|
+
return /* @__PURE__ */ t(r, { children: [/* @__PURE__ */ e("button", {
|
|
215
|
+
type: "button",
|
|
216
|
+
className: [s.band, c ? s.selected : null].filter(Boolean).join(" "),
|
|
217
|
+
style: {
|
|
218
|
+
"--be-from": E(G(a)),
|
|
219
|
+
"--be-to": E(G(o))
|
|
220
|
+
},
|
|
221
|
+
"aria-label": `Band ${i + 1}`,
|
|
222
|
+
"aria-pressed": c,
|
|
223
|
+
"data-band-index": i,
|
|
224
|
+
onPointerDown: $(i),
|
|
225
|
+
onFocus: ee(i),
|
|
226
|
+
children: /* @__PURE__ */ e("span", {
|
|
227
|
+
className: s.bandContent,
|
|
228
|
+
children: N?.(n, i)
|
|
229
|
+
})
|
|
230
|
+
}), i < U.length - 1 && /* @__PURE__ */ e("div", {
|
|
231
|
+
role: "slider",
|
|
232
|
+
tabIndex: 0,
|
|
233
|
+
className: s.seam,
|
|
234
|
+
style: { "--be-at": E(G(U[i + 1].from)) },
|
|
235
|
+
"aria-label": `Seam ${i + 1}`,
|
|
236
|
+
"aria-orientation": "horizontal",
|
|
237
|
+
"aria-valuemin": g(U, i, k, A)[0],
|
|
238
|
+
"aria-valuemax": g(U, i, k, A)[1],
|
|
239
|
+
"aria-valuenow": U[i + 1].from,
|
|
240
|
+
"data-seam-index": i,
|
|
241
|
+
onPointerDown: Z(i),
|
|
242
|
+
onKeyDown: Q(i)
|
|
243
|
+
})] }, i);
|
|
244
|
+
})
|
|
245
|
+
})
|
|
246
|
+
]
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
//#endregion
|
|
250
|
+
export { l as n, u as r, k as t };
|
|
251
|
+
|
|
252
|
+
//# sourceMappingURL=BandEditor-DjOi4ldl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BandEditor-DjOi4ldl.js","names":[],"sources":["../../src/components/BandEditor/BandEditor.module.css","../../src/components/BandEditor/scale.ts","../../src/components/BandEditor/bands.ts","../../src/components/BandEditor/BandEditor.tsx"],"sourcesContent":[".root {\n position: relative;\n user-select: none;\n -webkit-user-select: none;\n touch-action: none;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.label {\n font: var(--wzl-font-weight-medium) var(--wzl-font-size-sm) / var(--wzl-leading-tight) var(--wzl-font-ui);\n color: var(--wzl-fg-muted);\n}\n\n/* The ruler carries the ticks and is the split affordance: a click anywhere\n * on it divides the band underneath. The band strip below owns selection and\n * body drags, so neither gesture has to guess which the pointer meant. */\n.ruler {\n position: relative;\n height: var(--be-ruler-height, 20px);\n cursor: crosshair;\n}\n\n.tick {\n position: absolute;\n left: var(--be-at);\n bottom: 0;\n width: 1px;\n height: 6px;\n background: var(--wzl-fg-subtle);\n pointer-events: none;\n}\n\n.tickLabel {\n position: absolute;\n bottom: 7px;\n left: 0;\n transform: translateX(-50%);\n font: var(--wzl-font-weight-medium) var(--wzl-font-size-xs) / var(--wzl-leading-tight) var(--wzl-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);\n color: var(--wzl-fg-muted);\n white-space: nowrap;\n}\n\n.bands {\n position: relative;\n height: var(--be-band-height, 34px);\n}\n\n.band {\n position: absolute;\n top: 0;\n bottom: 0;\n left: var(--be-from);\n width: calc(var(--be-to) - var(--be-from));\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n padding: 0 4px;\n margin: 0;\n background: var(--wzl-surface-raised);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n color: var(--wzl-fg);\n font: var(--wzl-font-weight-medium) var(--wzl-font-size-sm) / var(--wzl-leading-tight) var(--wzl-font-ui, ui-sans-serif, system-ui, sans-serif);\n cursor: grab;\n}\n\n.band:hover {\n background: var(--wzl-surface-hover);\n}\n\n.band:active {\n cursor: grabbing;\n}\n\n.band:focus-visible {\n outline: 2px solid var(--wzl-accent);\n outline-offset: -2px;\n}\n\n/* First and last bands are pinned to `min` / `max`, so their bodies do not\n * translate — the cursor should not promise otherwise. */\n.band:first-of-type,\n.band:last-of-type {\n cursor: default;\n}\n\n/* Accent mixed toward transparent rather than a flat token, so the tint\n reads over whatever surface the consumer's theme puts behind it. */\n.selected {\n background: color-mix(in srgb, var(--wzl-accent) 22%, transparent);\n border-color: var(--wzl-accent);\n box-shadow: inset 0 0 0 1px var(--wzl-accent);\n color: var(--wzl-fg);\n}\n\n.bandContent {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n pointer-events: none;\n}\n\n/* Wider than the line it draws: a 1px seam is unhittable. */\n.seam {\n position: absolute;\n left: var(--be-at);\n top: -3px;\n bottom: -3px;\n width: 11px;\n margin-left: -5px;\n z-index: 1;\n cursor: ew-resize;\n background: none;\n border: none;\n}\n\n.seam::before {\n content: '';\n position: absolute;\n top: 0;\n bottom: 0;\n left: 5px;\n width: 1px;\n background: var(--wzl-border-strong);\n}\n\n.seam:hover::before,\n.seam:focus-visible::before {\n background: var(--wzl-accent);\n width: 2px;\n}\n\n.seam:focus-visible {\n outline: 2px solid var(--wzl-accent);\n outline-offset: 0;\n border-radius: var(--wzl-radius-sm);\n}\n","/**\n * Maps a domain value onto its position along the track, and back.\n *\n * Deliberately narrow — two functions over an explicit `[min, max]` — rather\n * than a general scale type for the package. `Plot2D`, `CurveEditor` and\n * `@weasel-js/core` each already use \"scale\" or \"domain\" to mean something\n * else; generalizing is a job for a second consumer that needs one.\n */\nexport interface BandScale {\n /** Domain → position in [0,1]. Must be monotonic increasing. */\n toUnit(value: number, min: number, max: number): number;\n /** Inverse of `toUnit`. */\n fromUnit(unit: number, min: number, max: number): number;\n}\n\nexport function clamp01(u: number): number {\n return u < 0 ? 0 : u > 1 ? 1 : u;\n}\n\n/** Even domain steps take even track steps. */\nexport const linearScale: BandScale = {\n toUnit: (value, min, max) => (max === min ? 0 : (value - min) / (max - min)),\n fromUnit: (unit, min, max) => min + unit * (max - min),\n};\n\n/** Even *ratios* take even track steps. Requires `min > 0`. */\nexport const logScale: BandScale = {\n toUnit: (value, min, max) => {\n const lo = Math.log(min);\n const hi = Math.log(max);\n return hi === lo ? 0 : (Math.log(value) - lo) / (hi - lo);\n },\n fromUnit: (unit, min, max) => {\n const lo = Math.log(min);\n return Math.exp(lo + unit * (Math.log(max) - lo));\n },\n};\n\nlet warnedNonPositiveMin = false;\n\nfunction isDev(): boolean {\n return typeof process !== 'undefined' ? process.env.NODE_ENV !== 'production' : true;\n}\n\n/**\n * Resolves the `scale` prop, substituting `linearScale` for a `logScale`\n * that `min` would send to `NaN`.\n */\nexport function resolveScale(\n scale: 'linear' | 'log' | BandScale | undefined,\n min: number,\n): BandScale {\n const requested =\n scale === undefined || scale === 'log'\n ? logScale\n : scale === 'linear'\n ? linearScale\n : scale;\n\n if (requested !== logScale || min > 0) return requested;\n\n if (isDev() && !warnedNonPositiveMin) {\n warnedNonPositiveMin = true;\n console.warn(\n `BandEditor: a log scale needs min > 0, but min is ${min}. Falling back to a linear scale. ` +\n `Pass scale=\"linear\" to silence this.`,\n );\n }\n return linearScale;\n}\n","import type { BandScale } from './scale';\nimport { clamp01 } from './scale';\n\nexport interface Band<T> {\n /** Domain value where this band starts. The first band's is normalized to `min`. */\n from: number;\n data: T;\n}\n\n/**\n * A band list covers `[min, max]` exactly: N bands, N−1 interior seams, no\n * gaps and no overlaps. Seam *k* is `bands[k + 1].from`, and lives between\n * `bands[k].from` and the start of the band after next (or `max`).\n *\n * Every function here preserves that. Each returns the array it was given\n * when the edit would be a no-op, so callers can skip a callback with `===`.\n */\n\n/** Pins the first band's start to `min`; leaves the rest alone. */\nexport function normalizeBands<T>(value: readonly Band<T>[], min: number): Band<T>[] {\n const bands = value.map((b) => ({ ...b }));\n if (bands.length > 0) bands[0].from = min;\n return bands;\n}\n\n/** `[from, to]` of band `index` in domain space. */\nexport function bandBounds<T>(\n bands: readonly Band<T>[],\n index: number,\n min: number,\n max: number,\n): [number, number] {\n const from = index === 0 ? min : bands[index].from;\n const to = index === bands.length - 1 ? max : bands[index + 1].from;\n return [from, to];\n}\n\n/** How far seam `index` can travel before it would cross a neighbour. */\nexport function seamBounds<T>(\n bands: readonly Band<T>[],\n index: number,\n min: number,\n max: number,\n): [number, number] {\n const lo = index === 0 ? min : bands[index].from;\n const hi = index + 2 <= bands.length - 1 ? bands[index + 2].from : max;\n return [lo, hi];\n}\n\n/** Clamps a target position for seam `index` to its neighbours, inclusive. */\nexport function clampSeamTo<T>(\n bands: readonly Band<T>[],\n index: number,\n to: number,\n min: number,\n max: number,\n): number {\n const [lo, hi] = seamBounds(bands, index, min, max);\n return Math.max(lo, Math.min(hi, to));\n}\n\nexport function setSeam<T>(bands: readonly Band<T>[], index: number, to: number): Band<T>[] {\n if (bands[index + 1] === undefined || bands[index + 1].from === to) return bands as Band<T>[];\n const next = bands.map((b) => ({ ...b }));\n next[index + 1].from = to;\n return next;\n}\n\n/** Band edges as track positions: `length + 1` values from 0 to 1. */\nexport function unitEdges<T>(\n bands: readonly Band<T>[],\n scale: BandScale,\n min: number,\n max: number,\n): number[] {\n const edges = bands.map((b, i) => (i === 0 ? 0 : clamp01(scale.toUnit(b.from, min, max))));\n edges.push(1);\n return edges;\n}\n\n/**\n * Largest part of `shift` band `index` can take without pushing a neighbour's\n * far edge past it. Zero for the first and last band, whose outer edges are\n * `min` and `max` and do not move.\n */\nexport function clampBandShift(edges: readonly number[], index: number, shift: number): number {\n const isFirst = index === 0;\n const isLast = index === edges.length - 2;\n if (isFirst || isLast) return 0;\n const lo = edges[index - 1] - edges[index];\n const hi = edges[index + 2] - edges[index + 1];\n return Math.max(lo, Math.min(hi, shift));\n}\n\n/** Moves both edges of band `index`, which is the same as moving two seams. */\nexport function moveBandEdges<T>(\n bands: readonly Band<T>[],\n index: number,\n from: number,\n to: number,\n): Band<T>[] {\n const next = bands.map((b) => ({ ...b }));\n next[index].from = from;\n if (next[index + 1] !== undefined) next[index + 1].from = to;\n return next;\n}\n\n/**\n * Splits the band containing `at` in two, the new band starting there.\n * A position already on a seam or on `min` / `max` splits nothing.\n */\nexport function splitBands<T>(\n bands: readonly Band<T>[],\n at: number,\n min: number,\n max: number,\n makeData: (at: number, from: T) => T,\n): Band<T>[] {\n if (bands.length === 0 || at <= min || at >= max) return bands as Band<T>[];\n let index = -1;\n for (let i = 0; i < bands.length; i++) {\n const [from, to] = bandBounds(bands, i, min, max);\n if (at > from && at < to) {\n index = i;\n break;\n }\n }\n if (index < 0) return bands as Band<T>[];\n const next = bands.map((b) => ({ ...b }));\n next.splice(index + 1, 0, { from: at, data: makeData(at, bands[index].data) });\n return next;\n}\n\n/**\n * Merges band `index` into its left neighbour, which keeps its payload and\n * absorbs the span. The first band has no left neighbour and cannot be\n * merged away — a partition always has at least one part.\n */\nexport function mergeBand<T>(bands: readonly Band<T>[], index: number): Band<T>[] {\n if (index <= 0 || index >= bands.length) return bands as Band<T>[];\n return bands.filter((_, i) => i !== index).map((b) => ({ ...b }));\n}\n","import {\n Fragment,\n useEffect,\n useId,\n useRef,\n type CSSProperties,\n type KeyboardEvent as ReactKeyboardEvent,\n type PointerEvent as ReactPointerEvent,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { openPointerSession, type PointerSession } from '@weasel-js/core';\nimport s from './BandEditor.module.css';\nimport { clamp01, resolveScale, type BandScale } from './scale';\nimport {\n bandBounds,\n clampBandShift,\n clampSeamTo,\n mergeBand,\n moveBandEdges,\n normalizeBands,\n seamBounds,\n setSeam,\n splitBands,\n unitEdges,\n type Band,\n} from './bands';\n\nexport type { Band, BandScale };\n\nexport interface BandEditorProps<T> {\n /** Ascending by `from`. `value[0].from` is normalized to `min` on read. */\n value: Band<T>[];\n /** Live during a drag — wire for preview, do not write to history. */\n onInput?: (next: Band<T>[]) => void;\n /** Committed at gesture end: one call per gesture. */\n onChange: (next: Band<T>[]) => void;\n min: number;\n max: number;\n /** Default `'log'`. */\n scale?: 'linear' | 'log' | BandScale;\n ticks?: { at: number; label?: ReactNode }[];\n /** Snap a dragged seam to a tick within ~6px. Default true; `alt` defeats it per-drag. */\n snap?: boolean;\n renderBand?: (band: Band<T>, index: number) => ReactNode;\n selectedIndex?: number | null;\n onSelect?: (index: number) => void;\n /** Payload for a band split off an existing one. Default duplicates `from`. */\n splitBand?: (at: number, from: T) => T;\n label?: ReactNode;\n className?: string;\n}\n\n/** Snap radius, in track pixels. */\nconst SNAP_PX = 6;\n\n/** One arrow-key step, as a fraction of the track. */\nconst KEY_STEP = 0.01;\n\nfunction pct(unit: number): string {\n return `${clamp01(unit) * 100}%`;\n}\n\nfunction keepData<T>(_at: number, from: T): T {\n return from;\n}\n\nfunction isTextEntry(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n if (target.isContentEditable) return true;\n const tag = target.tagName;\n return tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT';\n}\n\n/**\n * Divides a numeric axis into contiguous bands and lets you drag the seams\n * between them. Each band carries a payload the consumer supplies and\n * renders through `renderBand`; the control itself knows nothing about what\n * a band means.\n *\n * The axis is always fully covered — N bands, N−1 interior seams, no gaps and\n * no overlaps — so editing is editing a sorted list of seam positions. Seams\n * clamp at their neighbours rather than crossing, which means a drag can\n * never destroy a band: removal is only ever the explicit `x` / `Delete`\n * merge. The first band is doubly exceptional, its left edge pinned to `min`\n * and its body immovable, and it has no left neighbour to merge into.\n *\n * | Gesture | Effect |\n * |---|---|\n * | drag a seam | resize the two bands either side |\n * | drag a band body | move both its seams, preserving its span |\n * | click the ruler | split the band under the pointer |\n * | `x` / `Delete` | merge the selected band into its left neighbour |\n * | click a band | select it |\n * | `←` `→` on a focused seam | move it by one step; `shift` for ten |\n *\n * `scale` defaults to `'log'`, because the interesting part of a width axis\n * is usually its narrow end.\n */\nexport function BandEditor<T>(props: BandEditorProps<T>): ReactElement {\n const {\n value,\n onInput,\n onChange,\n min,\n max,\n scale,\n ticks,\n renderBand,\n selectedIndex,\n onSelect,\n label,\n className,\n } = props;\n const snap = props.snap ?? true;\n const splitBand = props.splitBand ?? keepData;\n\n const trackRef = useRef<HTMLDivElement | null>(null);\n const sessionRef = useRef<PointerSession | null>(null);\n useEffect(() => () => { sessionRef.current?.cancel(); }, []);\n const labelId = useId();\n const bands = normalizeBands(value, min);\n const sc = resolveScale(scale, min);\n const toUnit = (v: number): number => clamp01(sc.toUnit(v, min, max));\n const fromUnit = (u: number): number => sc.fromUnit(clamp01(u), min, max);\n\n const trackWidth = (): number => trackRef.current?.getBoundingClientRect().width ?? 0;\n\n const unitAt = (clientX: number): number => {\n const rect = trackRef.current?.getBoundingClientRect();\n if (!rect || rect.width === 0) return 0;\n return clamp01((clientX - rect.left) / rect.width);\n };\n\n const snapped = (unit: number, altKey: boolean): number => {\n if (!snap || altKey || !ticks || ticks.length === 0) return unit;\n const width = trackWidth();\n if (width === 0) return unit;\n let best = unit;\n let bestDistance = SNAP_PX / width;\n for (const tick of ticks) {\n const tickUnit = toUnit(tick.at);\n const distance = Math.abs(tickUnit - unit);\n if (distance <= bestDistance) {\n bestDistance = distance;\n best = tickUnit;\n }\n }\n return best;\n };\n\n // No pointer capture: a band body is a `<button>` whose content the consumer\n // renders, and capture would retarget pointerup and kill the click on it.\n // A drag that ends without a release commits nothing.\n const drag = (\n down: ReactPointerEvent<HTMLElement>,\n onMove: (ev: PointerEvent) => void,\n onEnd: () => void,\n ): void => {\n sessionRef.current?.cancel();\n sessionRef.current = openPointerSession(down.currentTarget, down, {\n onMove,\n onEnd: () => { sessionRef.current = null; onEnd(); },\n onCancel: () => { sessionRef.current = null; },\n }, { capture: false });\n };\n\n const onSeamPointerDown = (index: number) => (e: ReactPointerEvent<HTMLDivElement>): void => {\n if (typeof e.button === 'number' && e.button > 0) return;\n e.preventDefault();\n e.stopPropagation();\n const base = bands;\n let latest: Band<T>[] | null = null;\n drag(\n e,\n (ev) => {\n const to = clampSeamTo(base, index, fromUnit(snapped(unitAt(ev.clientX), ev.altKey)), min, max);\n latest = setSeam(base, index, to);\n onInput?.(latest);\n },\n () => {\n if (latest) onChange(latest);\n },\n );\n };\n\n const onSeamKeyDown = (index: number) => (e: ReactKeyboardEvent<HTMLDivElement>): void => {\n const [lo, hi] = seamBounds(bands, index, min, max);\n let target: number;\n if (e.key === 'Home') target = lo;\n else if (e.key === 'End') target = hi;\n else {\n let delta = 0;\n if (e.key === 'ArrowRight' || e.key === 'ArrowUp') delta = e.shiftKey ? KEY_STEP * 10 : KEY_STEP;\n else if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') delta = e.shiftKey ? -KEY_STEP * 10 : -KEY_STEP;\n else return;\n target = fromUnit(toUnit(bands[index + 1].from) + delta);\n }\n e.preventDefault();\n const next = setSeam(bands, index, clampSeamTo(bands, index, target, min, max));\n if (next !== bands) onChange(next);\n };\n\n const onBandPointerDown = (index: number) => (e: ReactPointerEvent<HTMLButtonElement>): void => {\n if (typeof e.button === 'number' && e.button > 0) return;\n if (index !== selectedIndex) onSelect?.(index);\n // The first and last bands' outer edges are `min` and `max`, which do not\n // move, so their bodies have nothing to translate.\n if (index === 0 || index === bands.length - 1) return;\n const base = bands;\n const edges = unitEdges(base, sc, min, max);\n const startUnit = unitAt(e.clientX);\n let latest: Band<T>[] | null = null;\n drag(\n e,\n (ev) => {\n const shift = clampBandShift(edges, index, unitAt(ev.clientX) - startUnit);\n latest = moveBandEdges(\n base,\n index,\n fromUnit(edges[index] + shift),\n fromUnit(edges[index + 1] + shift),\n );\n onInput?.(latest);\n },\n () => {\n if (latest) onChange(latest);\n },\n );\n };\n\n const onBandFocus = (index: number) => (): void => {\n if (index !== selectedIndex) onSelect?.(index);\n };\n\n const onTrackPointerDown = (e: ReactPointerEvent<HTMLDivElement>): void => {\n if (typeof e.button === 'number' && e.button > 0) return;\n e.preventDefault();\n const next = splitBands(bands, fromUnit(unitAt(e.clientX)), min, max, splitBand);\n if (next !== bands) onChange(next);\n };\n\n const onRootKeyDown = (e: ReactKeyboardEvent<HTMLDivElement>): void => {\n if (e.key !== 'x' && e.key !== 'Delete') return;\n // `x` is a bare letter and Cmd/Ctrl+X is cut: neither may be swallowed\n // when the keystroke belongs to something a consumer put in a band.\n if (e.metaKey || e.ctrlKey || e.altKey) return;\n if (isTextEntry(e.target)) return;\n if (selectedIndex === null || selectedIndex === undefined) return;\n const next = mergeBand(bands, selectedIndex);\n if (next === bands) return;\n e.preventDefault();\n onChange(next);\n onSelect?.(selectedIndex - 1);\n };\n\n return (\n <div\n className={[s.root, className].filter(Boolean).join(' ')}\n role=\"group\"\n aria-label={typeof label === 'string' ? label : undefined}\n aria-labelledby={label !== undefined && typeof label !== 'string' ? labelId : undefined}\n onKeyDown={onRootKeyDown}\n >\n {label !== undefined && <div id={labelId} className={s.label}>{label}</div>}\n <div className={s.ruler} ref={trackRef} data-band-ruler=\"\" onPointerDown={onTrackPointerDown}>\n {ticks?.map((tick, i) => (\n <span\n key={i}\n className={s.tick}\n data-tick-at={tick.at}\n style={{ '--be-at': pct(toUnit(tick.at)) } as CSSProperties}\n >\n {tick.label !== undefined && <span className={s.tickLabel}>{tick.label}</span>}\n </span>\n ))}\n </div>\n <div className={s.bands}>\n {bands.map((band, i) => {\n const [from, to] = bandBounds(bands, i, min, max);\n const isSelected = selectedIndex === i;\n return (\n <Fragment key={i}>\n <button\n type=\"button\"\n className={[s.band, isSelected ? s.selected : null].filter(Boolean).join(' ')}\n style={{ '--be-from': pct(toUnit(from)), '--be-to': pct(toUnit(to)) } as CSSProperties}\n aria-label={`Band ${i + 1}`}\n aria-pressed={isSelected}\n data-band-index={i}\n onPointerDown={onBandPointerDown(i)}\n onFocus={onBandFocus(i)}\n >\n <span className={s.bandContent}>{renderBand?.(band, i)}</span>\n </button>\n {i < bands.length - 1 && (\n <div\n role=\"slider\"\n tabIndex={0}\n className={s.seam}\n style={{ '--be-at': pct(toUnit(bands[i + 1].from)) } as CSSProperties}\n aria-label={`Seam ${i + 1}`}\n aria-orientation=\"horizontal\"\n aria-valuemin={seamBounds(bands, i, min, max)[0]}\n aria-valuemax={seamBounds(bands, i, min, max)[1]}\n aria-valuenow={bands[i + 1].from}\n data-seam-index={i}\n onPointerDown={onSeamPointerDown(i)}\n onKeyDown={onSeamKeyDown(i)}\n />\n )}\n </Fragment>\n );\n })}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|