@broberg/bodymap 0.2.4 → 0.2.6

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/three.cjs CHANGED
@@ -75,11 +75,26 @@ var painPointSchema = zod.z.object({
75
75
  timestamp: zod.z.string()
76
76
  });
77
77
  zod.z.array(painPointSchema);
78
+ function decidePick(region, report, config = {}) {
79
+ if (!isSelectable(region, config)) return "ignore";
80
+ return report.some((p) => p.region === region) ? "clear" : "select";
81
+ }
78
82
  function isSelectable(key, config = {}) {
79
83
  const s = config[key];
80
84
  if (s?.visible === false) return false;
81
85
  return s?.selectable ?? true;
82
86
  }
87
+ var defaultUi = {
88
+ text: "#1e293b",
89
+ mutedText: "#475569",
90
+ panelBg: "#fff",
91
+ border: "#e2e8f0",
92
+ badgeBg: "#f1f5f9",
93
+ danger: "#dc2626"
94
+ };
95
+ function uiColors(palette) {
96
+ return { ...defaultUi, ...palette?.ui ?? {} };
97
+ }
83
98
  var defaultPalette = {
84
99
  body: "#d2d7de",
85
100
  hover: "#8fd0cd",
@@ -263,6 +278,7 @@ function BodyMap3D(props) {
263
278
  showRegionCode = true,
264
279
  className
265
280
  } = props;
281
+ const chrome = uiColors(palette);
266
282
  const L = mergeLabels(locale, labels);
267
283
  const UI = { ...locale === "en" ? UI_EN : UI_DA, ...ui };
268
284
  const nameOf = (key) => L.regions[key] ?? getRegion(key)?.label ?? key;
@@ -294,6 +310,7 @@ function BodyMap3D(props) {
294
310
  sexRef.current = sex;
295
311
  const setSelectedRef = react.useRef(setSelected);
296
312
  setSelectedRef.current = setSelected;
313
+ const pickRef = react.useRef(() => "ignore");
297
314
  const setReadyRef = react.useRef(setReady);
298
315
  setReadyRef.current = setReady;
299
316
  const apiRef = react.useRef(null);
@@ -489,7 +506,12 @@ function BodyMap3D(props) {
489
506
  const onUp = (e) => {
490
507
  if (Math.hypot(e.clientX - downX, e.clientY - downY) > 6 || Date.now() - downT > 450) return;
491
508
  const k = pick(e.clientX, e.clientY);
492
- if (k) setSelectedRef.current(k);
509
+ if (!k) return;
510
+ const outcome = pickRef.current(k);
511
+ if (outcome === "clear") {
512
+ hovered = null;
513
+ canvas.style.cursor = "default";
514
+ }
493
515
  };
494
516
  canvas.addEventListener("pointerdown", onDown);
495
517
  canvas.addEventListener("pointermove", onMove);
@@ -545,6 +567,12 @@ function BodyMap3D(props) {
545
567
  commit(report.filter((p) => p.region !== k));
546
568
  setSelected(null);
547
569
  };
570
+ pickRef.current = (k) => {
571
+ const what = decidePick(k, reportRef.current, configRef.current ?? {});
572
+ if (what === "clear") removePain(k);
573
+ else if (what === "select") setSelected(k);
574
+ return what;
575
+ };
548
576
  const changeSex = (s) => {
549
577
  if (sexProp === void 0) setInternalSex(s);
550
578
  onSexChange?.(s);
@@ -562,20 +590,20 @@ function BodyMap3D(props) {
562
590
  ready && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-testid": "bodymap3d-ready", style: { position: "absolute", width: 1, height: 1, opacity: 0, pointerEvents: "none" } }),
563
591
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 18, alignItems: "flex-start", flexWrap: "wrap" }, children: [
564
592
  unsupported ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": "bodymap3d-unsupported", style: { flex: "1 1 520px", minWidth: 320, height: canvasH, borderRadius: 16, background: "#0e1424", color: "#cbd5e1", display: "flex", alignItems: "center", justifyContent: "center", padding: 24, textAlign: "center", fontSize: 14 }, children: "3D kr\xE6ver WebGL, som ikke er tilg\xE6ngeligt her." }) : /* @__PURE__ */ jsxRuntime.jsx("div", { ref: mountRef, "data-testid": "bodymap3d-canvas", style: { flex: "1 1 520px", height: canvasH, minWidth: 320, borderRadius: 16, overflow: "hidden", background: "#0e1424", touchAction: "none" } }),
565
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: "1 1 300px", minWidth: 260 }, children: region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { border: "1px solid #e2e8f0", borderRadius: 14, padding: 16, background: "#fff" }, children: [
593
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: "1 1 300px", minWidth: 260 }, children: region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { border: `1px solid ${chrome.border}`, borderRadius: 14, padding: 16, background: chrome.panelBg }, children: [
566
594
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 12 }, children: [
567
595
  /* @__PURE__ */ jsxRuntime.jsx("b", { style: { fontSize: 16 }, children: nameOf(region.key) }),
568
- showRegionCode && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-testid": "bodymap3d-region-code", style: { font: "11px ui-monospace, monospace", color: "#64748b", background: "#f1f5f9", borderRadius: 6, padding: "2px 7px" }, children: [
596
+ showRegionCode && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-testid": "bodymap3d-region-code", style: { font: "11px ui-monospace, monospace", color: chrome.mutedText, background: chrome.badgeBg, borderRadius: 6, padding: "2px 7px" }, children: [
569
597
  region.code,
570
598
  region.side ? " \xB7 " + region.side : ""
571
599
  ] })
572
600
  ] }),
