@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.js CHANGED
@@ -53,11 +53,26 @@ var painPointSchema = z.object({
53
53
  timestamp: z.string()
54
54
  });
55
55
  z.array(painPointSchema);
56
+ function decidePick(region, report, config = {}) {
57
+ if (!isSelectable(region, config)) return "ignore";
58
+ return report.some((p) => p.region === region) ? "clear" : "select";
59
+ }
56
60
  function isSelectable(key, config = {}) {
57
61
  const s = config[key];
58
62
  if (s?.visible === false) return false;
59
63
  return s?.selectable ?? true;
60
64
  }
65
+ var defaultUi = {
66
+ text: "#1e293b",
67
+ mutedText: "#475569",
68
+ panelBg: "#fff",
69
+ border: "#e2e8f0",
70
+ badgeBg: "#f1f5f9",
71
+ danger: "#dc2626"
72
+ };
73
+ function uiColors(palette) {
74
+ return { ...defaultUi, ...palette?.ui ?? {} };
75
+ }
61
76
  var defaultPalette = {
62
77
  body: "#d2d7de",
63
78
  hover: "#8fd0cd",
@@ -241,6 +256,7 @@ function BodyMap3D(props) {
241
256
  showRegionCode = true,
242
257
  className
243
258
  } = props;
259
+ const chrome = uiColors(palette);
244
260
  const L = mergeLabels(locale, labels);
245
261
  const UI = { ...locale === "en" ? UI_EN : UI_DA, ...ui };
246
262
  const nameOf = (key) => L.regions[key] ?? getRegion(key)?.label ?? key;
@@ -272,6 +288,7 @@ function BodyMap3D(props) {
272
288
  sexRef.current = sex;
273
289
  const setSelectedRef = useRef(setSelected);
274
290
  setSelectedRef.current = setSelected;
291
+ const pickRef = useRef(() => "ignore");
275
292
  const setReadyRef = useRef(setReady);
276
293
  setReadyRef.current = setReady;
277
294
  const apiRef = useRef(null);
@@ -467,7 +484,12 @@ function BodyMap3D(props) {
467
484
  const onUp = (e) => {
468
485
  if (Math.hypot(e.clientX - downX, e.clientY - downY) > 6 || Date.now() - downT > 450) return;
469
486
  const k = pick(e.clientX, e.clientY);
470
- if (k) setSelectedRef.current(k);
487
+ if (!k) return;
488
+ const outcome = pickRef.current(k);
489
+ if (outcome === "clear") {
490
+ hovered = null;
491
+ canvas.style.cursor = "default";
492
+ }
471
493
  };
472
494
  canvas.addEventListener("pointerdown", onDown);
473
495
  canvas.addEventListener("pointermove", onMove);
@@ -523,6 +545,12 @@ function BodyMap3D(props) {
523
545
  commit(report.filter((p) => p.region !== k));
524
546
  setSelected(null);
525
547
  };
548
+ pickRef.current = (k) => {
549
+ const what = decidePick(k, reportRef.current, configRef.current ?? {});
550
+ if (what === "clear") removePain(k);
551
+ else if (what === "select") setSelected(k);
552
+ return what;
553
+ };
526
554
  const changeSex = (s) => {
527
555
  if (sexProp === void 0) setInternalSex(s);
528
556
  onSexChange?.(s);
@@ -540,20 +568,20 @@ function BodyMap3D(props) {
540
568
  ready && /* @__PURE__ */ jsx("span", { "data-testid": "bodymap3d-ready", style: { position: "absolute", width: 1, height: 1, opacity: 0, pointerEvents: "none" } }),
541
569
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 18, alignItems: "flex-start", flexWrap: "wrap" }, children: [
542
570
  unsupported ? /* @__PURE__ */ 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__ */ 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" } }),
543
- /* @__PURE__ */ jsx("div", { style: { flex: "1 1 300px", minWidth: 260 }, children: region ? /* @__PURE__ */ jsxs("div", { style: { border: "1px solid #e2e8f0", borderRadius: 14, padding: 16, background: "#fff" }, children: [
571
+ /* @__PURE__ */ jsx("div", { style: { flex: "1 1 300px", minWidth: 260 }, children: region ? /* @__PURE__ */ jsxs("div", { style: { border: `1px solid ${chrome.border}`, borderRadius: 14, padding: 16, background: chrome.panelBg }, children: [
544
572
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 12 }, children: [
545
573
  /* @__PURE__ */ jsx("b", { style: { fontSize: 16 }, children: nameOf(region.key) }),
546
- showRegionCode && /* @__PURE__ */ jsxs("span", { "data-testid": "bodymap3d-region-code", style: { font: "11px ui-monospace, monospace", color: "#64748b", background: "#f1f5f9", borderRadius: 6, padding: "2px 7px" }, children: [
574
+ showRegionCode && /* @__PURE__ */ 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: [
547
575
  region.code,
548
576
  region.side ? " \xB7 " + region.side : ""
549
577
  ] })
550
578
  ] }),
551
- /* @__PURE__ */ jsx("div", { style: { fontSize: 11, fontWeight: 700, letterSpacing: ".06em", textTransform: "uppercase", color: "#94a3b8", marginBottom: 7 }, children: L.intensity }),
579
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 11, fontWeight: 700, letterSpacing: ".06em", textTransform: "uppercase", color: chrome.mutedText, marginBottom: 7 }, children: L.intensity }),
552
580
  /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 4, marginBottom: 12 }, children: Array.from({ length: 11 }, (_, i) => /* @__PURE__ */ 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)) }),
553
- /* @__PURE__ */ jsx("div", { style: { fontSize: 11, fontWeight: 700, letterSpacing: ".06em", textTransform: "uppercase", color: "#94a3b8", marginBottom: 7 }, children: L.quality }),
581
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 11, fontWeight: 700, letterSpacing: ".06em", textTransform: "uppercase", color: chrome.mutedText, marginBottom: 7 }, children: L.quality }),
554
582
  /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, marginBottom: 14 }, children: PAIN_TYPES.map((t) => /* @__PURE__ */ 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)) }),
555
- current && /* @__PURE__ */ jsx("button", { "data-testid": "bodymap3d-remove", onClick: () => removePain(region.key), style: { ...btn, color: "#ef4444", borderColor: "#f6c9c9" }, children: L.remove })
556
- ] }) : showEmptyHint ? /* @__PURE__ */ 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 })
583
+ current && /* @__PURE__ */ jsx("button", { "data-testid": "bodymap3d-remove", onClick: () => removePain(region.key), style: { ...btn, color: chrome.danger, borderColor: "#f6c9c9" }, children: L.remove })
584
+ ] }) : showEmptyHint ? /* @__PURE__ */ 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 })
557
585
  ] })
558
586
  ] });
559
587
  }