@kungal/ui-tokens 2.28.0 → 2.30.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/CHANGELOG.md CHANGED
@@ -1,5 +1,75 @@
1
1
  # @kungal/ui-tokens
2
2
 
3
+ ## 2.30.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 1ec5cc6: Scroll lock: publish the scrollbar width it removes, and stop compensating a page that lost nothing
8
+
9
+ Opening a Modal, Drawer, Lightbox or CommandPalette hides the page scrollbar.
10
+ KunUI compensates by padding `<body>`, which holds in-flow content still but
11
+ cannot reach anything `position: fixed` — fixed positioning resolves against the
12
+ initial containing block, and that grows by the scrollbar width. Measured on
13
+ this repo's own docs site (Chromium 152, 15.2px classic scrollbar): a
14
+ `top-right` toast went from `right = 1458.4` to `right = 1473.6` when the
15
+ command palette opened, and a probe fixed at `right: 1rem` moved the same
16
+ 15.2px. There was no way for a consumer to correct it either, because the number
17
+ was never exposed.
18
+
19
+ It is now published on `<html>` as `--kun-scrollbar-width` for as long as a lock
20
+ is held, so a fixed header, FAB or side rail can take it back:
21
+
22
+ ```css
23
+ .my-fixed-toolbar {
24
+ right: 1rem;
25
+ margin-right: var(--kun-scrollbar-width, 0px);
26
+ }
27
+ ```
28
+
29
+ Apply it as a **margin**, not folded into `left`/`right`: a declaration
30
+ containing `var()` is only validated after substitution, so a value that isn't a
31
+ length invalidates the whole declaration — a dropped margin merely loses the
32
+ compensation, a dropped `left` sends the element to its static position.
33
+ `@kungal/ui-tokens` ships the `0px` resting value; keep the `0px` fallback
34
+ anyway if you may be used without it. This is the same contract Radix
35
+ (`--removed-body-scroll-bar-size`) and Reka (`--scrollbar-width`) expose.
36
+
37
+ `KunMessageProvider` now uses it to hold its own toasts still — all of the width
38
+ for the right-anchored placements, half for the centred ones, none for the
39
+ left-anchored ones.
40
+
41
+ **Also fixed:** a page that already set `scrollbar-gutter: stable` on `<html>`
42
+ was compensated on top of a gutter that was never lost, so KunUI's padding _was_
43
+ the layout shift — measured at 16px of content shrink on every open. The lock
44
+ now detects a reserved gutter and adds nothing. On overlay-scrollbar platforms
45
+ (macOS, iOS, most mobile) nothing is removed either, and the published width is
46
+ `0px` in both cases, so one consumer declaration is correct everywhere.
47
+
48
+ **Why KunUI does not set `scrollbar-gutter: stable` itself**, though it would
49
+ hold fixed elements still and react-aria and Base UI both do it: a reserved
50
+ gutter sits outside the initial containing block, and page content cannot paint
51
+ there by any means — measured in Chrome 152, `right: -32px`, `width: 100vw` and
52
+ a negative margin all still clipped at the ICB edge, and
53
+ `document.elementFromPoint()` in the gutter returned `null`. Every full-bleed
54
+ backdrop would stop ~15px short of the screen edge and show the page background
55
+ as a bright band down the side of a dim modal, and a right-anchored Drawer would
56
+ float 15.6px off the edge. Reserving the gutter is only viable together with
57
+ keeping the scrollbar _rendered_, which is a larger change than this one.
58
+
59
+ The scroll lock's standing limitations are now written down in
60
+ `docs/INTEGRATION.md` §5 — most usefully, it does nothing at all on a page whose
61
+ scroll container is `<html>` rather than `<body>` (`html { overflow-y: scroll }`
62
+ and friends), which has always been true and is now stated.
63
+
64
+ **What it costs you:** nothing to change. The only new thing KunUI touches is
65
+ one custom property on `<html>`, saved and put back on close so a value of your
66
+ own survives; if you observe root attribute mutations, expect a `style` change
67
+ on open and on close. If you were correcting KunUI's shift by hand in an app
68
+ stylesheet, replace it with the variable — it is correct on the platforms where
69
+ your hand-rolled constant was not.
70
+
71
+ ## 2.29.0
72
+
3
73
  ## 2.28.0
4
74
 
5
75
  ## 2.27.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kungal/ui-tokens",
3
- "version": "2.28.0",
3
+ "version": "2.30.0",
4
4
  "description": "KunUI design tokens — framework-agnostic Tailwind v4 theme (semantic colors, radius, z-index, animations).",
5
5
  "type": "module",
6
6
  "keywords": [
package/src/tokens.css CHANGED
@@ -311,6 +311,30 @@
311
311
  z-index: var(--z-kun-message, 9999);
312
312
  }
313
313
 
314
+ /* How much viewport width an open overlay took away when it hid the page
315
+ * scrollbar. `useBodyScrollLock` writes the live value onto <html> while a
316
+ * Modal/Drawer/Lightbox/CommandPalette is open and removes it on close; this
317
+ * declaration is the unlocked resting value so a consumer never has to reason
318
+ * about the variable being absent.
319
+ *
320
+ * It is 0 whenever nothing was actually removed — overlay scrollbars, or a page
321
+ * that reserves its own `scrollbar-gutter: stable`. Otherwise it is the
322
+ * scrollbar width, and the initial containing block really did grow, so a
323
+ * `position: fixed` element that is right-anchored or centred needs it. Apply
324
+ * it as a MARGIN, not folded into the anchor: an invalid var() substitution
325
+ * makes the whole declaration invalid at computed-value time, and a dropped
326
+ * margin merely loses the compensation where a dropped `left` sends the element
327
+ * to its static position.
328
+ *
329
+ * margin-right: var(--kun-scrollbar-width, 0px);
330
+ *
331
+ * Plain :root + a literal fallback at every use, same reasoning as the z-index
332
+ * and border blocks: a @theme variable can be tree-shaken out of a consumer's
333
+ * build. */
334
+ :root {
335
+ --kun-scrollbar-width: 0px;
336
+ }
337
+
314
338
  /* Canonical neutral border — the SINGLE source of truth for every structural
315
339
  * hairline (inputs, cards, dividers, popovers, tabs, tables…). Defaults to the
316
340
  * `default-100` step — a very light hairline that just delineates a surface