573
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, fontWeight: 700, letterSpacing: ".06em", textTransform: "uppercase", color: "#94a3b8", marginBottom: 7 }, children: L.intensity }),
601
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, fontWeight: 700, letterSpacing: ".06em", textTransform: "uppercase", color: chrome.mutedText, marginBottom: 7 }, children: L.intensity }),
574
602
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 4, marginBottom: 12 }, children: Array.from({ length: 11 }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx("button", { "data-testid": `bodymap3d-intensity-${i}`, onClick: () => setPain(region.key, i, current?.type), style: { ...btn, display: "inline-flex", alignItems: "center", justifyContent: "center", minWidth: 30, height: 30, padding: 0, background: current?.intensity === i ? "#0e8f8a" : "#fff", color: current?.intensity === i ? "#fff" : "#1e293b" }, children: i }, i)) }),
575
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, fontWeight: 700, letterSpacing: ".06em", textTransform: "uppercase", color: "#94a3b8", marginBottom: 7 }, children: L.quality }),
603
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, fontWeight: 700, letterSpacing: ".06em", textTransform: "uppercase", color: chrome.mutedText, marginBottom: 7 }, children: L.quality }),
576
604
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, marginBottom: 14 }, children: PAIN_TYPES.map((t) => /* @__PURE__ */ jsxRuntime.jsx("button", { "data-testid": `bodymap3d-type-${t}`, onClick: () => setPain(region.key, current?.intensity ?? 5, t), style: { ...btn, borderRadius: 999, padding: "6px 12px", background: current?.type === t ? "#1e293b" : "#fff", color: current?.type === t ? "#fff" : "#64748b" }, children: L.qualities[t] ?? t }, t)) }),
577
- current && /* @__PURE__ */ jsxRuntime.jsx("button", { "data-testid": "bodymap3d-remove", onClick: () => removePain(region.key), style: { ...btn, color: "#ef4444", borderColor: "#f6c9c9" }, children: L.remove })
578
- ] }) : showEmptyHint ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": "bodymap3d-empty", style: { border: "1px solid #e2e8f0", borderRadius: 14, padding: 16, background: "#fff", color: "#94a3b8", fontSize: 13.5 }, children: UI.hoverHint }) : null })
605
+ current && /* @__PURE__ */ jsxRuntime.jsx("button", { "data-testid": "bodymap3d-remove", onClick: () => removePain(region.key), style: { ...btn, color: chrome.danger, borderColor: "#f6c9c9" }, children: L.remove })
606
+ ] }) : showEmptyHint ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": "bodymap3d-empty", style: { border: `1px solid ${chrome.border}`, borderRadius: 14, padding: 16, background: chrome.panelBg, color: chrome.mutedText, fontSize: 13.5 }, children: UI.hoverHint }) : null })
579
607
  ] })
580
608
  ] });
581
609
  }