@junoput01/junoui 0.6.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/CHANGELOG.md CHANGED
@@ -1,5 +1,109 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - aad6351: **`.juno-btn--sm` promotes to the tap target on touch; `.juno-btn--dense` is the opt-out.**
8
+
9
+ `--sm` names a **density**, and consumers reach for it as a **semantic**. Audited across one app: 40 call sites, nearly all `--sm --ghost` meaning "secondary", shipping a 24px target on a phone — and junoui's own showcase does it twice, in a navbar action slot.
10
+
11
+ A size modifier should not quietly become a tap-target decision. Under `(pointer: coarse)`, `.juno-btn--sm` now holds `--juno-size-tap-min` like every other control. Type and padding still shrink, so it stays a density modifier and stops being a touch-target one. **On a fine pointer nothing changes** — still 24px, the WCAG 2.2 AA floor (2.5.8) exactly.
12
+
13
+ `.juno-btn--dense` opts a `--sm` button back out, for a toolbar that is genuinely dense on touch (a scrubber, an editor rail). It is meaningful only in combination with `--sm`, on purpose: a dense touch target should be chosen by name, never inherited from a size.
14
+
15
+ **This is a visual change on touch devices.** Any `--sm` button in a phone layout grows to 44px unless you add `--dense`. Audit your `--sm` call sites: the ones that meant "secondary" want `--ghost` alone and are now correct for free; the ones that meant "dense" want `--dense` added.
16
+
17
+ The rule lives in `button.css`, not `base.css`'s coarse block — a media query adds no specificity, so a `.juno-btn--sm` there would lose to `button.css`'s own `.juno-btn--sm` later in the bundle.
18
+
19
+ - 40a5e43: **Class manifest + `junoui/testing` — conformance kit slice 1.**
20
+
21
+ A `juno-*` class name in a consumer's source is a string that has to match something in junoui's stylesheet, and nothing checked it. When it does not match, nothing fails: the file compiles, the tests pass, and the element renders as unstyled UA defaults. One consumer shipped eleven such names in a dialog; on a phone that put the confirm button off the bottom of the screen with no way to reach it. junoui had the same defect pointing the other way — `.juno-seg__option` sat in a `touch-action` list that never matched anything, because the shipped class is `.juno-seg__opt`.
22
+
23
+ **New: `junoui/classes.json`**, generated at build time from the bundle's own selectors — `all`, `public` (the documented subset), `roles`, `components` grouped BEM-wise, plus the other `juno-*` namespaces junoui ships and a consumer writes as bare strings: `tokens`, `keyframes`, `icons`.
24
+
25
+ **New: `junoui/testing`**, dependency-free and framework-agnostic:
26
+
27
+ ```js
28
+ import { assertJunoClasses } from 'junoui/testing';
29
+ assertJunoClasses(['src/**/*.tsx'], { allowed: ['my-own-juno-namespaced-thing'] });
30
+ ```
31
+
32
+ It throws with every offending `file: name`, and throws rather than passing when its globs match no files.
33
+
34
+ **What it answers:** "junoui ships nothing by this name." **What it does not:** whether the class still does what your component assumes.
35
+
36
+ Nothing existing changes; both entries are additive.
37
+
38
+ - 447c133: The floating bar's offset from the bottom edge is now one token,
39
+ `--juno-dock-edge-offset`, consumed by both `.juno-dock--pill`/`--float`'s margin
40
+ and `--juno-dock-clearance`. Plus `--juno-dock-clearance-breathing` (default
41
+ `space-8`) for the gap between the bar and the last row.
42
+
43
+ No default changes: the offset still resolves to `space-16 + env(safe-area-inset-bottom)`
44
+ and the clearances to the same 86px / 78px they did at a 44px bubble.
45
+
46
+ What it fixes: the inset FORM used to be written separately at each site, so a
47
+ consumer whose design puts the bar flush above the home indicator —
48
+ `max(8px, env(safe-area-inset-bottom))` — changed its margin and could not change
49
+ the reservation, which kept adding. Measured at 16px of dead band at inset 0 and
50
+ 24px at inset 34, with no value of `--juno-dock-h` able to reconcile them because
51
+ one side added the inset and the other maxed it. Both now follow the token, so
52
+ they agree by construction at every inset.
53
+
54
+ - e852323: **The dock publishes its horizontal item budget.**
55
+
56
+ `.juno-dock__item` is `flex: 1 1 0`, so the bar divides its inner width by however many items are present. A consumer deciding how many to render — and whether they still hold a tap target — had to re-derive that from the numbers in `dock.css`. Two did, in prose, twice, and both drifted the same way: they subtracted 12px of inline padding where the pill actually spends 8 (`--juno-space-4` a side), so every per-item width came out ~0.8px low.
57
+
58
+ New custom properties on `.juno-dock`:
59
+
60
+ | Property | What it is |
61
+ | --------------------------- | --------------------------------------------------------------------------------------------- |
62
+ | `--juno-dock-items` | The item budget. You set it to what you render (default `5`). |
63
+ | `--juno-dock-item-inline` | The width one item gets — a prediction of the flex layout, asserted against the measured box. |
64
+ | `--juno-dock-fit-inline` | The narrowest viewport at which every item still holds `--juno-size-tap-comfortable`. |
65
+ | `--juno-dock-chrome-inline` | The bar's total inline chrome. `0` full-bleed, `34px` on `--pill`/`--float`. |
66
+ | `--juno-dock-avail` | The width the budget divides (default `100vw`). |
67
+
68
+ The margin, padding and border terms are declared once and consumed by both the variant's own box and the sum, so the budget cannot disagree with the bar it describes — the same construction as `--juno-dock-edge-offset`. One consequence worth knowing: `--pill`/`--float` now paint their border from `--juno-dock-border-inline`, so overriding that term to `0` removes the hairline as well as widening the items. That is deliberate — the sum follows the paint.
69
+
70
+ **No scale floor is published.** `44px / --juno-dock-item-inline` is a ratio of two lengths and CSS cannot divide by a length. A consumer that must scale rather than drop an item compares the two values itself.
71
+
72
+ ### Patch Changes
73
+
74
+ - 770f331: **fold-slot: the fold now reaches zero when composed with a component class.**
75
+ `.juno-fold` promises its inline-size folds to zero, and the canonical use puts it on an element that already carries the capsule chrome — `.juno-pillbar__item`, `.juno-btn`, `.juno-chip`. Composed that way it could not: `min-inline-size` (the 44px tap floor), `padding-inline` and `border-inline-width` each hold a border-box inline size open, and the folded state released none of them. Measured against the built bundle at a 390px viewport, composed with `.juno-pillbar__item`: 44px folded, 20px with the floor released, 0px with all three. A consumer's pill carried one dead 44px slot whenever the folded action was absent.
76
+
77
+ The folded state now releases all three, and each is in the fold's transition list so nothing snaps as the fold opens or shuts.
78
+
79
+ Also fixed, and invisible from the source: `transition` is a shorthand, `.juno-fold` was one class of specificity, and `pillbar.css` sorts after `fold-slot.css` — so `.juno-pillbar__item`'s own `transition` replaced the fold's whole list and the slot jumped shut instead of folding. The fold's declarations now sit at attribute specificity, and its transition list carries the chrome properties (`color`, `background-color`) too, since owning the shorthand means owning all of it. A component of your own that composes with `.juno-fold` and needs a third property transitioned must state it above `(0,2,0)`.
80
+
81
+ - a1f3f53: New `docs/ios-pwa.md`: a bounded statement of what junoui gives you on iOS and in
82
+ a Home-Screen web app — what you get for free, what your app must supply, and
83
+ what junoui explicitly does not do. `docs/ios-conformance.md` gains the
84
+ standalone `<head>` contract and names the letterbox flag
85
+ (`data-juno-letterboxed`, app-set, documented rather than shipped).
86
+
87
+ Docs ship in the package, so a consumer installing this version receives both.
88
+ Two corrections travel with them: the letterbox flag is **not** an upstream-fix
89
+ detector (that test needs a document that cannot scroll, and the unlock makes it
90
+ scroll), and `.juno-pagination`'s items take the coarse-pointer promotion on the
91
+ inline axis only — 44 × 32 on touch, which clears WCAG 2.5.8 AA and not the
92
+ 44 px comfortable target the docs previously implied.
93
+
94
+ - 4568157: **Two mistyped class names in the touch-default lists, and a tap floor for the segmented pill.**
95
+
96
+ `base.css` carries two `:where()` lists of junoui's own tappable components — one dropping double-tap-to-zoom recognition (`touch-action: manipulation`), one killing the UA tap-highlight square under `(pointer: coarse)`. Two members named classes that do not exist, so `:where()` matched nothing, the rule still parsed, every other member kept working, and the named components silently kept the defaults they were listed to opt out of:
97
+
98
+ - `.juno-seg__option` → `.juno-seg__opt` (touch-action list)
99
+ - `.juno-list__item` → `.juno-list__row` (**both** lists)
100
+
101
+ Every segmented control and every grouped list row in every consumer has been carrying the ~300ms double-tap delay. No consumer change is needed — the fix lands in the shipped stylesheet.
102
+
103
+ `.juno-seg__opt` was also the only interactive primitive with no tap floor: it computed 25.39px from its padding, which meets WCAG 2.2 AA (2.5.8, 24px) by accident and misses the comfortable touch target entirely. It now holds `--juno-size-tap-min` on the painted box, like `.juno-btn`. Measured against the built bundle: **fine pointer unchanged at 25.39px, coarse 25.39 → 44.00**, width unchanged either way — so no showcase baseline moves.
104
+
105
+ Unlike `.juno-btn--sm`, `.juno-seg--sm` does **not** drop below that floor: it reduces type and padding only. A segmented row is routinely the only control on a whole settings section, so a sub-tap variant of it has no safe use on a phone.
106
+
3
107
  ## 0.6.0
