@spotlab/hand-matrix 0.3.0 → 0.4.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/README.md CHANGED
@@ -95,13 +95,16 @@ goes in as props and changes come out through `on*Change` callbacks.
95
95
  produces).
96
96
  - `cellsToComboWeights(cells, actionIndex): Map<string, number>` — collapse
97
97
  one action back to absolute per-combo weights, ready to save as a range.
98
- - `cellsToRanges(original, seed, cells): HandFrequency[][]` — turn the
99
- edited grid back into one hand-keyed range per action. `original` holds
100
- each action's range (or `null`) in editor action order, `seed` the cells
101
- the editor opened with, and `cells` the cells after editing. Combos whose
102
- cell still matches its seed keep each action's original hands verbatim;
103
- changed combos, and every combo of a `null` action, are rebuilt from the
104
- cells.
98
+ - `cellsToRanges(original, seed, cells, avail?): HandFrequency[][]` — turn
99
+ the edited grid back into one hand-keyed range per action. `original`
100
+ holds each action's range (or `null`) in editor action order, `seed` the
101
+ cells the editor opened with, and `cells` the cells after editing.
102
+ `avail` is the parent range per hand (`null` for unconstrained); leave it
103
+ out when the parent gives every hand of a combo the same weight. Combos
104
+ whose cell still matches its seed keep each action's original hands
105
+ verbatim, and a `null` action takes what's left of each hand there.
106
+ Changed combos are rebuilt from the cells. Either way, each hand's
107
+ actions sum to its parent weight.
105
108
  - `comboWeightsToCells(cells, actionWeights, passive): EditorCell[]` — the
106
109
  inverse: re-derive the cells' conditional weights from absolute
107
110
  per-action ranges, keeping each cell's `avail`.
