@broberg/bodymap 0.8.0 → 0.9.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/dist/three.d.cts CHANGED
@@ -119,6 +119,19 @@ interface BodymapUiColors {
119
119
  badgeBg?: string;
120
120
  /** The destructive action (remove a marked region). */
121
121
  danger?: string;
122
+ /** Border on the destructive control. Its TEXT was already themeable and its
123
+ * border was not — half a control. (F052.30) */
124
+ dangerBorder?: string;
125
+ /**
126
+ * THE ACTIVE CONTROL colour — the chosen intensity, the active sex toggle.
127
+ *
128
+ * NOT `palette.selected`. That is the colour of a MARK ON SKIN; this is the
129
+ * colour of an active button. Collapsing them would stop a consumer having a
130
+ * teal mark and a navy button, which is a normal thing to want. (F052.30)
131
+ */
132
+ accent?: string;
133
+ /** Text ON the accent. Check it against your accent — see the README. */
134
+ accentText?: string;
122
135
  }
123
136
  type BodyView = "front" | "back" | "left" | "right";
124
137
  /** Side in the serialized report — a midline region (no side) becomes "center". */
package/dist/three.d.ts CHANGED
@@ -119,6 +119,19 @@ interface BodymapUiColors {
119
119
  badgeBg?: string;
120
120
  /** The destructive action (remove a marked region). */
121
121
  danger?: string;
122
+ /** Border on the destructive control. Its TEXT was already themeable and its
123
+ * border was not — half a control. (F052.30) */
124
+ dangerBorder?: string;
125
+ /**
126
+ * THE ACTIVE CONTROL colour — the chosen intensity, the active sex toggle.
127
+ *
128
+ * NOT `palette.selected`. That is the colour of a MARK ON SKIN; this is the
129
+ * colour of an active button. Collapsing them would stop a consumer having a
130
+ * teal mark and a navy button, which is a normal thing to want. (F052.30)
131
+ */
132
+ accent?: string;
133
+ /** Text ON the accent. Check it against your accent — see the README. */
134
+ accentText?: string;
122
135
  }
123
136
  type BodyView = "front" | "back" | "left" | "right";
124
137
  /** Side in the serialized report — a midline region (no side) becomes "center". */
package/dist/three.js CHANGED
@@ -89,7 +89,16 @@ var defaultUi = {
89
89
  stageBg: STAGE_BG,
90
90
  border: "#e2e8f0",
91
91
  badgeBg: "#f1f5f9",
92
- danger: "#dc2626"
92
+ danger: "#dc2626",
93
+ dangerBorder: "#f6c9c9",
94
+ // F052.30 — was #0e8f8a, which measured 3.95:1 against white. AA needs 4.5,
95
+ // and this is the SELECTED intensity button on a surface where AA is a legal
96
+ // duty. It shipped from 0.2.0 and no check could see it: the colour was an
97
+ // inline literal, and the F052.19 contrast sweep only read this object.
98
+ // #0c7d77 is the same teal a shade deeper — 4.98:1, with headroom rather than
99
+ // sitting on the 4.5 boundary where any later tweak reopens it.
100
+ accent: "#0c7d77",
101
+ accentText: "#fff"
93
102
  };
94
103
  function uiColors(palette) {
95
104
  return { ...defaultUi, ...palette?.ui ?? {} };
@@ -276,8 +285,20 @@ function webglAvailable() {
276
285
  return false;
277
286
  }
278
287
  }
