@broberg/bodymap 0.5.0 → 0.7.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 +64 -0
- package/dist/react.cjs +18 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -0
- package/dist/react.d.ts +2 -0
- package/dist/react.js +18 -1
- package/dist/react.js.map +1 -1
- package/dist/three.cjs +118 -27
- package/dist/three.cjs.map +1 -1
- package/dist/three.d.cts +19 -0
- package/dist/three.d.ts +19 -0
- package/dist/three.js +118 -27
- package/dist/three.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -211,6 +211,70 @@ had *arrived* on a device that never *showed* it.)
|
|
|
211
211
|
`VIBRATION_PATTERNS.ignore` is empty on purpose: a tap that changed nothing must
|
|
212
212
|
not feel like it did.
|
|
213
213
|
|
|
214
|
+
## Closing the picker without marking anything
|
|
215
|
+
|
|
216
|
+
Opening a region writes **nothing** to the report — only choosing an intensity
|
|
217
|
+
does. So until 0.7.0 there was no exit from a region you opened by accident: your
|
|
218
|
+
options were to mark it (writing something you did not mean) or to open a
|
|
219
|
+
different region (which you also did not mean).
|
|
220
|
+
|
|
221
|
+
Both renderers now carry a close control (`bodymap-close` / `bodymap3d-close`),
|
|
222
|
+
and in the 3D renderer `Escape` closes the open region — falling through to
|
|
223
|
+
leaving fullscreen only when no region is open, so one press never does two
|
|
224
|
+
things.
|
|
225
|
+
|
|
226
|
+
**Close is not remove, and the distinction is deliberate:**
|
|
227
|
+
|
|
228
|
+
| | |
|
|
229
|
+
|---|---|
|
|
230
|
+
| **Close** | always available. Stops editing this region. **Never touches the report.** |
|
|
231
|
+
| **Remove** | only when something is actually marked. Deletes the mark. |
|
|
232
|
+
|
|
233
|
+
A «Remove» button offered while the report is empty tells the user something was
|
|
234
|
+
stored when nothing was — so it stays gated, and the close control is what fills
|
|
235
|
+
the gap.
|
|
236
|
+
|
|
237
|
+
**Why it went unnoticed for so long:** every test and demo in this package taps a
|
|
238
|
+
region *in order to mark it*. Nobody had ever tested changing their mind. Nothing
|
|
239
|
+
was behaving wrongly — it was a path with no exit, and paths with no exit do not
|
|
240
|
+
fail, they strand people.
|
|
241
|
+
|
|
242
|
+
## Fullscreen — fill the viewport with the body
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
// built-in control (default)
|
|
246
|
+
<BodyMap3D models={models} />
|
|
247
|
+
|
|
248
|
+
// your own button — you own the state
|
|
249
|
+
const [big, setBig] = useState(false);
|
|
250
|
+
<BodyMap3D models={models} fullscreen={big} onFullscreenChange={setBig} showFullscreenButton={false} />
|
|
251
|
+
<button onClick={() => setBig(true)}>Se stor</button>
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
`Escape` leaves it. The pain report is untouched by entering or leaving.
|
|
255
|
+
|
|
256
|
+
**It is a viewport fill, not the browser Fullscreen API — deliberately.** iOS
|
|
257
|
+
Safari does not support fullscreen on an arbitrary element at all, and a phone is
|
|
258
|
+
this component's primary surface. A `position: fixed; inset: 0` overlay behaves
|
|
259
|
+
identically on every platform, needs no user-gesture dance, and cannot leave you
|
|
260
|
+
with a control that silently does nothing on the one device that matters most.
|
|
261
|
+
|
|
262
|
+
### It ships with a `ResizeObserver`, and that is not incidental
|
|
263
|
+
|
|
264
|
+
Before 0.6.0 the canvas measured the element **once at mount** and only re-measured
|
|
265
|
+
on a **window** resize. Everything below changes the ELEMENT without touching the
|
|
266
|
+
window, and each one left the picture at its old size — a body that renders small,
|
|
267
|
+
off-centre, or clipped, with nothing wrong in the code because the camera maths is
|
|
268
|
+
correct and the numbers it was handed are stale:
|
|
269
|
+
|
|
270
|
+
- entering or leaving fullscreen
|
|
271
|
+
- switching `canvasHeight` at your own breakpoint
|
|
272
|
+
- a container animating open, or a wizard step revealing the panel
|
|
273
|
+
- **a phone's URL bar collapsing, which changes what `vh` means**
|
|
274
|
+
|
|
275
|
+
If you saw a badly framed body on a phone before 0.6.0, this is the first thing to
|
|
276
|
+
retest.
|
|
277
|
+
|
|
214
278
|
## `seam` — soft region edges are OPT-IN, and here is why
|
|
215
279
|
|
|
216
280
|
```tsx
|
package/dist/react.cjs
CHANGED
|
@@ -235,6 +235,7 @@ var LABELS_DA = {
|
|
|
235
235
|
intensity: "Intensitet (0-10)",
|
|
236
236
|
quality: "Kvalitet",
|
|
237
237
|
remove: "Fjern punkt",
|
|
238
|
+
close: "Luk",
|
|
238
239
|
front: "Forfra",
|
|
239
240
|
back: "Bagfra",
|
|
240
241
|
empty: "V\xE6lg en kropsdel for at markere smerte.",
|
|
@@ -257,6 +258,7 @@ var LABELS_EN = {
|
|
|
257
258
|
intensity: "Intensity (0-10)",
|
|
258
259
|
quality: "Quality",
|
|
259
260
|
remove: "Remove point",
|
|
261
|
+
close: "Close",
|
|
260
262
|
front: "Front",
|
|
261
263
|
back: "Back",
|
|
262
264
|
empty: "Pick a body part to mark pain.",
|
|
@@ -356,6 +358,10 @@ var STYLE = `
|
|
|
356
358
|
.bmap__panel--empty{color:var(--bmap-muted);font-size:13.5px}
|
|
357
359
|
.bmap__ph{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:12px}
|
|
358
360
|
.bmap__ph b{font-size:16px}
|
|
361
|
+
.bmap__close{margin-left:auto;font:inherit;font-size:20px;line-height:1;cursor:pointer;background:none;border:1px solid transparent;border-radius:8px;width:32px;height:32px;color:var(--bmap-muted,#475569)}
|
|
362
|
+
.bmap__close:hover{background:var(--bmap-badge-bg,#f1f5f9)}
|
|
363
|
+
.bmap__close:active{transform:scale(.94)}
|
|
364
|
+
.bmap__close:focus-visible{outline:2px solid var(--bmap-accent,#0e8f8a);outline-offset:2px}
|
|
359
365
|
.bmap__code{font:11px ui-monospace,monospace;color:var(--bmap-muted);background:var(--bmap-badge-bg);border-radius:6px;padding:2px 7px}
|
|
360
366
|
.bmap__lbl{font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--bmap-muted);margin:0 0 7px}
|
|
361
367
|
.bmap__scale{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:14px}
|
|
@@ -653,7 +659,18 @@ function BodyMap({
|
|
|
653
659
|
readOnly ? null : region ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bmap__panel", "data-testid": "bodymap-panel", children: [
|
|
654
660
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bmap__ph", children: [
|
|
655
661
|
/* @__PURE__ */ jsxRuntime.jsx("b", { children: nameOf(region.key) }),
|
|
656
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bmap__code", children: region.code })
|
|
662
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bmap__code", children: region.code }),
|
|
663
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
664
|
+
"button",
|
|
665
|
+
{
|
|
666
|
+
type: "button",
|
|
667
|
+
className: "bmap__close",
|
|
668
|
+
"data-testid": "bodymap-close",
|
|
669
|
+
"aria-label": L.close,
|
|
670
|
+
onClick: () => setSelected(null),
|
|
671
|
+
children: "\xD7"
|
|
672
|
+
}
|
|
673
|
+
)
|
|
657
674
|
] }),
|
|
658
675
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "bmap__lbl", id: "bmap-intensity-lbl", children: L.intensity }),
|
|
659
676
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bmap__scale", role: "group", "aria-labelledby": "bmap-intensity-lbl", children: Array.from({ length: 11 }, (_, n) => /* @__PURE__ */ jsxRuntime.jsx(
|