@broberg/bodymap 0.6.0 → 0.7.1
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 +44 -1
- 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 +37 -6
- package/dist/three.cjs.map +1 -1
- package/dist/three.d.cts +2 -0
- package/dist/three.d.ts +2 -0
- package/dist/three.js +37 -6
- package/dist/three.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -211,6 +211,34 @@ 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
|
+
|
|
214
242
|
## Fullscreen — fill the viewport with the body
|
|
215
243
|
|
|
216
244
|
```tsx
|
|
@@ -223,7 +251,22 @@ const [big, setBig] = useState(false);
|
|
|
223
251
|
<button onClick={() => setBig(true)}>Se stor</button>
|
|
224
252
|
```
|
|
225
253
|
|
|
226
|
-
`Escape` leaves it
|
|
254
|
+
`Escape` leaves it — **but a phone has no Escape**, so there must always be a
|
|
255
|
+
reachable control. That is why the built-in one exists and why switching it off is
|
|
256
|
+
a commitment to supplying your own.
|
|
257
|
+
|
|
258
|
+
⚠️ **If you supply your own control, render it as a SIBLING of the fullscreen
|
|
259
|
+
surface — not as a child of a container beneath it.** The surface is
|
|
260
|
+
`position: fixed`, so a button positioned `absolute` inside your original box ends
|
|
261
|
+
up *underneath* it. A consumer hit exactly this: their × disappeared under the
|
|
262
|
+
overlay, and because they had already set `showFullscreenButton={false}` there was
|
|
263
|
+
no way out at all. Give yours `position: fixed` and a z-index above the overlay,
|
|
264
|
+
and assert with `document.elementFromPoint()` that the point you can see is the
|
|
265
|
+
button you think it is.
|
|
266
|
+
|
|
267
|
+
The control sits inside the safe area (`env(safe-area-inset-*)` on all four sides),
|
|
268
|
+
and becomes a compact × in fullscreen — a text pill is wide enough to cover half a
|
|
269
|
+
phone's status bar. The pain report is untouched by entering or leaving.
|
|
227
270
|
|
|
228
271
|
**It is a viewport fill, not the browser Fullscreen API — deliberately.** iOS
|
|
229
272
|
Safari does not support fullscreen on an arbitrary element at all, and a phone is
|
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(
|