4
108
 
5
109
  ### Minor Changes
package/README.md CHANGED
@@ -78,22 +78,23 @@ feature newer than the floor.
78
78
 
79
79
  ## Documentation
80
80
 
81
- | | |
82
- | -------------------------------------------------------------------------------- | ------------------------------------------------------------- |
83
- | [Getting started](./docs/getting-started.md) | Install, model, what ships |
84
- | [Integration](./docs/integration.md) | Consuming in an app: import order, fonts, token bridge |
85
- | [Web](./docs/web.md) · [Native](./docs/native.md) · [Flutter](./docs/flutter.md) | Per-platform usage |
86
- | [Design guidelines](./docs/design-guidelines.md) | Color semantics, a11y — for any tool |
87
- | [Layout](./docs/layout.md) | Responsive primitives + container queries (how blocks adapt) |
88
- | [Boot shell](./docs/boot-shell.md) | Fast first paint: pre-bundle shell, lazy screens, warming |
89
- | [Accessibility](./docs/accessibility.md) | WCAG 2.2 + WAI-ARIA references, focus, motion, targets, RTL |
90
- | [iOS conformance](./docs/ios-conformance.md) | Sourced iOS metrics safe areas, tap targets, viewport units |
91
- | [Browser support](./docs/browser-support.md) | The supported floor, what degrades below it, what breaks |
92
- | [Token reference](./docs/tokens-reference.md) | Every token + value + platform name (generated) |
93
- | [Components](./docs/components/README.md) | 30+ forms, overlays, table, alerts, tabs, icons, nav, more |
94
- | [Release gate](./RELEASING.md) | The consumer build every release candidate must pass |
95
- | [Contributing](./CONTRIBUTING.md) | Add tokens/components, lint, test, release |
96
- | [Roadmap](./docs/roadmap.md) | Missing capabilities, prioritised |
81
+ | | |
82
+ | -------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
83
+ | [Getting started](./docs/getting-started.md) | Install, model, what ships |
84
+ | [Integration](./docs/integration.md) | Consuming in an app: import order, fonts, token bridge |
85
+ | [Web](./docs/web.md) · [Native](./docs/native.md) · [Flutter](./docs/flutter.md) | Per-platform usage |
86
+ | [Design guidelines](./docs/design-guidelines.md) | Color semantics, a11y — for any tool |
87
+ | [Layout](./docs/layout.md) | Responsive primitives + container queries (how blocks adapt) |
88
+ | [Boot shell](./docs/boot-shell.md) | Fast first paint: pre-bundle shell, lazy screens, warming |
89
+ | [Accessibility](./docs/accessibility.md) | WCAG 2.2 + WAI-ARIA references, focus, motion, targets, RTL |
90
+ | [iOS & PWA](./docs/ios-pwa.md) | The bounded claim: what's free, what you supply, what it won't do |
91
+ | [iOS conformance](./docs/ios-conformance.md) | Sourced iOS metrics safe areas, tap targets, viewport units |
92
+ | [Browser support](./docs/browser-support.md) | The supported floor, what degrades below it, what breaks |
93
+ | [Token reference](./docs/tokens-reference.md) | Every token + value + platform name (generated) |
94
+ | [Components](./docs/components/README.md) | 30+ forms, overlays, table, alerts, tabs, icons, nav, more |
95
+ | [Release gate](./RELEASING.md) | The consumer build every release candidate must pass |
96
+ | [Contributing](./CONTRIBUTING.md) | Add tokens/components, lint, test, release |
97
+ | [Roadmap](./docs/roadmap.md) | Missing capabilities, prioritised |
97
98
 
98
99
  ## Repository
99
100