@ponchia/ui 0.8.0 → 0.9.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 +125 -0
- package/README.md +3 -3
- package/classes/classes.json +26 -3
- package/classes/index.d.ts +8 -0
- package/classes/index.js +8 -0
- package/css/core.css +1 -0
- package/css/overlay.css +24 -10
- package/css/row.css +154 -0
- package/css/workbench.css +1 -1
- package/dist/bronto.css +1 -1
- package/dist/css/overlay.css +1 -1
- package/dist/css/row.css +1 -0
- package/dist/css/workbench.css +1 -1
- package/docs/migrations/0.7-to-0.8.md +216 -0
- package/docs/migrations/0.8-to-0.9.md +66 -0
- package/docs/package-contract.md +5 -1
- package/docs/reference.md +14 -1
- package/docs/reporting.md +8 -8
- package/docs/stability.md +2 -1
- package/docs/theming.md +16 -0
- package/docs/usage.md +42 -0
- package/llms.txt +1 -1
- package/package.json +17 -13
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# Migrating 0.7 to 0.8
|
|
2
|
+
|
|
3
|
+
Machine-readable migration graph: [`MIGRATIONS.json`](../../MIGRATIONS.json) —
|
|
4
|
+
it has no entry for this pair, because nothing was renamed or removed. Every
|
|
5
|
+
class, token, attribute, and export valid in 0.7 is still valid.
|
|
6
|
+
|
|
7
|
+
0.8.0 comes from auditing one real consumer's stylesheet in full. It repairs an
|
|
8
|
+
accessibility floor, adds three surfaces that consumer had to hand-write, and
|
|
9
|
+
changes what a colorway does. Only the last of those needs a decision from you.
|
|
10
|
+
|
|
11
|
+
## 1. Decide what your skins should look like — the one breaking change
|
|
12
|
+
|
|
13
|
+
**Only affects you if you set `data-bronto-skin`.** If you don't, skip to §2.
|
|
14
|
+
|
|
15
|
+
Until 0.7, a colorway moved `--accent` and nothing else; the neutral canvas
|
|
16
|
+
stayed grey, and ADR-0001 step 4 said so. From 0.8 a colorway also re-points ten
|
|
17
|
+
canvas tokens per theme:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
--bg --bg-elevated --panel --panel-strong --panel-soft
|
|
21
|
+
--line --line-strong --text --text-soft --text-dim
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
So "Amber CRT" now actually renders amber. Nothing in your source changes and no
|
|
25
|
+
checker will flag anything — the break is purely visual, which is why it is
|
|
26
|
+
worth reading rather than discovering.
|
|
27
|
+
|
|
28
|
+
**Contrast is not a regression risk.** Each neutral keeps the core token's OKLCH
|
|
29
|
+
*lightness* exactly and moves only hue plus a small chroma, and `check-contrast`
|
|
30
|
+
re-measures all 21 gated pairings per skin per theme. Status colours
|
|
31
|
+
(`--success` / `--warning` / `--danger` / `--info`) are untouched by design: a
|
|
32
|
+
warning must look like a warning in every skin.
|
|
33
|
+
|
|
34
|
+
### If you already hand-wrote a canvas for a skin
|
|
35
|
+
|
|
36
|
+
Delete it. That workaround is what motivated this change, and a hand-rolled
|
|
37
|
+
version is almost certainly not contrast-gated, probably covers one theme, and
|
|
38
|
+
probably misses whichever skin nobody opened.
|
|
39
|
+
|
|
40
|
+
### If you want the 0.7 look back
|
|
41
|
+
|
|
42
|
+
Re-declare the ten tokens after the skin import. They are ordinary custom
|
|
43
|
+
properties on a `:root[data-bronto-skin=…]` selector inside `@layer bronto`, so
|
|
44
|
+
un-layered app CSS wins without a specificity fight:
|
|
45
|
+
|
|
46
|
+
```css
|
|
47
|
+
@import '@ponchia/ui';
|
|
48
|
+
@import '@ponchia/ui/css/skins.css';
|
|
49
|
+
|
|
50
|
+
/* Keep the neutral canvas grey under every colorway. */
|
|
51
|
+
:root[data-bronto-skin] {
|
|
52
|
+
--bg: #f4f4f2;
|
|
53
|
+
--bg-elevated: #fbfbfa;
|
|
54
|
+
--panel: #ffffff;
|
|
55
|
+
--panel-strong: #ffffff;
|
|
56
|
+
--panel-soft: #ececea;
|
|
57
|
+
--line: #d8d8d4;
|
|
58
|
+
--line-strong: #a8a8a2;
|
|
59
|
+
--text: #0a0a0a;
|
|
60
|
+
--text-soft: #353533;
|
|
61
|
+
--text-dim: #686863;
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
(Those are the 0.7 light values; take the dark set from `tokens/resolved.json`
|
|
66
|
+
and repeat under `:root[data-theme='dark'][data-bronto-skin]`.)
|
|
67
|
+
|
|
68
|
+
## 2. Delete your tap-target workaround
|
|
69
|
+
|
|
70
|
+
The coarse-pointer floor was written as a bare `2.9rem`, and `css/base.css` sets
|
|
71
|
+
`html { font-size: 0.9375rem }` — so it resolved to **43.5px**, half a pixel
|
|
72
|
+
under the 44 that WCAG 2.5.5 and both platform HIGs require, and less than that
|
|
73
|
+
under any host with a smaller root. If you noticed and declared your own 44px
|
|
74
|
+
floor, you can now drop it:
|
|
75
|
+
|
|
76
|
+
```diff
|
|
77
|
+
-:root { --touch-target: 44px; }
|
|
78
|
+
-
|
|
79
|
+
-@media (pointer: coarse) {
|
|
80
|
+
- .my-control { min-block-size: var(--touch-target); }
|
|
81
|
+
-}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Bronto's controls float to `var(--tap-target)` — `max(44px, 2.9rem)` — on their
|
|
85
|
+
own. For your *own* controls, consume the token rather than a literal:
|
|
86
|
+
|
|
87
|
+
```css
|
|
88
|
+
@media (pointer: coarse) {
|
|
89
|
+
.my-control {
|
|
90
|
+
min-block-size: var(--tap-target); /* 44px floor, WCAG 2.5.5 */
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`--tap-target-min` is the WCAG 2.5.8 AA 24px floor, for controls that only have
|
|
96
|
+
to clear the smaller bar. Both clamp in px on purpose: **keep the clamp if you
|
|
97
|
+
override them.** A bare rem is how a 44px floor quietly becomes 43.5px.
|
|
98
|
+
|
|
99
|
+
## 3. Delete your safe-area declarations
|
|
100
|
+
|
|
101
|
+
0.7 had no `env()` awareness at all. If you declared your own insets, drop them —
|
|
102
|
+
the same four names now ship:
|
|
103
|
+
|
|
104
|
+
```diff
|
|
105
|
+
-:root {
|
|
106
|
+
- --safe-area-top: env(safe-area-inset-top, 0px);
|
|
107
|
+
- --safe-area-bottom: env(safe-area-inset-bottom, 0px);
|
|
108
|
+
-}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Eight viewport-anchored surfaces now read them: the app rail and topbar, a
|
|
112
|
+
sticky site header, the skip link, both toast stacks, the drawer modal, and the
|
|
113
|
+
lightbox. Every rule uses `max(<authored>, var(--safe-area-*))`, so **desktop
|
|
114
|
+
rendering is unchanged**.
|
|
115
|
+
|
|
116
|
+
They are indirected through custom properties rather than calling `env()` at the
|
|
117
|
+
point of use, which matters twice: a desktop test runner cannot emulate `env()`
|
|
118
|
+
but can override a property, and a host running inside its own chrome (an
|
|
119
|
+
embedded webview, a kiosk frame) can declare the real insets. Follow the same
|
|
120
|
+
convention for your own floating chrome:
|
|
121
|
+
|
|
122
|
+
```css
|
|
123
|
+
.my-floating-bar {
|
|
124
|
+
inset-block-end: max(1rem, var(--safe-area-bottom));
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 4. Two new opt-in ergonomics
|
|
129
|
+
|
|
130
|
+
Neither is required; both replace a common workaround.
|
|
131
|
+
|
|
132
|
+
**`ui-button__label`** — an icon button can keep its words for the accessible
|
|
133
|
+
name and for text-based test selectors while giving back the pixels. One markup
|
|
134
|
+
shape serves both forms, and no `aria-label` can drift out of sync with the
|
|
135
|
+
visible wording:
|
|
136
|
+
|
|
137
|
+
```html
|
|
138
|
+
<button class="ui-button ui-button--icon">
|
|
139
|
+
<span class="ui-icon" style="--icon-mask: …"></span>
|
|
140
|
+
<span class="ui-button__label">Delete</span>
|
|
141
|
+
</button>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Drop `--icon` and the same markup renders glyph + word. The slot ellipsises
|
|
145
|
+
rather than wrapping, so a labelled button in a tight bar shrinks instead of
|
|
146
|
+
pushing its neighbours out.
|
|
147
|
+
|
|
148
|
+
**`ui-button--dense`** — for bars whose *height* is the constraint: a pane title
|
|
149
|
+
bar, a packed toolbar, a table row's actions. It lowers only the visual floor,
|
|
150
|
+
to `--tap-target-min`. The coarse-pointer block still floats it to the full
|
|
151
|
+
`--tap-target`, so a control you shrink for a mouse is never shrunk for a
|
|
152
|
+
finger. `ui.button({ size: 'dense' })` in the recipe API.
|
|
153
|
+
|
|
154
|
+
## 5. Retire your own severity vocabulary
|
|
155
|
+
|
|
156
|
+
Nothing forces this, but it is the reason most likely to have produced
|
|
157
|
+
divergent code. Bronto shipped the tones without the **scale**, so consumers
|
|
158
|
+
invented tier names — and inside one app they drift, because each surface was
|
|
159
|
+
written on a different day. If you have more than one, `css/state.css` now
|
|
160
|
+
publishes the canonical ladder:
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
critical › error › warning › notice › ok (+ unknown, outside the order)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```js
|
|
167
|
+
import { severity, SEVERITY_LEVELS } from '@ponchia/ui/classes';
|
|
168
|
+
|
|
169
|
+
severity('critical'); // { class: 'ui-severity', 'data-level': 'critical' }
|
|
170
|
+
severity('warning', { part: 'row' }); // { class: 'ui-severity-row', … }
|
|
171
|
+
SEVERITY_LEVELS; // sort and filter from this, not a local copy
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
The level travels on `data-level` — one attribute name — so a chip, a row, a
|
|
175
|
+
dot, and your own element all read the same selector, and your own element can
|
|
176
|
+
take `var(--severity-tone)` without copying a colour table.
|
|
177
|
+
|
|
178
|
+
Map your existing tiers onto it rather than keeping both. `unknown` is the
|
|
179
|
+
landing spot for anything unmeasured or stale; do **not** map it to `ok`, which
|
|
180
|
+
is an assertion of health and is how a dead collector reads as a healthy system.
|
|
181
|
+
|
|
182
|
+
## 6. Other surfaces you may be hand-rolling
|
|
183
|
+
|
|
184
|
+
Each of these replaced something a real consumer had built locally. None is
|
|
185
|
+
required.
|
|
186
|
+
|
|
187
|
+
- **`.ui-pane`** — a grab header, an in-place rename input, and an actions slot
|
|
188
|
+
that scrolls rather than pushing its last control past the clipped edge. If
|
|
189
|
+
you have a node/window/panel with a draggable title bar, this is it.
|
|
190
|
+
`.ui-panel` is still just a padded card.
|
|
191
|
+
- **`.ui-toolstrip--pane`** — a control bar belonging to one pane rather than to
|
|
192
|
+
the app: no frame of its own, and it refuses to wrap so a second row cannot
|
|
193
|
+
resize live content underneath. Mark the shrinking element with
|
|
194
|
+
`.ui-toolstrip__fill`.
|
|
195
|
+
- **`.ui-selectionbar--anchored`** (and the same on `.ui-toolstrip`) — viewport
|
|
196
|
+
anchoring for a floating bar, safe-area aware. Use
|
|
197
|
+
`--anchor-block-start` for the bar that must *not* sit under the thumb.
|
|
198
|
+
- **`.ui-empty-state__glyph/__lead/__hint`** and **`--invite`** — the three
|
|
199
|
+
parts every empty surface re-invents, plus the distinction between reporting
|
|
200
|
+
absence and offering the next action.
|
|
201
|
+
|
|
202
|
+
## 7. If you read `tokens.dtcg.json`
|
|
203
|
+
|
|
204
|
+
Six new scale tokens are **deliberately absent** from it, listed in the root
|
|
205
|
+
extension's `omittedCssVariables`: the two tap-target floors are `max()`
|
|
206
|
+
comparisons and the four safe-area insets are `env()` reads, and neither has a
|
|
207
|
+
conforming DTCG shape. Emitting one arm of a clamp, or the 0px fallback of an
|
|
208
|
+
`env()`, would publish a value that is wrong everywhere it matters. Read
|
|
209
|
+
`tokens.json` for the authored CSS. This is the same treatment `--shadow` and
|
|
210
|
+
the em trackings already get.
|
|
211
|
+
|
|
212
|
+
## Nothing else changed
|
|
213
|
+
|
|
214
|
+
No class was renamed or removed. No export moved. `bronto-ui-check` will not
|
|
215
|
+
report anything new for a 0.7-clean consumer — which is worth stating plainly,
|
|
216
|
+
because the one breaking change in this release is invisible to it.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Migrating 0.8 to 0.9
|
|
2
|
+
|
|
3
|
+
Machine-readable migration graph: [`MIGRATIONS.json`](../../MIGRATIONS.json).
|
|
4
|
+
|
|
5
|
+
One required change, and it is a one-word addition.
|
|
6
|
+
|
|
7
|
+
## 1. Add `ui-menu--dropdown` to your menus
|
|
8
|
+
|
|
9
|
+
`.ui-menu` used to weld its placement into the surface: `position: absolute`
|
|
10
|
+
plus an offset relative to its trigger. That made the class unusable for a menu
|
|
11
|
+
opened at a POINT — a canvas context menu, a long-press sheet — so a consumer
|
|
12
|
+
with one re-declared the panel, border, radius and shadow just to get a surface.
|
|
13
|
+
|
|
14
|
+
Placement is now opted into:
|
|
15
|
+
|
|
16
|
+
```diff
|
|
17
|
+
<details class="ui-menu-host" data-bronto-menu>
|
|
18
|
+
<summary class="ui-button ui-button--subtle">Menu</summary>
|
|
19
|
+
- <div class="ui-menu">
|
|
20
|
+
+ <div class="ui-menu ui-menu--dropdown">
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Without the modifier the surface renders in normal flow. Nothing else changed:
|
|
24
|
+
`--dropdown` carries exactly the declarations that used to be unconditional.
|
|
25
|
+
|
|
26
|
+
For a menu you position yourself, use `ui-menu--at-pointer` and set `left`/`top`
|
|
27
|
+
(or the logical equivalents) from the host — Bronto only takes it out of flow
|
|
28
|
+
and gives it the popover layer.
|
|
29
|
+
|
|
30
|
+
## 2. Optional: adopt `ui-row`
|
|
31
|
+
|
|
32
|
+
New in the default bundle, so it costs nothing to try. If you have a list of
|
|
33
|
+
selectable lines that is not a table and not a menu — search results, an
|
|
34
|
+
explorer, an outline, backlinks, commits — that is `ui-row`:
|
|
35
|
+
|
|
36
|
+
```html
|
|
37
|
+
<button class="ui-row ui-row--ruled" type="button" aria-selected="true">
|
|
38
|
+
<span class="ui-row__mark" aria-hidden="true">◆</span>
|
|
39
|
+
<span class="ui-row__title">apps/server/src/collab/room.ts</span>
|
|
40
|
+
<span class="ui-row__meta">4m</span>
|
|
41
|
+
</button>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`__title` truncates; `__meta` does not. Selection reads `aria-selected` or
|
|
45
|
+
`aria-current`, so the visual state cannot disagree with what a screen reader
|
|
46
|
+
announces. Rows carrying a severity want `ui-severity-row` instead.
|
|
47
|
+
|
|
48
|
+
`ui-menu__item` composes it, so menu items and rows cannot drift apart.
|
|
49
|
+
|
|
50
|
+
## 3. Know what `data-density` actually does
|
|
51
|
+
|
|
52
|
+
No change in behaviour — a correction to what the docs claimed. The preset
|
|
53
|
+
re-points the `--space-*` scale, so it moves the ~40 components whose padding is
|
|
54
|
+
expressed in that scale and **none** of the rest. `ui-alert` and
|
|
55
|
+
`ui-menu__item` are the two most likely to surprise you.
|
|
56
|
+
|
|
57
|
+
The others carry tuned pairs like `0.5rem 0.55rem` that a seven-step scale
|
|
58
|
+
cannot express; flattening them would change the default rendering everyone
|
|
59
|
+
uses. If you need a denser variant of a component that does not respond,
|
|
60
|
+
override its padding — and if you do that repeatedly for the same component,
|
|
61
|
+
report it, because that is evidence for a real `--dense` modifier.
|
|
62
|
+
|
|
63
|
+
## Nothing else changed
|
|
64
|
+
|
|
65
|
+
No class was removed or renamed. `bronto-ui-check` will not report anything new
|
|
66
|
+
for a 0.8-clean consumer.
|
package/docs/package-contract.md
CHANGED
|
@@ -49,6 +49,7 @@ semantic versioning contract for the surfaces listed here.
|
|
|
49
49
|
| `./css/skins.css` | `./dist/css/skins.css` | Opt-in layered CSS leaf | Stable additive | Generated layered direct-import leaf. Opt-in and not included in dist/bronto.css. |
|
|
50
50
|
| `./css/dataviz.css` | `./dist/css/dataviz.css` | Opt-in layered CSS leaf | Stable additive | Generated layered direct-import leaf. Opt-in and not included in dist/bronto.css. |
|
|
51
51
|
| `./css/report.css` | `./dist/css/report.css` | Opt-in layered CSS leaf | Stable additive | Generated layered direct-import leaf. Opt-in and not included in dist/bronto.css. |
|
|
52
|
+
| `./css/row.css` | `./dist/css/row.css` | Bundled layered CSS leaf | Stable additive | Generated layered direct-import leaf. Also included in dist/bronto.css. |
|
|
52
53
|
| `./css/figure.css` | `./dist/css/figure.css` | Opt-in layered CSS leaf | Stable additive | Generated layered direct-import leaf. Opt-in and not included in dist/bronto.css. |
|
|
53
54
|
| `./css/annotations.css` | `./dist/css/annotations.css` | Opt-in layered CSS leaf | Stable additive | Generated layered direct-import leaf. Opt-in and not included in dist/bronto.css. |
|
|
54
55
|
| `./css/legend.css` | `./dist/css/legend.css` | Opt-in layered CSS leaf | Stable additive | Generated layered direct-import leaf. Opt-in and not included in dist/bronto.css. |
|
|
@@ -94,6 +95,7 @@ semantic versioning contract for the surfaces listed here.
|
|
|
94
95
|
| `./css/unlayered/skins.css` | `./css/skins.css` | Unlayered CSS leaf | Stable path | Raw authored CSS leaf for consumers that deliberately opt out of @layer bronto on that leaf. |
|
|
95
96
|
| `./css/unlayered/dataviz.css` | `./css/dataviz.css` | Unlayered CSS leaf | Stable path | Raw authored CSS leaf for consumers that deliberately opt out of @layer bronto on that leaf. |
|
|
96
97
|
| `./css/unlayered/report.css` | `./css/report.css` | Unlayered CSS leaf | Stable path | Raw authored CSS leaf for consumers that deliberately opt out of @layer bronto on that leaf. |
|
|
98
|
+
| `./css/unlayered/row.css` | `./css/row.css` | Unlayered CSS leaf | Stable path | Raw authored CSS leaf for consumers that deliberately opt out of @layer bronto on that leaf. |
|
|
97
99
|
| `./css/unlayered/figure.css` | `./css/figure.css` | Unlayered CSS leaf | Stable path | Raw authored CSS leaf for consumers that deliberately opt out of @layer bronto on that leaf. |
|
|
98
100
|
| `./css/unlayered/annotations.css` | `./css/annotations.css` | Unlayered CSS leaf | Stable path | Raw authored CSS leaf for consumers that deliberately opt out of @layer bronto on that leaf. |
|
|
99
101
|
| `./css/unlayered/legend.css` | `./css/legend.css` | Unlayered CSS leaf | Stable path | Raw authored CSS leaf for consumers that deliberately opt out of @layer bronto on that leaf. |
|
|
@@ -299,6 +301,8 @@ always includes `package.json`, `README.md`, `LICENSE`, and
|
|
|
299
301
|
| `docs/migrations/0.4-to-0.5.md` | Shipped documentation | Curated Markdown reading asset shipped in the npm tarball. |
|
|
300
302
|
| `docs/migrations/0.5-to-0.6.md` | Shipped documentation | Curated Markdown reading asset shipped in the npm tarball. |
|
|
301
303
|
| `docs/migrations/0.6-to-0.7.md` | Shipped documentation | Curated Markdown reading asset shipped in the npm tarball. |
|
|
304
|
+
| `docs/migrations/0.7-to-0.8.md` | Shipped documentation | Curated Markdown reading asset shipped in the npm tarball. |
|
|
305
|
+
| `docs/migrations/0.8-to-0.9.md` | Shipped documentation | Curated Markdown reading asset shipped in the npm tarball. |
|
|
302
306
|
| `docs/adr/0001-color-system.md` | Shipped documentation | Curated Markdown reading asset shipped in the npm tarball. |
|
|
303
307
|
| `docs/adr/0002-scope-and-2026-baseline.md` | Shipped documentation | Curated Markdown reading asset shipped in the npm tarball. |
|
|
304
308
|
| `docs/adr/0003-theme-model.md` | Shipped documentation | Curated Markdown reading asset shipped in the npm tarball. |
|
|
@@ -315,7 +319,7 @@ result. The listed gates are part of `npm run check`.
|
|
|
315
319
|
| Package manifest | `package.json` | docs/package-contract.md | `npm run package-contract:build` | check:fresh; check:exports; check:pack; check:consumer-surface; check:consumer-types; check:publint; check:attw | The complete export/file matrix in this document is generated from the manifest; packed tarball imports, concrete file resolution, and package-level type resolution are smoke-tested in clean consumers. |
|
|
316
320
|
| Token model | `tokens/index.js` | css/tokens.css; tokens/index.json; tokens/tokens.dtcg.json; tokens/resolved.json; tokens/figma.variables.json; tokens/index.d.ts | `npm run tokens:css:build; tokens:build; dtcg:build; resolved:build; figma:variables:build; dts:build` | check:fresh; check:contrast | Token names/roles are public. Resolved and Figma handoff values are visual tuning before 1.0. |
|
|
317
321
|
| Class registry | `classes/index.js plus css/*.css selectors` | classes/classes.json; classes/index.d.ts; classes/vscode.css-custom-data.json; docs/reference.md | `npm run classes:json:build; dts:build; vscode:build; reference:build` | check:fresh; check:classes; check:contract | The typed registry, JSON vocabulary, and generated reference stay aligned with real selectors. |
|
|
318
|
-
| Authored CSS graph | `css/core.css plus css/*.css leaves` | dist/bronto.css; dist/css/*.css (
|
|
322
|
+
| Authored CSS graph | `css/core.css plus css/*.css leaves` | dist/bronto.css; dist/css/*.css (47 layered outputs) | `npm run dist:build` | check:dist; check:exports; check:component-matrix | Default bundle and direct layered leaf imports are generated from authored CSS, size-gated, and coverage-owned as foundation or component leaves. |
|
|
319
323
|
| JSDoc-authored public JS | `behaviors/; annotations/; connectors/; react/; solid/; qwik/; svelte/; vue/` | adjacent *.d.ts and *.d.ts.map files | `npm run dts:emit` | check:dts-emit; check:types; check:consumer-surface; check:consumer-types; check:behavior-matrix; check:attw; check:publint | Declarations are emitted from the shipped JS, package subpath imports are compiled from a packed clean consumer, and public behavior exports are docs/unit/browser owned. |
|
|
320
324
|
| Glyph registry | `glyphs/glyphs.js` | glyphs/glyphs.d.ts | `npm run glyphs:build` | check:glyphs; check:unit | Glyph names and render options are public. The registry stays sorted and type-covered. |
|
|
321
325
|
| Display colorways | `tokens/skins.js` | css/skins.css; tokens/skins.d.ts | `npm run skins:build` | check:skins; check:contrast | Skins are opt-in root-level choices and never part of dist/bronto.css. |
|
package/docs/reference.md
CHANGED
|
@@ -9,7 +9,7 @@ rendering of every class is the kitchen-sink demo:
|
|
|
9
9
|
**<https://ponchia.github.io/bronto-ui/>**. Theming knobs and the token
|
|
10
10
|
contract: [docs/theming.md](theming.md).
|
|
11
11
|
|
|
12
|
-
-
|
|
12
|
+
- 677 classes across 184 component groups
|
|
13
13
|
- Import the typed registry: `import { cls, ui, cx } from '@ponchia/ui/classes'`
|
|
14
14
|
- Validate markup as data (no JS/TS): `@ponchia/ui/classes.json` — the same
|
|
15
15
|
vocabulary as language-neutral JSON (`groups`, `classes`, `states`,
|
|
@@ -874,6 +874,8 @@ each one matches a real selector in the stylesheet.
|
|
|
874
874
|
| `cls.menuItem` | `ui-menu__item` | part |
|
|
875
875
|
| `cls.menuLabel` | `ui-menu__label` | part |
|
|
876
876
|
| `cls.menuSep` | `ui-menu__sep` | part |
|
|
877
|
+
| `cls.menuAtPointer` | `ui-menu--at-pointer` | modifier |
|
|
878
|
+
| `cls.menuDropdown` | `ui-menu--dropdown` | modifier |
|
|
877
879
|
|
|
878
880
|
### `.ui-menu-host`
|
|
879
881
|
|
|
@@ -1117,6 +1119,17 @@ each one matches a real selector in the stylesheet.
|
|
|
1117
1119
|
| --- | --- | --- |
|
|
1118
1120
|
| `cls.reveal` | `ui-reveal` | base |
|
|
1119
1121
|
|
|
1122
|
+
### `.ui-row`
|
|
1123
|
+
|
|
1124
|
+
| Registry key | Class | Kind |
|
|
1125
|
+
| --- | --- | --- |
|
|
1126
|
+
| `cls.row` | `ui-row` | base |
|
|
1127
|
+
| `cls.rowMark` | `ui-row__mark` | part |
|
|
1128
|
+
| `cls.rowMeta` | `ui-row__meta` | part |
|
|
1129
|
+
| `cls.rowTitle` | `ui-row__title` | part |
|
|
1130
|
+
| `cls.rowRuled` | `ui-row--ruled` | modifier |
|
|
1131
|
+
| `cls.rowStacked` | `ui-row--stacked` | modifier |
|
|
1132
|
+
|
|
1120
1133
|
### `.ui-screen-only`
|
|
1121
1134
|
|
|
1122
1135
|
| Registry key | Class | Kind |
|
package/docs/reporting.md
CHANGED
|
@@ -54,18 +54,18 @@ No install? Link the same files from a CDN. Pin the version — pre-1.0, breakin
|
|
|
54
54
|
changes ship in the minor (see [stability.md](./stability.md)):
|
|
55
55
|
|
|
56
56
|
```html
|
|
57
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
58
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
57
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.9.0/dist/bronto.css" />
|
|
58
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.9.0/dist/css/report-kit.css" />
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
Leaf-by-leaf CDN imports use the same `dist/css/` paths:
|
|
62
62
|
|
|
63
63
|
```html
|
|
64
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
65
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
66
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
67
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
68
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
64
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.9.0/dist/bronto.css" />
|
|
65
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.9.0/dist/css/report.css" />
|
|
66
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.9.0/dist/css/dataviz.css" />
|
|
67
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.9.0/dist/css/annotations.css" />
|
|
68
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.9.0/dist/css/legend.css" />
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
The CDN serves the package's own `fonts/` next to the CSS, so font URLs resolve
|
|
@@ -879,7 +879,7 @@ or validation runtime.
|
|
|
879
879
|
|
|
880
880
|
```json
|
|
881
881
|
{
|
|
882
|
-
"$schema": "https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
882
|
+
"$schema": "https://cdn.jsdelivr.net/npm/@ponchia/ui@0.9.0/schemas/report-claims.v1.schema.json",
|
|
883
883
|
"schemaVersion": "bronto-report-claims.v1",
|
|
884
884
|
"report": { "title": "Decision readiness", "type": "decision" },
|
|
885
885
|
"claims": [
|
package/docs/stability.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Public API stability
|
|
2
2
|
|
|
3
3
|
`@ponchia/ui` is pre-1.0. Breaking changes ship in the minor (`0.x.0`), and
|
|
4
|
-
patches are non-breaking. In practical terms: **PATCH releases (`0.
|
|
4
|
+
patches are non-breaking. In practical terms: **PATCH releases (`0.9.x`) are
|
|
5
5
|
non-breaking bug-fixes and additive changes — safe to upgrade without review;
|
|
6
6
|
MINOR releases (`0.x.0`) may include breaking changes and consumers should
|
|
7
7
|
review the CHANGELOG before upgrading.** Pin `~0.x` (tilde) to accept only
|
|
@@ -140,6 +140,7 @@ current public-surface matrix and the release policy above still applies.
|
|
|
140
140
|
| Connectors (`@ponchia/ui/connectors`, `css/connectors.css`, `.ui-connector*`, `initConnectors`) | Stable additive | Connector class names, the `data-bronto-connector` attribute contract, geometry helper function names, and recipe options are public. Helper internals/heuristics may tune before 1.0. Opt-in, not in the default bundle. |
|
|
141
141
|
| Spotlight (`css/spotlight.css`, `.ui-spotlight*`, `.ui-tour-note*`, `initSpotlight`) | Stable additive | Spotlight/tour-note class names, the `--spot-*` custom-property contract, and the `data-bronto-spotlight`/`data-target` attributes are public. Opt-in, not in the default bundle. Not a tour engine. |
|
|
142
142
|
| Crosshair (`css/crosshair.css`, `.ui-crosshair*`, `.ui-readout`, `initCrosshair`) | Stable additive | Crosshair/readout class names, the `--crosshair-x/y` properties, the `data-bronto-crosshair` attribute, and the `bronto:crosshair:move`/`:leave` event contract are public. Opt-in. Reports pointer position only — no data mapping. |
|
|
143
|
+
| Rows (`css/row.css`, `.ui-row*`) | Stable additive | Class names, the `__title` / `__meta` / `__mark` parts, the `--stacked` / `--ruled` modifiers, and the selection contract are public: `aria-selected`, `aria-current` and `.is-selected` all paint the selected state, so the visual state cannot disagree with the announced one. `__title` is the part that truncates and `__meta` is the part that does not — that asymmetry is the contract, not a detail. **In the default bundle**, unusually for a new surface: `.ui-menu__item` composes it, so a core component depends on it. Also exported standalone, which is why it appears here, but it is NOT opt-in. |
|
|
143
144
|
| Selection states (`css/selection.css`, `.ui-sel*`) | Stable additive | The `.ui-sel`/`--on`/`--off`/`--maybe` emphasis classes and recipe options are public. Opt-in, cross-cutting. The host owns selection logic; Bronto only styles the states. |
|
|
144
145
|
| Analytical roll-up (`css/analytical.css`) | Stable additive | A convenience `@import` of the nine analytical leaves (figure, annotations, legend, marks, connectors, spotlight, crosshair, selection, highlights). The set of leaves it bundles may grow additively; each leaf also stays individually exported. Opt-in, not in the default bundle. |
|
|
145
146
|
| Sources / provenance (`css/sources.css`, `.ui-citation*`, `.ui-source-card*`, `.ui-source-list*`, `.ui-provenance*`, `.ui-src--*`, `initSources`) | Stable additive | Citation/source/provenance class names, the cross-cutting `.ui-src--*` trust-state modifiers (always paired with an author label), the optional `data-bronto-sources` / `data-bronto-source-ref` behavior contract, `bronto:source:focus`, and the `ui.citation`/`ui.source`/`ui.provenance` recipes + `cls.sourceList` are public. Opt-in, not in the default bundle. |
|
package/docs/theming.md
CHANGED
|
@@ -130,6 +130,22 @@ you change CSS `--accent` later.
|
|
|
130
130
|
- **Spacing** — override the `--space-2xs … --space-2xl` scale, or use a
|
|
131
131
|
preset: `data-density="compact"` / `data-density="comfortable"` on any
|
|
132
132
|
element (defaults to the middle scale).
|
|
133
|
+
|
|
134
|
+
**Read this before relying on the preset.** It re-points the `--space-*`
|
|
135
|
+
scale, and only components whose padding is *expressed in that scale* move
|
|
136
|
+
with it — around 40 of them, including `ui-panel`, `ui-modal__body`,
|
|
137
|
+
`ui-evidence-item`, `ui-claim`, `ui-job`, `ui-code__body` and the report
|
|
138
|
+
surfaces. The rest carry tuned padding pairs like `0.5rem 0.55rem`, which the
|
|
139
|
+
seven-step scale cannot express, so **they do not respond at all** —
|
|
140
|
+
`ui-alert` and `ui-menu__item` are the two most likely to surprise you.
|
|
141
|
+
|
|
142
|
+
That is a real limit, not an oversight to work around: flattening a tuned pair
|
|
143
|
+
onto the nearest scale step would change how those components look at the
|
|
144
|
+
default density, which is the one nearly everyone uses. If you need a denser
|
|
145
|
+
variant of a component that does not respond, override its padding directly —
|
|
146
|
+
and if you find yourself doing that repeatedly for the same component, that is
|
|
147
|
+
worth reporting, because it is evidence for a real `--dense` modifier rather
|
|
148
|
+
than a preset that half-works.
|
|
133
149
|
- **Dark surface** — the dark theme's base is a deliberately *elevated*
|
|
134
150
|
near-black (`--bg: #121212`) for readability: pure black + bright text
|
|
135
151
|
causes halation, and near-black-on-black surface steps are imperceptible.
|
package/docs/usage.md
CHANGED
|
@@ -186,6 +186,48 @@ a `.ui-legend` key, and fallback data. Full LLM/static report cookbook:
|
|
|
186
186
|
spinner is CSS. This is the ARIA-driven contract — see reference.md
|
|
187
187
|
→ "Composition & state".
|
|
188
188
|
|
|
189
|
+
## Rows: `ui-row` vs table vs menu item
|
|
190
|
+
|
|
191
|
+
Three shapes look alike and are not interchangeable:
|
|
192
|
+
|
|
193
|
+
- **`ui-table`** when the data has columns and a header. A table promises that
|
|
194
|
+
the third cell means the same thing on every line.
|
|
195
|
+
- **`ui-menu__item`** when the list is a menu: it dismisses on choice, and it is
|
|
196
|
+
reached through `ui-menu-host`.
|
|
197
|
+
- **`ui-row`** for everything else — a search result, a file in an explorer, an
|
|
198
|
+
outline entry, a backlink, a commit. A full-width clickable line that
|
|
199
|
+
*persists*.
|
|
200
|
+
|
|
201
|
+
```html
|
|
202
|
+
<button class="ui-row ui-row--ruled" type="button" aria-current="true">
|
|
203
|
+
<span class="ui-row__mark" aria-hidden="true">◆</span>
|
|
204
|
+
<span class="ui-row__title">apps/server/src/collab/room.ts</span>
|
|
205
|
+
<span class="ui-row__meta">4m</span>
|
|
206
|
+
</button>
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
The one rule worth knowing: **`__title` is what truncates.** It takes the slack
|
|
210
|
+
and gives it back first; `__meta` never shrinks, because a half-rendered number
|
|
211
|
+
is worse than no number.
|
|
212
|
+
|
|
213
|
+
**Pick the right attribute, and it is probably not `aria-selected`.** That one
|
|
214
|
+
is only valid on a row whose role accepts it — `option` inside a `listbox`, or
|
|
215
|
+
`row` / `tab` / `gridcell` / `treeitem`. On a bare `<button>` it is invalid ARIA
|
|
216
|
+
and axe rates it *critical*; this project shipped that mistake in its own demo
|
|
217
|
+
and the a11y gate caught it before release.
|
|
218
|
+
|
|
219
|
+
- `aria-current="true"` — the row is the current one. The common case, and valid
|
|
220
|
+
on any element.
|
|
221
|
+
- `aria-selected="true"` — only when the row really is an `option` in a
|
|
222
|
+
`listbox`, or another role that accepts it.
|
|
223
|
+
- `.is-selected` — when neither fits.
|
|
224
|
+
|
|
225
|
+
All three paint the same, so the visual state cannot disagree with the announced
|
|
226
|
+
one. Rows carrying a severity should use `ui-severity-row` (`css/state.css`)
|
|
227
|
+
instead, which adds the tone gutter.
|
|
228
|
+
|
|
229
|
+
`ui-menu__item` composes `ui-row`, which is why they cannot drift.
|
|
230
|
+
|
|
189
231
|
## Empty state vs invite
|
|
190
232
|
|
|
191
233
|
Both use `ui-empty-state`, and the slots are the same three parts — a quiet
|
package/llms.txt
CHANGED
|
@@ -45,7 +45,7 @@ the path changes from source `css/` to built `dist/css/`:
|
|
|
45
45
|
<!-- installed locally -->
|
|
46
46
|
<link rel="stylesheet" href="./node_modules/@ponchia/ui/dist/css/<leaf>.css" />
|
|
47
47
|
<!-- or from a CDN; pin the version (pre-1.0, breaking changes ship in the minor) -->
|
|
48
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
48
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.9.0/dist/css/<leaf>.css" />
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
The flattened default bundle is `dist/bronto.css` (bundler shorthand
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ponchia/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "CSS-first identity and UI layer for services, tools, sites, and reports
|
|
5
|
+
"description": "CSS-first identity and UI layer for services, tools, sites, and reports \u2014 works in HTML, every framework, and PDF, no component runtime. Shared app shell, forms, tables, workflow chrome, plus opt-in analytical/report primitives. Monochrome with one rationed accent. Zero runtime dependencies.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"css",
|
|
8
8
|
"ui",
|
|
@@ -113,6 +113,8 @@
|
|
|
113
113
|
"docs/migrations/0.4-to-0.5.md",
|
|
114
114
|
"docs/migrations/0.5-to-0.6.md",
|
|
115
115
|
"docs/migrations/0.6-to-0.7.md",
|
|
116
|
+
"docs/migrations/0.7-to-0.8.md",
|
|
117
|
+
"docs/migrations/0.8-to-0.9.md",
|
|
116
118
|
"docs/adr/0001-color-system.md",
|
|
117
119
|
"docs/adr/0002-scope-and-2026-baseline.md",
|
|
118
120
|
"docs/adr/0003-theme-model.md",
|
|
@@ -213,24 +215,24 @@
|
|
|
213
215
|
"prepublishOnly": "npm run build:artifacts && npm run check"
|
|
214
216
|
},
|
|
215
217
|
"devDependencies": {
|
|
216
|
-
"@arethetypeswrong/cli": "^0.18.
|
|
218
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
217
219
|
"@axe-core/playwright": "^4.11.3",
|
|
218
220
|
"@builder.io/qwik": "^1.20.0",
|
|
219
221
|
"@playwright/test": "1.60.0",
|
|
220
222
|
"github-actionlint": "^1.7.12",
|
|
221
|
-
"jsdom": "^
|
|
222
|
-
"knip": "^6.
|
|
223
|
-
"pdfjs-dist": "^6.
|
|
224
|
-
"prettier": "^3.9.
|
|
225
|
-
"publint": "^0.3.
|
|
226
|
-
"react": "^19.2.
|
|
227
|
-
"react-dom": "^19.2.
|
|
228
|
-
"solid-js": "^1.9.
|
|
229
|
-
"stylelint": "^17.14.
|
|
223
|
+
"jsdom": "^30.0.1",
|
|
224
|
+
"knip": "^6.32.1",
|
|
225
|
+
"pdfjs-dist": "^6.2.108",
|
|
226
|
+
"prettier": "^3.9.6",
|
|
227
|
+
"publint": "^0.3.23",
|
|
228
|
+
"react": "^19.2.8",
|
|
229
|
+
"react-dom": "^19.2.8",
|
|
230
|
+
"solid-js": "^1.9.14",
|
|
231
|
+
"stylelint": "^17.14.1",
|
|
230
232
|
"stylelint-config-standard": "^40.0.0",
|
|
231
233
|
"stylelint-use-logical": "^2.1.3",
|
|
232
234
|
"typescript": "^6.0.3",
|
|
233
|
-
"vega": "^6.
|
|
235
|
+
"vega": "^6.3.1",
|
|
234
236
|
"vega-lite": "^6.4.3"
|
|
235
237
|
},
|
|
236
238
|
"peerDependencies": {
|
|
@@ -278,6 +280,7 @@
|
|
|
278
280
|
"./css/skins.css": "./dist/css/skins.css",
|
|
279
281
|
"./css/dataviz.css": "./dist/css/dataviz.css",
|
|
280
282
|
"./css/report.css": "./dist/css/report.css",
|
|
283
|
+
"./css/row.css": "./dist/css/row.css",
|
|
281
284
|
"./css/figure.css": "./dist/css/figure.css",
|
|
282
285
|
"./css/annotations.css": "./dist/css/annotations.css",
|
|
283
286
|
"./css/legend.css": "./dist/css/legend.css",
|
|
@@ -323,6 +326,7 @@
|
|
|
323
326
|
"./css/unlayered/skins.css": "./css/skins.css",
|
|
324
327
|
"./css/unlayered/dataviz.css": "./css/dataviz.css",
|
|
325
328
|
"./css/unlayered/report.css": "./css/report.css",
|
|
329
|
+
"./css/unlayered/row.css": "./css/row.css",
|
|
326
330
|
"./css/unlayered/figure.css": "./css/figure.css",
|
|
327
331
|
"./css/unlayered/annotations.css": "./css/annotations.css",
|
|
328
332
|
"./css/unlayered/legend.css": "./css/legend.css",
|