279
- var btn = { font: "inherit", cursor: "pointer", borderRadius: 8, border: "1px solid #e2e8f0", background: "#fff", padding: "6px 9px" };
280
- var seg = (on) => ({ ...btn, background: on ? "#0e8f8a" : "#fff", color: on ? "#fff" : "#1e293b", fontWeight: 600 });
288
+ var btn = (c) => ({
289
+ font: "inherit",
290
+ cursor: "pointer",
291
+ borderRadius: 8,
292
+ border: `1px solid ${c.border}`,
293
+ background: c.panelBg,
294
+ padding: "6px 9px"
295
+ });
296
+ var seg = (c, on) => ({
297
+ ...btn(c),
298
+ background: on ? c.accent : c.panelBg,
299
+ color: on ? c.accentText : c.text,
300
+ fontWeight: 600
301
+ });
281
302
  function BodyMap3D(props) {
282
303
  const {
283
304
  models,
@@ -667,7 +688,7 @@ function BodyMap3D(props) {
667
688
  "data-fullscreen": isFullscreen ? "true" : void 0,
668
689
  style: {
669
690
  fontFamily: "system-ui, sans-serif",
670
- color: "#1e293b",
691
+ color: chrome.text,
671
692
  // A viewport fill, not the Fullscreen API — see the `fullscreen` prop.
672
693
  // `fixed`+`inset:0` behaves the same on iOS Safari, where element
673
694
  // fullscreen does not exist at all, as it does everywhere else.
@@ -699,8 +720,8 @@ function BodyMap3D(props) {
699
720
  },
700
721
  children: [
701
722
  showSexToggle && /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 16, flexWrap: "wrap", marginBottom: 12, fontSize: 13 }, children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
702
- /* @__PURE__ */ jsx("button", { "data-testid": "bodymap3d-sex-male", onClick: () => changeSex("male"), style: seg(sex === "male"), children: UI.male }),
703
- /* @__PURE__ */ jsx("button", { "data-testid": "bodymap3d-sex-female", onClick: () => changeSex("female"), style: seg(sex === "female"), children: UI.female })
723
+ /* @__PURE__ */ jsx("button", { "data-testid": "bodymap3d-sex-male", onClick: () => changeSex("male"), style: seg(chrome, sex === "male"), children: UI.male }),
724
+ /* @__PURE__ */ jsx("button", { "data-testid": "bodymap3d-sex-female", onClick: () => changeSex("female"), style: seg(chrome, sex === "female"), children: UI.female })
704
725
  ] }) }),
705
726
  /* @__PURE__ */ jsx("span", { ref: loadedRef, "data-testid": "bodymap3d-loaded", style: { display: "none" } }),
706
727
  ready && /* @__PURE__ */ jsx("span", { "data-testid": "bodymap3d-ready", style: { position: "absolute", width: 1, height: 1, opacity: 0, pointerEvents: "none" } }),
@@ -713,7 +734,7 @@ function BodyMap3D(props) {
713
734
  "aria-label": isFullscreen ? UI.collapse ?? "Close" : UI.expand ?? "Expand",
714
735
  onClick: () => setFullscreen(!isFullscreen),
715
736
  style: {
716
- ...btn,
737
+ ...btn(chrome),
717
738
  color: chrome.text,
718
739
  borderColor: chrome.border,
719
740
  background: chrome.panelBg,
@@ -764,16 +785,16 @@ function BodyMap3D(props) {
764
785
  "data-testid": "bodymap3d-close",
765
786
  "aria-label": L.close,
766
787
  onClick: () => setSelected(null),
767
- style: { ...btn, width: 32, height: 32, padding: 0, fontSize: 20, lineHeight: 1, color: chrome.mutedText, borderColor: chrome.border, background: chrome.panelBg },
788
+ style: { ...btn(chrome), width: 32, height: 32, padding: 0, fontSize: 20, lineHeight: 1, color: chrome.mutedText, borderColor: chrome.border, background: chrome.panelBg },
768
789
  children: "\xD7"
769
790
  }
770
791
  )
771
792
  ] }),
772
793
  /* @__PURE__ */ jsx("div", { style: { fontSize: 11, fontWeight: 700, letterSpacing: ".06em", textTransform: "uppercase", color: chrome.mutedText, marginBottom: 7 }, children: L.intensity }),
773
- /* @__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)) }),
794
+ /* @__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(chrome), display: "inline-flex", alignItems: "center", justifyContent: "center", minWidth: 30, height: 30, padding: 0, background: current?.intensity === i ? chrome.accent : chrome.panelBg, color: current?.intensity === i ? chrome.accentText : chrome.text }, children: i }, i)) }),
774
795
  /* @__PURE__ */ jsx("div", { style: { fontSize: 11, fontWeight: 700, letterSpacing: ".06em", textTransform: "uppercase", color: chrome.mutedText, marginBottom: 7 }, children: L.quality }),
775
- /* @__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)) }),
776
- current && /* @__PURE__ */ jsx("button", { "data-testid": "bodymap3d-remove", onClick: () => removePain(region.key), style: { ...btn, color: chrome.danger, borderColor: "#f6c9c9" }, children: L.remove })
796
+ /* @__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(chrome), borderRadius: 999, padding: "6px 12px", background: current?.type === t ? chrome.text : chrome.panelBg, color: current?.type === t ? chrome.panelBg : chrome.mutedText }, children: L.qualities[t] ?? t }, t)) }),
797
+ current && /* @__PURE__ */ jsx("button", { "data-testid": "bodymap3d-remove", onClick: () => removePain(region.key), style: { ...btn(chrome), color: chrome.danger, borderColor: chrome.dangerBorder }, children: L.remove })
777
798
  ] }) : 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 })
778
799
  ] })
779
800
  ]