@@ -31,17 +31,23 @@ export declare function comboWeightsToCells(cells: EditorCell[], actionWeights:
31
31
  * Turn an edited grid back into one hand-keyed range per action, keeping each
32
32
  * action's original hands wherever the editor didn't touch them. `original`
33
33
  * holds each action's range in editor action order, `seed` the cells the
34
- * editor opened with, and `cells` the cells after editing.
34
+ * editor opened with, and `cells` the cells after editing. `avail` is the
35
+ * parent range per hand, as passed (collapsed) to `seedCells`: `null` means
36
+ * unconstrained, and leaving it out takes each hand's weight from its cell's
37
+ * `avail`, which is exact whenever the parent gives every hand of a combo the
38
+ * same weight.
35
39
  *
36
40
  * A combo whose cell still equals its seed cell (same `avail`, same weights)
37
41
  * keeps every action's original hands verbatim, so input the whole-percent grid
38
42
  * can't represent — a single suit (`AhKh:0.7`) or a fractional weight
39
- * (`QQ:0.333`) — survives a save. A changed combo is rebuilt from the cells as
40
- * `cellsToComboWeights` does. An action whose original is `null` (e.g. an
41
- * implicit fold) is always rebuilt from the cells in full.
43
+ * (`QQ:0.333`) — survives a save. An action whose original is `null` (e.g. an
44
+ * implicit fold) takes what's left of each hand there: its parent weight minus
45
+ * the preserved originals, never below 0, split across `null` actions by their
46
+ * cell weights. A changed combo is rebuilt from its cell for every action, each
47
+ * hand getting the action's share of its own parent weight.
42
48
  *
43
49
  * Each rebuilt combo takes its first original hand's place, and combos the
44
50
  * original didn't have follow in matrix order, so an unedited range formats
45
51
  * back to the string it came from.
46
52
  */
47
- export declare function cellsToRanges(original: (HandFrequency[] | null)[], seed: EditorCell[], cells: EditorCell[]): HandFrequency[][];
53
+ export declare function cellsToRanges(original: (HandFrequency[] | null)[], seed: EditorCell[], cells: EditorCell[], avail?: HandFrequency[] | null): HandFrequency[][];
package/dist/index.js CHANGED
@@ -1,69 +1,69 @@
1
- import { useCallback as g, useEffect as N, useLayoutEffect as S, useMemo as I, useRef as b } from "react";
2
- import { COMBOS as v, comboOf as A, expandComboWeights as M, parseRange as P, toComboWeights as W } from "@spotlab/range";
3
- import { jsx as p, jsxs as w } from "react/jsx-runtime";
4
- var D = (t, e) => Array.from({ length: Math.ceil(t.length / e) }, (n, r) => t.slice(r * e, r * e + e)), T = "to right", R = (t) => t.length === 0 ? "transparent" : `linear-gradient(${T}, ${t.join(", ")})`, O = (t) => {
1
+ import { useCallback as M, useEffect as x, useLayoutEffect as P, useMemo as T, useRef as $ } from "react";
2
+ import { COMBOS as C, comboOf as W, handsOfCombo as D, parseRange as F, toComboWeights as B } from "@spotlab/range";
3
+ import { jsx as g, jsxs as y } from "react/jsx-runtime";
4
+ var X = (t, e) => Array.from({ length: Math.ceil(t.length / e) }, (n, r) => t.slice(r * e, r * e + e)), _ = "to right", L = (t) => t.length === 0 ? "transparent" : `linear-gradient(${_}, ${t.join(", ")})`, j = (t) => {
5
5
  const e = t.target;
6
6
  e.hasPointerCapture(t.pointerId) && e.releasePointerCapture(t.pointerId);
7
- }, $ = (t, e, n) => {
7
+ }, E = (t, e, n) => {
8
8
  const r = t.ownerDocument.elementFromPoint(e, n)?.closest("[data-combo]");
9
9
  return !r || !t.contains(r) ? null : r.getAttribute("data-combo");
10
- }, B = ({ combo: t, onPointerDown: e, comboStyle: n }) => /* @__PURE__ */ p("div", {
10
+ }, q = ({ combo: t, onPointerDown: e, comboStyle: n }) => /* @__PURE__ */ g("div", {
11
11
  className: "spotlab-hm-cell",
12
12
  "data-combo": t,
13
13
  style: n?.(t),
14
14
  onPointerDown: e && ((r) => {
15
- O(r), e(t, r);
15
+ j(r), e(t, r);
16
16
  }),
17
- children: /* @__PURE__ */ p("div", {
17
+ children: /* @__PURE__ */ g("div", {
18
18
  className: "spotlab-hm-cell-inner",
19
- children: /* @__PURE__ */ p("div", {
19
+ children: /* @__PURE__ */ g("div", {
20
20
  "data-combo": t,
21
21
  children: t
22
22
  })
23
23
  })
24
- }), F = ({ row: t, ...e }) => /* @__PURE__ */ p("div", {
24
+ }), G = ({ row: t, ...e }) => /* @__PURE__ */ g("div", {
25
25
  className: "spotlab-hm-row",
26
- children: t.map((n, r) => /* @__PURE__ */ p(B, {
26
+ children: t.map((n, r) => /* @__PURE__ */ g(q, {
27
27
  combo: n,
28
28
  ...e
29
29
  }, r))
30
- }), X = {
30
+ }), U = {
31
31
  touchAction: "none",
32
32
  userSelect: "none",
33
33
  WebkitUserSelect: "none",
34
34
  WebkitTouchCallout: "none"
35
- }, x = ({ className: t, onPointerDown: e, onPointerEnter: n, ...r }) => {
36
- const a = b(null), o = (s) => {
37
- const l = $(s.currentTarget, s.clientX, s.clientY);
38
- l !== a.current && (a.current = l, l && n?.(l, s));
35
+ }, S = ({ className: t, onPointerDown: e, onPointerEnter: n, ...r }) => {
36
+ const a = $(null), o = (c) => {
37
+ const s = E(c.currentTarget, c.clientX, c.clientY);
38
+ s !== a.current && (a.current = s, s && n?.(s, c));
39
39
  };
40
- return /* @__PURE__ */ p("div", {
40
+ return /* @__PURE__ */ g("div", {
41
41
  className: ["spotlab-hm-root", t].filter(Boolean).join(" "),
42
- style: e ? X : void 0,
43
- onPointerDown: n && ((s) => {
44
- a.current = $(s.currentTarget, s.clientX, s.clientY);
42
+ style: e ? U : void 0,
43
+ onPointerDown: n && ((c) => {
44
+ a.current = E(c.currentTarget, c.clientX, c.clientY);
45
45
  }),
46
46
  onPointerMove: n && o,
47
47
  onPointerLeave: n && (() => a.current = null),
48
- children: D(v, 13).map((s, l) => /* @__PURE__ */ p(F, {
49
- row: s,
48
+ children: X(C, 13).map((c, s) => /* @__PURE__ */ g(G, {
49
+ row: c,
50
50
  onPointerDown: e,
51
51
  ...r
52
- }, l))
52
+ }, s))
53
53
  });
54
- }, _ = (t, e) => ({ background: R([`${t} 0 ${e * 100}%`, `transparent ${e * 100}% 100%`]) }), rt = ({ range: t, fill: e = "var(--spotlab-hm-fill)", className: n }) => {
55
- const r = I(() => {
56
- const a = typeof t == "string" ? P(t) : t;
57
- return W(a);
54
+ }, Y = (t, e) => ({ background: L([`${t} 0 ${e * 100}%`, `transparent ${e * 100}% 100%`]) }), ot = ({ range: t, fill: e = "var(--spotlab-hm-fill)", className: n }) => {
55
+ const r = T(() => {
56
+ const a = typeof t == "string" ? F(t) : t;
57
+ return B(a);
58
58
  }, [t]);
59
- return /* @__PURE__ */ p(x, {
59
+ return /* @__PURE__ */ g(S, {
60
60
  className: n,
61
61
  comboStyle: (a) => {
62
62
  const o = r.get(a);
63
- return o ? _(e, o) : {};
63
+ return o ? Y(e, o) : {};
64
64
  }
65
65
  });
66
- }, j = (t) => Math.max(0, Math.min(100, Math.round(t))), q = (t, e) => {
66
+ }, H = (t) => Math.max(0, Math.min(100, Math.round(t))), Q = (t, e) => {
67
67
  const n = t.map(Math.round);
68
68
  let r = 100 - n.reduce((a, o) => a + o, 0);
69
69
  if (r !== 0) {
@@ -80,58 +80,58 @@ var D = (t, e) => Array.from({ length: Math.ceil(t.length / e) }, (n, r) => t.sl
80
80
  }
81
81
  }
82
82
  return n;
83
- }, G = (t, e, n, r) => {
84
- const a = j(n), o = t.slice();
83
+ }, J = (t, e, n, r) => {
84
+ const a = H(n), o = t.slice();
85
85
  o[e] = a;
86
- const s = 100 - a, l = [];
87
- for (let i = 0; i < t.length; i++) i !== e && l.push(i);
88
- const c = l.reduce((i, d) => i + t[d], 0);
89
- if (c <= 0) {
90
- l.forEach((d) => o[d] = 0);
91
- const i = e === r ? l[0] : r;
92
- i != null && (o[i] = s);
93
- } else l.forEach((i) => o[i] = Math.round(t[i] / c * s));
94
- return q(o, e);
95
- }, E = (t, e) => t.reduce((n, r, a) => a === e ? n : n + r, 0), C = new Map(v.map((t, e) => [t, e])), U = (t, e, n) => {
86
+ const c = 100 - a, s = [];
87
+ for (let h = 0; h < t.length; h++) h !== e && s.push(h);
88
+ const d = s.reduce((h, p) => h + t[p], 0);
89
+ if (d <= 0) {
90
+ s.forEach((p) => o[p] = 0);
91
+ const h = e === r ? s[0] : r;
92
+ h != null && (o[h] = c);
93
+ } else s.forEach((h) => o[h] = Math.round(t[h] / d * c));
94
+ return Q(o, e);
95
+ }, N = (t, e) => t.reduce((n, r, a) => a === e ? n : n + r, 0), k = new Map(C.map((t, e) => [t, e])), K = (t, e, n) => {
96
96
  const r = t.slice();
97
- return r[C.get(e)] = n, r;
98
- }, L = (t, e) => {
97
+ return r[k.get(e)] = n, r;
98
+ }, I = (t, e) => {
99
99
  const n = t.slice();
100
- let r = E(n, e);
100
+ let r = N(n, e);
101
101
  if (r > 100) {
102
102
  const a = 100 / r;
103
103
  for (let o = 0; o < n.length; o++) o !== e && (n[o] = Math.round(n[o] * a));
104
- r = E(n, e);
104
+ r = N(n, e);
105
105
  }
106
106
  return n[e] = Math.max(0, 100 - r), n;
107
107
  };
108
- function nt(t, e, n) {
109
- return v.map((r) => {
108
+ function lt(t, e, n) {
109
+ return C.map((r) => {
110
110
  const a = t ? t.get(r) ?? 0 : 1, o = e.map(() => 0);
111
111
  return a <= 0 ? (o[n] = 100, {
112
112
  avail: 0,
113
113
  weights: o
114
- }) : (e.forEach((s, l) => {
115
- const c = s?.get(r) ?? 0;
116
- o[l] = Math.round(c / a * 100);
114
+ }) : (e.forEach((c, s) => {
115
+ const d = c?.get(r) ?? 0;
116
+ o[s] = Math.round(d / a * 100);
117
117
  }), {
118
118
  avail: a,
119
- weights: L(o, n)
119
+ weights: I(o, n)
120
120
  });
121
121
  });
122
122
  }
123
- var Y = 8;
124
- function H(t, e) {
123
+ var A = 8;
124
+ function st(t, e) {
125
125
  const n = /* @__PURE__ */ new Map();
126
126
  return t.forEach((r, a) => {
127
127
  if (r.avail <= 0) return;
128
- const o = r.weights.reduce((l, c) => l + c, 0);
128
+ const o = r.weights.reduce((s, d) => s + d, 0);
129
129
  if (!o) return;
130
- const s = Number((r.weights[e] / o * r.avail).toFixed(Y));
131
- s && n.set(v[a], s);
130
+ const c = Number((r.weights[e] / o * r.avail).toFixed(A));
131
+ c && n.set(C[a], c);
132
132
  }), n;
133
133
  }
134
- function at(t, e, n) {
134
+ function ct(t, e, n) {
135
135
  return t.map((r, a) => {
136
136
  const o = e.map(() => 0);
137
137
  if (r.avail <= 0)
@@ -139,145 +139,153 @@ function at(t, e, n) {
139
139
  avail: r.avail,
140
140
  weights: o
141
141
  };
142
- const s = v[a];
143
- return e.forEach((l, c) => {
144
- const i = l?.get(s) ?? 0;
145
- o[c] = Math.round(i / r.avail * 100);
142
+ const c = C[a];
143
+ return e.forEach((s, d) => {
144
+ const h = s?.get(c) ?? 0;
145
+ o[d] = Math.round(h / r.avail * 100);
146
146
  }), {
147
147
  avail: r.avail,
148
- weights: L(o, n)
148
+ weights: I(o, n)
149
149
  };
150
150
  });
151
151
  }
152
- var Q = (t, e) => t.avail !== e.avail || t.weights.length !== e.weights.length || t.weights.some((n, r) => n !== e.weights[r]);
153
- function ot(t, e, n) {
154
- const r = new Set(v.filter((a, o) => Q(e[o], n[o])));
155
- return t.map((a, o) => {
156
- const s = H(n, o);
157
- if (a === null) return M(s);
158
- const l = (d) => {
159
- const h = s.get(d);
160
- return h ? M(/* @__PURE__ */ new Map([[d, h]])) : [];
161
- }, c = [], i = /* @__PURE__ */ new Set();
162
- for (const d of a) {
163
- const h = A(d.hand);
164
- r.has(h) ? i.has(h) || (i.add(h), c.push(...l(h))) : c.push(d);
152
+ var V = (t, e) => t.avail !== e.avail || t.weights.length !== e.weights.length || t.weights.some((n, r) => n !== e.weights[r]);
153
+ function it(t, e, n, r) {
154
+ const a = r && new Map(r.map(({ hand: l, frequency: i }) => [l, i])), o = (l, i) => r === void 0 ? i.avail : a ? a.get(l) ?? 0 : 1, c = t.map((l) => l && new Map(l.map(({ hand: i, frequency: f }) => [i, f]))), s = (l) => c.reduce((i, f) => i + (f?.get(l) ?? 0), 0), d = t.flatMap((l, i) => l ? [] : [i]), h = (l, i) => D(l).flatMap((f) => {
155
+ const b = Number(i(f).toFixed(A));
156
+ return b > 0 ? [{
157
+ hand: f,
158
+ frequency: b
159
+ }] : [];
160
+ }), p = (l, i) => {
161
+ const f = n[k.get(l)], b = f.weights.reduce((v, w) => v + w, 0);
162
+ return f.avail <= 0 || !b ? [] : h(l, (v) => f.weights[i] / b * o(v, f));
163
+ }, m = (l, i) => {
164
+ const f = n[k.get(l)], b = d.reduce((w, O) => w + f.weights[O], 0), v = b ? f.weights[i] / b : 1 / d.length;
165
+ return h(l, (w) => Math.max(0, o(w, f) - s(w)) * v);
166
+ }, u = new Set(C.filter((l, i) => V(e[i], n[i])));
167
+ return t.map((l, i) => {
168
+ if (l === null) return C.flatMap((v) => u.has(v) ? p(v, i) : m(v, i));
169
+ const f = [], b = /* @__PURE__ */ new Set();
170
+ for (const v of l) {
171
+ const w = W(v.hand);
172
+ u.has(w) ? b.has(w) || (b.add(w), f.push(...p(w, i))) : f.push(v);
165
173
  }
166
- for (const d of r) i.has(d) || c.push(...l(d));
167
- return c;
174
+ for (const v of u) b.has(v) || f.push(...p(v, i));
175
+ return f;
168
176
  });
169
177
  }
170
- function J(t) {
171
- const { cells: e, brush: n, tool: r, onCellsChange: a, onBrushChange: o, onToolChange: s } = t, l = b(null), c = g(() => {
172
- l.current?.abort(), l.current = null;
178
+ function Z(t) {
179
+ const { cells: e, brush: n, tool: r, onCellsChange: a, onBrushChange: o, onToolChange: c } = t, s = $(null), d = M(() => {
180
+ s.current?.abort(), s.current = null;
173
181
  }, []);
174
- N(() => c, [c]);
175
- const i = b(e);
176
- S(() => {
177
- i.current = e;
182
+ x(() => d, [d]);
183
+ const h = $(e);
184
+ P(() => {
185
+ h.current = e;
178
186
  }, [e]);
179
- const d = g((u) => {
180
- const f = i.current, { avail: m } = f[C.get(u)];
181
- if (m <= 0) return;
182
- const k = U(f, u, {
183
- avail: m,
187
+ const p = M((u) => {
188
+ const l = h.current, { avail: i } = l[k.get(u)];
189
+ if (i <= 0) return;
190
+ const f = K(l, u, {
191
+ avail: i,
184
192
  weights: [...n]
185
193
  });
186
- i.current = k, a(k);
187
- }, [n, a]), h = g((u) => {
188
- const f = C.get(u);
189
- e[f].avail <= 0 || (o([...e[f].weights]), s("brush"));
194
+ h.current = f, a(f);
195
+ }, [n, a]), m = M((u) => {
196
+ const l = k.get(u);
197
+ e[l].avail <= 0 || (o([...e[l].weights]), c("brush"));
190
198
  }, [
191
199
  e,
192
200
  o,
193
- s
201
+ c
194
202
  ]);
195
203
  return {
196
- onCellDown: g((u) => {
204
+ onCellDown: M((u) => {
197
205
  if (r === "eyedropper") {
198
- h(u);
206
+ m(u);
199
207
  return;
200
208
  }
201
- c();
202
- const f = new AbortController();
203
- l.current = f, window.addEventListener("pointerup", c, { signal: f.signal }), window.addEventListener("pointercancel", c, { signal: f.signal }), d(u);
209
+ d();
210
+ const l = new AbortController();
211
+ s.current = l, window.addEventListener("pointerup", d, { signal: l.signal }), window.addEventListener("pointercancel", d, { signal: l.signal }), p(u);
204
212
  }, [
205
213
  r,
206
- h,
207
- d,
208
- c
214
+ m,
215
+ p,
216
+ d
209
217
  ]),
210
- onCellEnter: g((u) => {
211
- l.current && r === "brush" && d(u);
212
- }, [r, d])
218
+ onCellEnter: M((u) => {
219
+ s.current && r === "brush" && p(u);
220
+ }, [r, p])
213
221
  };
214
222
  }
215
- var y = (t, e, n) => {
223
+ var R = (t, e, n) => {
216
224
  const r = [];
217
225
  let a = 0;
218
226
  return n.forEach((o) => {
219
- const s = (t.weights[o] || 0) / 100;
220
- if (s <= 0) return;
221
- const l = e[o].color;
222
- r.push(`${l} ${a * 100}%`), r.push(`${l} ${(a + s) * 100}%`), a += s;
223
- }), r.length > 0 && a < 1 - 1e-9 && r.push(`transparent ${a * 100}% 100%`), R(r);
224
- }, lt = ({ cells: t, actions: e, order: n, brush: r, tool: a, onCellsChange: o, onBrushChange: s, onToolChange: l, className: c }) => {
225
- const { onCellDown: i, onCellEnter: d } = J({
227
+ const c = (t.weights[o] || 0) / 100;
228
+ if (c <= 0) return;
229
+ const s = e[o].color;
230
+ r.push(`${s} ${a * 100}%`), r.push(`${s} ${(a + c) * 100}%`), a += c;
231
+ }), r.length > 0 && a < 1 - 1e-9 && r.push(`transparent ${a * 100}% 100%`), L(r);
232
+ }, ut = ({ cells: t, actions: e, order: n, brush: r, tool: a, onCellsChange: o, onBrushChange: c, onToolChange: s, className: d }) => {
233
+ const { onCellDown: h, onCellEnter: p } = Z({
226
234
  cells: t,
227
235
  brush: r,
228
236
  tool: a,
229
237
  onCellsChange: o,
230
- onBrushChange: s,
231
- onToolChange: l
238
+ onBrushChange: c,
239
+ onToolChange: s
232
240
  });
233
- return /* @__PURE__ */ p(x, {
234
- className: c,
235
- comboStyle: (h) => {
236
- const u = t[C.get(h)];
241
+ return /* @__PURE__ */ g(S, {
242
+ className: d,
243
+ comboStyle: (m) => {
244
+ const u = t[k.get(m)];
237
245
  if (u.avail <= 0) return {
238
246
  background: "var(--spotlab-hm-dead-hatch)",
239
247
  backgroundColor: "var(--spotlab-hm-muted-bg)",
240
248
  cursor: "not-allowed",
241
249
  color: "var(--spotlab-hm-muted-fg)"
242
250
  };
243
- const f = a === "eyedropper" ? "copy" : "pointer";
251
+ const l = a === "eyedropper" ? "copy" : "pointer";
244
252
  if (u.avail < 1) {
245
- const m = `${u.avail * 100}%`;
253
+ const i = `${u.avail * 100}%`;
246
254
  return {
247
- background: `repeating-linear-gradient(180deg, var(--spotlab-hm-muted-fg) 0 4px, transparent 4px 8px), var(--spotlab-hm-dead-hatch), ${y(u, e, n)}`,
255
+ background: `repeating-linear-gradient(180deg, var(--spotlab-hm-muted-fg) 0 4px, transparent 4px 8px), var(--spotlab-hm-dead-hatch), ${R(u, e, n)}`,
248
256
  backgroundSize: `1px 100%, ${(1 - u.avail) * 100}% 100%, ${u.avail * 100}% 100%`,
249
- backgroundPosition: `${m} center, right center, left center`,
257
+ backgroundPosition: `${i} center, right center, left center`,
250
258
  backgroundRepeat: "no-repeat, no-repeat, no-repeat",
251
- cursor: f
259
+ cursor: l
252
260
  };
253
261
  }
254
262
  return {
255
- background: y(u, e, n),
256
- cursor: f
263
+ background: R(u, e, n),
264
+ cursor: l
257
265
  };
258
266
  },
259
- onPointerDown: i,
260
- onPointerEnter: d
267
+ onPointerDown: h,
268
+ onPointerEnter: p
261
269
  });
262
- }, K = (t) => /* @__PURE__ */ p("input", {
270
+ }, z = (t) => /* @__PURE__ */ g("input", {
263
271
  type: "number",
264
272
  className: "spotlab-hm-weight-input",
265
273
  ...t
266
- }), V = ({ value: t, color: e, passive: n, onChange: r }) => {
267
- const a = b(null), o = b(!1), s = g((l) => {
268
- const c = a.current;
269
- if (!c) return;
270
- const i = c.getBoundingClientRect();
271
- r((l - i.left) / i.width * 100);
274
+ }), tt = ({ value: t, color: e, passive: n, onChange: r }) => {
275
+ const a = $(null), o = $(!1), c = M((s) => {
276
+ const d = a.current;
277
+ if (!d) return;
278
+ const h = d.getBoundingClientRect();
279
+ r((s - h.left) / h.width * 100);
272
280
  }, [r]);
273
- return N(() => {
274
- const l = (i) => {
275
- o.current && s(i.clientX);
276
- }, c = () => o.current = !1;
277
- return window.addEventListener("pointermove", l), window.addEventListener("pointerup", c), () => {
278
- window.removeEventListener("pointermove", l), window.removeEventListener("pointerup", c);
281
+ return x(() => {
282
+ const s = (h) => {
283
+ o.current && c(h.clientX);
284
+ }, d = () => o.current = !1;
285
+ return window.addEventListener("pointermove", s), window.addEventListener("pointerup", d), () => {
286
+ window.removeEventListener("pointermove", s), window.removeEventListener("pointerup", d);
279
287
  };
280
- }, [s]), /* @__PURE__ */ p("div", {
288
+ }, [c]), /* @__PURE__ */ g("div", {
281
289
  ref: a,
282
290
  role: "slider",
283
291
  "aria-valuenow": t,
@@ -285,10 +293,10 @@ var y = (t, e, n) => {
285
293
  "aria-valuemax": 100,
286
294
  className: "spotlab-hm-slider-track",
287
295
  style: { background: `linear-gradient(to right, ${e} 0 ${t}%, var(--spotlab-hm-track-bg) ${t}% 100%)` },
288
- onPointerDown: (l) => {
289
- o.current = !0, s(l.clientX);
296
+ onPointerDown: (s) => {
297
+ o.current = !0, c(s.clientX);
290
298
  },
291
- children: /* @__PURE__ */ p("div", {
299
+ children: /* @__PURE__ */ g("div", {
292
300
  className: "spotlab-hm-slider-thumb",
293
301
  style: {
294
302
  left: `${t}%`,
@@ -296,44 +304,44 @@ var y = (t, e, n) => {
296
304
  }
297
305
  })
298
306
  });
299
- }, Z = (t, e) => /* @__PURE__ */ w("span", {
307
+ }, et = (t, e) => /* @__PURE__ */ y("span", {
300
308
  className: "spotlab-hm-slider-label",
301
- children: [t.label, e && /* @__PURE__ */ p("span", {
309
+ children: [t.label, e && /* @__PURE__ */ g("span", {
302
310
  className: "spotlab-hm-slider-remainder",
303
311
  children: " · remainder"
304
312
  })]
305
- }), st = ({ actions: t, order: e, weights: n, passive: r, onWeightsChange: a, renderActionLabel: o, renderActionExtra: s, components: l, className: c }) => {
306
- const i = l?.WeightInput ?? K, d = (h, u) => {
307
- a(G(n, h, u, r));
313
+ }), ht = ({ actions: t, order: e, weights: n, passive: r, onWeightsChange: a, renderActionLabel: o, renderActionExtra: c, components: s, className: d }) => {
314
+ const h = s?.WeightInput ?? z, p = (m, u) => {
315
+ a(J(n, m, u, r));
308
316
  };
309
- return /* @__PURE__ */ p("div", {
310
- className: ["spotlab-hm-root spotlab-hm-sliders", c].filter(Boolean).join(" "),
311
- children: e.map((h) => {
312
- const u = t[h], f = h === r;
313
- return /* @__PURE__ */ w("div", {
317
+ return /* @__PURE__ */ g("div", {
318
+ className: ["spotlab-hm-root spotlab-hm-sliders", d].filter(Boolean).join(" "),
319
+ children: e.map((m) => {
320
+ const u = t[m], l = m === r;
321
+ return /* @__PURE__ */ y("div", {
314
322
  className: "spotlab-hm-slider-row",
315
- "data-passive": f,
316
- children: [/* @__PURE__ */ w("div", {
323
+ "data-passive": l,
324
+ children: [/* @__PURE__ */ y("div", {
317
325
  className: "spotlab-hm-slider-header",
318
326
  children: [
319
- /* @__PURE__ */ p("span", {
327
+ /* @__PURE__ */ g("span", {
320
328
  className: "spotlab-hm-slider-swatch",
321
329
  style: { background: u.color }
322
330
  }),
323
- o?.(u, h, f) ?? Z(u, f),
324
- s?.(u, h)
331
+ o?.(u, m, l) ?? et(u, l),
332
+ c?.(u, m)
325
333
  ]
326
- }), /* @__PURE__ */ w("div", {
334
+ }), /* @__PURE__ */ y("div", {
327
335
  className: "spotlab-hm-slider-track-row",
328
- children: [/* @__PURE__ */ p(V, {
329
- value: n[h],
336
+ children: [/* @__PURE__ */ g(tt, {
337
+ value: n[m],
330
338
  color: u.color,
331
- passive: f,
332
- onChange: (m) => d(h, m)
333
- }), /* @__PURE__ */ p(i, {
334
- value: n[h],
339
+ passive: l,
340
+ onChange: (i) => p(m, i)
341
+ }), /* @__PURE__ */ g(h, {
342
+ value: n[m],
335
343
  "aria-label": `${u.label} weight`,
336
- onChange: (m) => d(h, parseInt(m.target.value || "0", 10))
344
+ onChange: (i) => p(m, parseInt(i.target.value || "0", 10))
337
345
  })]
338
346
  })]
339
347
  }, u.id);
@@ -341,16 +349,16 @@ var y = (t, e, n) => {
341
349
  });
342
350
  };
343
351
  export {
344
- st as ActionWeightSliders,
345
- T as CELL_FILL_DIRECTION,
346
- x as HandMatrix,
347
- rt as RangeGrid,
348
- lt as RangeMatrixEditor,
349
- R as cellFillGradient,
350
- H as cellsToComboWeights,
351
- ot as cellsToRanges,
352
- at as comboWeightsToCells,
353
- G as rebalance,
354
- nt as seedCells,
355
- J as useRangePainting
352
+ ht as ActionWeightSliders,
353
+ _ as CELL_FILL_DIRECTION,
354
+ S as HandMatrix,
355
+ ot as RangeGrid,
356
+ ut as RangeMatrixEditor,
357
+ L as cellFillGradient,
358
+ st as cellsToComboWeights,
359
+ it as cellsToRanges,
360
+ ct as comboWeightsToCells,
361
+ J as rebalance,
362
+ lt as seedCells,
363
+ Z as useRangePainting
356
364
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spotlab/hand-matrix",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "A 13x13 poker hand-matrix React component: the read-only grid primitive and a range-string-aware display component, themed through CSS custom properties.",
5
5
  "type": "module",
6
6
  "license": "MIT",