@junoput01/junoui 0.6.0 → 0.8.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 +209 -0
- package/README.md +17 -16
- package/dist/android/dimens.xml +2 -0
- package/dist/classes.json +1774 -0
- package/dist/css/juno-tokens.css +10 -0
- package/dist/css/juno.css +1057 -56
- package/dist/flutter/juno_tokens.dart +10 -0
- package/dist/ios/JunoTokens.swift +10 -0
- package/dist/js/tokens.js +16 -0
- package/dist/json/tokens.json +51 -0
- package/dist/rust/juno_tokens.rs +383 -0
- package/dist/scss/_juno-tokens.scss +10 -0
- package/docs/accessibility.md +6 -0
- package/docs/browser-support.md +3 -0
- package/docs/components/button.md +11 -2
- package/docs/components/canvas-ink.md +71 -0
- package/docs/components/dock.md +34 -0
- package/docs/components/fold-slot.md +26 -1
- package/docs/components/gizmo.md +114 -0
- package/docs/components/swatch.md +95 -0
- package/docs/components/tree.md +112 -0
- package/docs/conformance-kit.md +255 -0
- package/docs/getting-started.md +14 -0
- package/docs/integration.md +52 -6
- package/docs/ios-conformance.md +200 -3
- package/docs/ios-pwa.md +273 -0
- package/docs/native.md +38 -1
- package/docs/tokens-reference.md +15 -0
- package/package.json +8 -2
- package/src/css/base.css +35 -43
- package/src/css/components/button.css +42 -2
- package/src/css/components/canvas-ink.css +97 -0
- package/src/css/components/dock.css +65 -6
- package/src/css/components/fold-slot.css +49 -3
- package/src/css/components/gizmo.css +238 -0
- package/src/css/components/segmented.css +15 -2
- package/src/css/components/swatch.css +187 -0
- package/src/css/components/tree.css +259 -0
- package/src/css/touch-surfaces.mjs +95 -0
- package/tools/gizmo.mjs +144 -0
- package/tools/testing.mjs +177 -0
- package/tools/tree.mjs +178 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,214 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 584359f: **Canvas ink — a halo pair for UI drawn over arbitrary imagery.**
|
|
8
|
+
|
|
9
|
+
junoui's contrast story assumes a controlled surface, `s0` through `s3`: every role colour's ratio is computed against a known background. Content drawn over a photo, a map, a video frame or a camera feed has no known background — in one orthophoto a black shadow and a snowfield are adjacent pixels, so no single ink colour is legible and no contrast ratio can be asserted about one.
|
|
10
|
+
|
|
11
|
+
New `ink.canvas.ink` / `ink.canvas.halo`: a pair that spans the luminance range, applied together. Over a light backing the halo carries the contrast, over a dark one the ink does. Plus `ink.vivid.*` (role hues at raised chroma, since chrome-tuned hues wash out over a saturated backdrop) and `ink.canvas.scrim` (`0.28`, for chrome floating over live content — deliberately distinct from `opacity.scrim` at `0.62`, which suppresses a modal's background and here would grey out the content being annotated).
|
|
12
|
+
|
|
13
|
+
Shipped as CSS you can apply, not only as tokens: `.juno-canvas-ink` (+ `--lg` and the role modifiers), `.juno-canvas-ink__halo` / `__stroke` for vector marks, and `.juno-canvas-scrim` with a reduced-transparency fallback. Every platform target carries the tokens — CSS, SCSS, JS, Swift, Dart, Android and Rust.
|
|
14
|
+
|
|
15
|
+
**The pair is not themed**, on purpose: a satellite image does not get lighter because the user chose light mode.
|
|
16
|
+
|
|
17
|
+
**The halo is pure black because the arithmetic requires it.** The worst backing is a mid grey where both halves are weakest; the sweep floor there is 4.61:1 against a 4.5:1 requirement, and a near-black with a blue cast measures 4.43:1 and fails. The guard sweeps all 256 grey backings rather than sampling the extremes, which are the easy cases.
|
|
18
|
+
|
|
19
|
+
Additive: no existing token or output changes.
|
|
20
|
+
|
|
21
|
+
- 63ddc0e: **Viewport orientation gizmo — compass ring, pitch arc, snap targets.**
|
|
22
|
+
|
|
23
|
+
The orientation widget any 3D or map viewport ships: a ring showing a heading with clickable snap targets, a secondary arc for a second angle (pitch, tilt, elevation) inside a clamped range, and a centre target that resets the view. For CAD and BIM viewers, product configurators, virtual tours, model previews, floor plans, and any map with a tilt.
|
|
24
|
+
|
|
25
|
+
**A ring, not a cube.** An Autodesk-style ViewCube is the wrong shape for anything with a privileged up-vector — a map, a terrain, a site plan — because there is no meaningful front, right or bottom face to click. A ring degrades to that case and generalises to free orbit; a cube does not go the other way.
|
|
26
|
+
|
|
27
|
+
**The app owns the camera.** It writes `--juno-gizmo-heading` and `--juno-gizmo-pitch`; junoui rotates the needle and the hand and never stores an angle.
|
|
28
|
+
|
|
29
|
+
The accessibility contract is why this is upstream rather than app-local: snap targets are real `<button>`s (focusable, activate on Enter _and_ Space, announced as controls, work in a screen reader's forms mode); every mark carries a real name, because `"N"` is a letter and not one; the widget is **one focus stop** with wrapping arrow keys, not eight tab stops for eight compass points; and the bearing is announced in words through a live region, because a rotating needle announces nothing and `"37deg"` is a number the listener has to convert.
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
import { enhanceGizmo, orientationLabel, bearingLabel } from 'junoui/gizmo';
|
|
33
|
+
bearingLabel(37); // → "north-east"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**The ring's diameter is derived, not chosen:** `d ≥ tap · (1 / sin(π/N) + 1)`. The tap floor moves from 24px to 44px on a coarse pointer, so a hard-coded diameter ships eight overlapping targets to a phone.
|
|
37
|
+
|
|
38
|
+
- cc1e29d: **Rust token target — `junoui/rust`.**
|
|
39
|
+
|
|
40
|
+
junoui compiles one DTCG source to CSS, SCSS, JS, Android XML, iOS Swift, Flutter Dart and DTCG JSON. Rust was the one mainstream native target missing, so a Rust consumer had to hand-transcribe hex values — which drift silently on the first patch release, with no lint to catch the stale copy. That is the mirrored-constant defect; this removes the reason to commit it.
|
|
41
|
+
|
|
42
|
+
`dist/rust/juno_tokens.rs` (exported as `junoui/rust`) is a dependency-free const module for any native Rust stack — egui, iced, Slint, Bevy, Dioxus desktop, Tauri's Rust side:
|
|
43
|
+
|
|
44
|
+
```rust
|
|
45
|
+
let bg = STANDARD_DARK.s0.to_f32_array(); // a whole theme, picked at runtime
|
|
46
|
+
let accent = STANDARD_DARK_ACTIVE; // or one role, flat
|
|
47
|
+
let gap = SPACE_16; // f32 px
|
|
48
|
+
let fade = MOTION_DURATION_BASE_MS; // f32 milliseconds
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Colors become an `Rgba` struct with `const fn hex()`, `to_f32_array()` and `with_alpha()`; core tokens are bucketed by the **form** of their value rather than by which file they came from — `px` → `f32`, `ms` → `f32` suffixed `_MS`, whole numbers → `i32`, ratios → `f32`, and CSS-authored strings (shadows, font stacks) shipped verbatim as `&str`.
|
|
52
|
+
|
|
53
|
+
Beyond the flat constants the Swift and Dart targets ship, there is a `Palette` struct and one const per palette/mode, because a Rust app picks a theme at runtime and wants a value it can pass around. Its fields and the constants that fill it both come from junoui's role list, so a role cannot reach one and miss the other.
|
|
54
|
+
|
|
55
|
+
`to_f32_array()` is sRGB-encoded, not linear — convert at your boundary if your pipeline wants linear.
|
|
56
|
+
|
|
57
|
+
Additive: no existing output changes.
|
|
58
|
+
|
|
59
|
+
- cd1dd93: **Colour swatch + palette.**
|
|
60
|
+
|
|
61
|
+
`classes.json` 0.7.0 had no class matching _swatch_ or _color_: no way to show a user-chosen colour or let someone pick one. For diagrams, calendars, tag and label systems, chart series colours, annotation tools, theming UIs and kanban boards.
|
|
62
|
+
|
|
63
|
+
**The hard part is not the square.** A swatch shows an arbitrary colour, so its border, its focus ring and its checked indicator all have to stay visible against a colour junoui has never seen. The border is a **pair** of hairlines that do different jobs: the inset one composites over the _swatch_ and edges it against its own fill; the outset one composites over the _panel_ and separates it from the surface. With the swatch's own contrast against that panel, the boundary has three ways to be visible and needs only one.
|
|
64
|
+
|
|
65
|
+
The alphas are measured, not chosen: at 0.45 / 0.35 a mid-grey swatch on a light panel leaves the best of the three at **2.57:1**, under the 3:1 non-text floor. At 0.65 the worst case is 3.39:1. The guard sweeps the swatch colour against both panels and keeps the old values as its control.
|
|
66
|
+
|
|
67
|
+
**Focus rings sit outside the swatch**, so their contrast is against the panel — a known surface. A ring drawn _on_ the swatch has the same unsolvable problem as the border, and a thicker ring does not fix a hue collision.
|
|
68
|
+
|
|
69
|
+
**Colour is never the only signal**, which is junoui's own rule and exactly what a bare swatch violates: every swatch carries an accessible name, the checked state is a **glyph** (with a dark halo, since it sits on the arbitrary colour) _plus_ a ring, and `--none` is a slash rather than a grey — a consumer without it paints unset as mid grey and the user cannot tell _grey_ from _none_.
|
|
70
|
+
|
|
71
|
+
`.juno-palette` is the grid that goes inside an existing `.juno-popover`; the app owns the colour list and the state.
|
|
72
|
+
|
|
73
|
+
- 671db90: **Tree / outliner — nested rows, disclosure, selection, reorder.**
|
|
74
|
+
|
|
75
|
+
`.juno-list` is flat and `.juno-accordion` is single-level. `.juno-tree` nests to arbitrary depth and carries a selection, a count slot, the same trailing-control slot `.juno-list__row` has, and a reorder handle. For layer stacks, file browsers, settings trees, org charts, comment threads and nested navigation.
|
|
76
|
+
|
|
77
|
+
**Zero JS for the visuals.** Indentation comes from the nested `role="group"` lists the ARIA pattern already requires, so depth is structural — no per-row custom property, no level number to keep in sync with `aria-level`. Collapse is `[aria-expanded="false"]` on the item, which the app owns, exactly like `aria-pressed` elsewhere.
|
|
78
|
+
|
|
79
|
+
**Keyboard is not optional and is not CSS.** A tree without arrow-key traversal and a roving tabindex is a list of buttons wearing tree roles, so junoui ships a stateless enhancer at `junoui/tree`:
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
import { enhanceTree } from 'junoui/tree';
|
|
83
|
+
const stop = enhanceTree(document.querySelector('.juno-tree'));
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
It stores nothing — expansion and selection live on the DOM and belong to you. It moves focus and dispatches `juno-tree-toggle` / `juno-tree-select` (bubbling, cancelable, `detail.item`); it does not expand, collapse, select or reorder, because expanding a node may need to load it.
|
|
87
|
+
|
|
88
|
+
**Three states that get conflated are painted separately:** `:hover` is where the pointer is, `aria-current` is which node you are on, `aria-selected` is what the next action applies to. A layer stack has all three at once.
|
|
89
|
+
|
|
90
|
+
**Touch.** The row holds `--juno-size-tap-min`. The caret and handle paint small so a dense tree stays dense and grow only their _hit area_ — a 44px painted caret would swallow its row. The handle is explicit and carries `touch-action: none` on itself alone: long-press-drag is the obvious gesture and the wrong one, because a tree beside a pan surface has to let the pan win.
|
|
91
|
+
|
|
92
|
+
Reorder _logic_ stays yours; junoui ships the affordance, its hit area, and the drop styling (`data-juno-drop="before|after|into"`, `data-juno-dragging`) — where a between-rows drop and an into-a-row drop look different, because they are different operations.
|
|
93
|
+
|
|
94
|
+
### Patch Changes
|
|
95
|
+
|
|
96
|
+
- 4f466ff: **The touch defaults are generated from one declared set — conformance kit slice 2.**
|
|
97
|
+
|
|
98
|
+
`base.css` carried two hand-maintained `:where()` lists, and both had drifted.
|
|
99
|
+
|
|
100
|
+
**From the classes:** `.juno-seg__option` (the shipped class is `.juno-seg__opt`) and `.juno-list__item` (it is `.juno-list__row`) sat in them. `:where()` matched nothing, the rule still parsed, every other member kept working — so every segmented control and every grouped list row in every consumer kept the ~300ms double-tap delay.
|
|
101
|
+
|
|
102
|
+
**From each other:** the tap-highlight list was a strict subset of the touch-action one, missing `__overflow`, `__opt`, `chip` and `toggle-btn`.
|
|
103
|
+
|
|
104
|
+
**Consumer-visible change:** `.juno-chip`, `.juno-pillbar__overflow`, `.juno-seg__opt` and `.juno-toggle-btn` now have their UA tap-highlight square suppressed on a coarse pointer, like every other tappable primitive. Verified in Chromium on both pointer types. Nothing else moves.
|
|
105
|
+
|
|
106
|
+
`src/css/touch-surfaces.mjs` is now the source of truth; the two rules are emitted from it. Adding a component to the touch defaults is one line and gets both. `touch-action` stays outside the coarse block — a hybrid device reports a fine primary pointer while still taking touch input — and the highlight stays inside it.
|
|
107
|
+
|
|
108
|
+
## 0.7.0
|
|
109
|
+
|
|
110
|
+
### Minor Changes
|
|
111
|
+
|
|
112
|
+
- aad6351: **`.juno-btn--sm` promotes to the tap target on touch; `.juno-btn--dense` is the opt-out.**
|
|
113
|
+
|
|
114
|
+
`--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.
|
|
115
|
+
|
|
116
|
+
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.
|
|
117
|
+
|
|
118
|
+
`.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.
|
|
119
|
+
|
|
120
|
+
**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.
|
|
121
|
+
|
|
122
|
+
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.
|
|
123
|
+
|
|
124
|
+
- 40a5e43: **Class manifest + `junoui/testing` — conformance kit slice 1.**
|
|
125
|
+
|
|
126
|
+
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`.
|
|
127
|
+
|
|
128
|
+
**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`.
|
|
129
|
+
|
|
130
|
+
**New: `junoui/testing`**, dependency-free and framework-agnostic:
|
|
131
|
+
|
|
132
|
+
```js
|
|
133
|
+
import { assertJunoClasses } from 'junoui/testing';
|
|
134
|
+
assertJunoClasses(['src/**/*.tsx'], { allowed: ['my-own-juno-namespaced-thing'] });
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
It throws with every offending `file: name`, and throws rather than passing when its globs match no files.
|
|
138
|
+
|
|
139
|
+
**What it answers:** "junoui ships nothing by this name." **What it does not:** whether the class still does what your component assumes.
|
|
140
|
+
|
|
141
|
+
Nothing existing changes; both entries are additive.
|
|
142
|
+
|
|
143
|
+
- 447c133: The floating bar's offset from the bottom edge is now one token,
|
|
144
|
+
`--juno-dock-edge-offset`, consumed by both `.juno-dock--pill`/`--float`'s margin
|
|
145
|
+
and `--juno-dock-clearance`. Plus `--juno-dock-clearance-breathing` (default
|
|
146
|
+
`space-8`) for the gap between the bar and the last row.
|
|
147
|
+
|
|
148
|
+
No default changes: the offset still resolves to `space-16 + env(safe-area-inset-bottom)`
|
|
149
|
+
and the clearances to the same 86px / 78px they did at a 44px bubble.
|
|
150
|
+
|
|
151
|
+
What it fixes: the inset FORM used to be written separately at each site, so a
|
|
152
|
+
consumer whose design puts the bar flush above the home indicator —
|
|
153
|
+
`max(8px, env(safe-area-inset-bottom))` — changed its margin and could not change
|
|
154
|
+
the reservation, which kept adding. Measured at 16px of dead band at inset 0 and
|
|
155
|
+
24px at inset 34, with no value of `--juno-dock-h` able to reconcile them because
|
|
156
|
+
one side added the inset and the other maxed it. Both now follow the token, so
|
|
157
|
+
they agree by construction at every inset.
|
|
158
|
+
|
|
159
|
+
- e852323: **The dock publishes its horizontal item budget.**
|
|
160
|
+
|
|
161
|
+
`.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.
|
|
162
|
+
|
|
163
|
+
New custom properties on `.juno-dock`:
|
|
164
|
+
|
|
165
|
+
| Property | What it is |
|
|
166
|
+
| --------------------------- | --------------------------------------------------------------------------------------------- |
|
|
167
|
+
| `--juno-dock-items` | The item budget. You set it to what you render (default `5`). |
|
|
168
|
+
| `--juno-dock-item-inline` | The width one item gets — a prediction of the flex layout, asserted against the measured box. |
|
|
169
|
+
| `--juno-dock-fit-inline` | The narrowest viewport at which every item still holds `--juno-size-tap-comfortable`. |
|
|
170
|
+
| `--juno-dock-chrome-inline` | The bar's total inline chrome. `0` full-bleed, `34px` on `--pill`/`--float`. |
|
|
171
|
+
| `--juno-dock-avail` | The width the budget divides (default `100vw`). |
|
|
172
|
+
|
|
173
|
+
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.
|
|
174
|
+
|
|
175
|
+
**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.
|
|
176
|
+
|
|
177
|
+
### Patch Changes
|
|
178
|
+
|
|
179
|
+
- 770f331: **fold-slot: the fold now reaches zero when composed with a component class.**
|
|
180
|
+
`.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.
|
|
181
|
+
|
|
182
|
+
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.
|
|
183
|
+
|
|
184
|
+
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)`.
|
|
185
|
+
|
|
186
|
+
- a1f3f53: New `docs/ios-pwa.md`: a bounded statement of what junoui gives you on iOS and in
|
|
187
|
+
a Home-Screen web app — what you get for free, what your app must supply, and
|
|
188
|
+
what junoui explicitly does not do. `docs/ios-conformance.md` gains the
|
|
189
|
+
standalone `<head>` contract and names the letterbox flag
|
|
190
|
+
(`data-juno-letterboxed`, app-set, documented rather than shipped).
|
|
191
|
+
|
|
192
|
+
Docs ship in the package, so a consumer installing this version receives both.
|
|
193
|
+
Two corrections travel with them: the letterbox flag is **not** an upstream-fix
|
|
194
|
+
detector (that test needs a document that cannot scroll, and the unlock makes it
|
|
195
|
+
scroll), and `.juno-pagination`'s items take the coarse-pointer promotion on the
|
|
196
|
+
inline axis only — 44 × 32 on touch, which clears WCAG 2.5.8 AA and not the
|
|
197
|
+
44 px comfortable target the docs previously implied.
|
|
198
|
+
|
|
199
|
+
- 4568157: **Two mistyped class names in the touch-default lists, and a tap floor for the segmented pill.**
|
|
200
|
+
|
|
201
|
+
`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:
|
|
202
|
+
|
|
203
|
+
- `.juno-seg__option` → `.juno-seg__opt` (touch-action list)
|
|
204
|
+
- `.juno-list__item` → `.juno-list__row` (**both** lists)
|
|
205
|
+
|
|
206
|
+
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.
|
|
207
|
+
|
|
208
|
+
`.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.
|
|
209
|
+
|
|
210
|
+
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.
|
|
211
|
+
|
|
3
212
|
## 0.6.0
|
|
4
213
|
|
|
5
214
|
### 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
|
|
91
|
-
| [
|
|
92
|
-
| [
|
|
93
|
-
| [
|
|
94
|
-
| [
|
|
95
|
-
| [
|
|
96
|
-
| [
|
|
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
|
|
package/dist/android/dimens.xml
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
<dimen name="bp_lg">1024dp</dimen>
|
|
10
10
|
<dimen name="bp_xl">1280dp</dimen>
|
|
11
11
|
<dimen name="bp_2xl">1536dp</dimen>
|
|
12
|
+
<dimen name="ink_canvas_halo-width">2dp</dimen>
|
|
13
|
+
<dimen name="ink_canvas_halo-width-lg">3dp</dimen>
|
|
12
14
|
<dimen name="radius_2">2dp</dimen>
|
|
13
15
|
<dimen name="radius_3">3dp</dimen>
|
|
14
16
|
<dimen name="radius_4">4dp</dimen>
|