@ponchia/ui 0.4.0 → 0.5.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 +352 -12
- package/MIGRATIONS.json +92 -0
- package/README.md +27 -17
- package/annotations/index.d.ts +280 -0
- package/annotations/index.js +522 -0
- package/behaviors/carousel.js +197 -0
- package/behaviors/combobox.js +195 -0
- package/behaviors/command.js +187 -0
- package/behaviors/connectors.js +96 -0
- package/behaviors/crosshair.js +58 -0
- package/behaviors/dialog.js +73 -0
- package/behaviors/disclosure.js +25 -0
- package/behaviors/dismissible.js +24 -0
- package/behaviors/forms.js +158 -0
- package/behaviors/glyph.js +109 -0
- package/behaviors/index.d.ts +82 -1
- package/behaviors/index.js +18 -1336
- package/behaviors/internal.js +50 -0
- package/behaviors/legend.js +46 -0
- package/behaviors/menu.js +46 -0
- package/behaviors/popover.js +108 -0
- package/behaviors/spotlight.js +53 -0
- package/behaviors/table.js +109 -0
- package/behaviors/tabs.js +103 -0
- package/behaviors/theme.js +82 -0
- package/behaviors/toast.js +152 -0
- package/classes/index.d.ts +318 -0
- package/classes/index.js +352 -0
- package/classes/vscode.css-custom-data.json +18 -14
- package/connectors/index.d.ts +71 -0
- package/connectors/index.js +179 -0
- package/css/analytical.css +21 -0
- package/css/annotations.css +292 -0
- package/css/command.css +97 -0
- package/css/connectors.css +93 -0
- package/css/crosshair.css +100 -0
- package/css/disclosure.css +29 -0
- package/css/dots.css +2 -0
- package/css/feedback.css +104 -0
- package/css/fonts.css +11 -7
- package/css/generated.css +117 -0
- package/css/legend.css +268 -0
- package/css/marks.css +144 -0
- package/css/motion.css +88 -0
- package/css/overlay.css +52 -1
- package/css/primitives.css +18 -0
- package/css/report.css +363 -0
- package/css/selection.css +46 -0
- package/css/sources.css +179 -0
- package/css/spotlight.css +104 -0
- package/css/state.css +121 -0
- package/css/tokens.css +78 -60
- package/css/workbench.css +83 -0
- package/dist/bronto.css +1 -1
- package/dist/css/analytical.css +1 -0
- package/dist/css/annotations.css +1 -0
- package/dist/css/command.css +1 -0
- package/dist/css/connectors.css +1 -0
- package/dist/css/crosshair.css +1 -0
- package/dist/css/disclosure.css +1 -1
- package/dist/css/dots.css +1 -1
- package/dist/css/feedback.css +1 -1
- package/dist/css/fonts.css +1 -1
- package/dist/css/generated.css +1 -0
- package/dist/css/legend.css +1 -0
- package/dist/css/marks.css +1 -0
- package/dist/css/motion.css +1 -1
- package/dist/css/overlay.css +1 -1
- package/dist/css/primitives.css +1 -1
- package/dist/css/report.css +1 -0
- package/dist/css/selection.css +1 -0
- package/dist/css/sources.css +1 -0
- package/dist/css/spotlight.css +1 -0
- package/dist/css/state.css +1 -0
- package/dist/css/tokens.css +1 -1
- package/dist/css/workbench.css +1 -0
- package/docs/adr/0001-color-system.md +26 -27
- package/docs/adr/0002-scope-and-2026-baseline.md +104 -0
- package/docs/adr/0003-theme-model.md +97 -0
- package/docs/annotations.md +345 -0
- package/docs/architecture.md +202 -0
- package/docs/command.md +95 -0
- package/docs/connectors.md +91 -0
- package/docs/contrast.md +42 -42
- package/docs/crosshair.md +63 -0
- package/docs/generated.md +91 -0
- package/docs/legends.md +168 -0
- package/docs/marks.md +86 -0
- package/docs/reference.md +418 -15
- package/docs/reporting.md +305 -0
- package/docs/selection.md +40 -0
- package/docs/sources.md +110 -0
- package/docs/spotlight.md +78 -0
- package/docs/stability.md +52 -0
- package/docs/state.md +85 -0
- package/docs/theming.md +18 -6
- package/docs/usage.md +43 -3
- package/docs/workbench.md +72 -0
- package/fonts/doto-400.woff2 +0 -0
- package/fonts/doto-500.woff2 +0 -0
- package/fonts/doto-600.woff2 +0 -0
- package/fonts/doto-700.woff2 +0 -0
- package/fonts/doto-800.woff2 +0 -0
- package/fonts/doto-900.woff2 +0 -0
- package/llms.txt +288 -8
- package/package.json +95 -5
- package/qwik/index.d.ts +60 -0
- package/qwik/index.js +149 -0
- package/react/index.d.ts +40 -14
- package/react/index.js +32 -5
- package/solid/index.d.ts +40 -14
- package/solid/index.js +31 -3
- package/tokens/index.d.ts +3 -3
- package/tokens/index.js +25 -19
- package/tokens/index.json +32 -28
- package/tokens/resolved.json +34 -32
- package/tokens/tokens.dtcg.json +22 -14
- package/fonts/doto-400.ttf +0 -0
- package/fonts/doto-500.ttf +0 -0
- package/fonts/doto-600.ttf +0 -0
- package/fonts/doto-700.ttf +0 -0
- package/fonts/doto-800.ttf +0 -0
- package/fonts/doto-900.ttf +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,353 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
> **Versioning:** pre-1.0, breaking changes ship in the _minor_. Pin
|
|
4
|
-
> `~0.
|
|
3
|
+
> **Versioning:** pre-1.0, breaking changes ship in the _minor_. Pin to the
|
|
4
|
+
> minor — `~0.4.0` (equivalently `^0.4.0`) resolves to `>=0.4.0 <0.5.0`; a bare
|
|
5
|
+
> `^0` / `*` wildcard does **not** protect you. See README → Versioning, and
|
|
5
6
|
> the deprecation policy in CONTRIBUTING.md.
|
|
6
7
|
|
|
8
|
+
## 0.5.0 — 2026-06-02
|
|
9
|
+
|
|
10
|
+
A **minor** that builds out the "analytical & generated-report UI" identity: a
|
|
11
|
+
full suite of opt-in **communication primitives** — SVG annotations, legends,
|
|
12
|
+
text/evidence marks, leader-line connectors, a guided-focus spotlight, a
|
|
13
|
+
crosshair/readout, a selection-state vocabulary, label declutter + direct labels
|
|
14
|
+
(`declutterLabels`/`directLabels`), and a source/citation/provenance **trust
|
|
15
|
+
layer** — plus a consolidation pass over them. Each owns its visual grammar and
|
|
16
|
+
pure geometry and refuses to own scales/state/hit-testing (no chart engine).
|
|
17
|
+
|
|
18
|
+
Per the project's versioning policy, breaking changes ship in the minor. This
|
|
19
|
+
release carries three: the opt-in report kit's chart data key moved into the new
|
|
20
|
+
legend layer (`.ui-chart__legend`/`__swatch` removed — see Changed and
|
|
21
|
+
[`MIGRATIONS.json`](MIGRATIONS.json)), annotation arrowheads now render via
|
|
22
|
+
the shared connectors geometry kernel (a small path-shape change), and the
|
|
23
|
+
opt-in marks' rationed-accent tone was renamed `evidence`→`accent` to match the
|
|
24
|
+
rest of the analytical tone vocabulary. Everything else is additive and opt-in,
|
|
25
|
+
save for the tiny `.ui-shortcut` keyboard-hint primitive that joins the core
|
|
26
|
+
layer; the rest of the default `dist/bronto.css` is unchanged. Also folds in the
|
|
27
|
+
0.4.x maintenance hardening that had not yet been released.
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- **SVG annotations** (`@ponchia/ui/css/annotations.css`,
|
|
32
|
+
`@ponchia/ui/annotations`, `.ui-annotation*`, `ui.annotation()`): an opt-in
|
|
33
|
+
annotation layer for charts, reports, and analytical figures, following the
|
|
34
|
+
d3-annotation grammar (a **subject** marks the thing, a **connector** points
|
|
35
|
+
away, a **note** carries the text). Ships a class grammar (variants for
|
|
36
|
+
label/callout/elbow/curve/circle/rect/threshold/badge/bracket/band/slope/
|
|
37
|
+
compare/cluster/axis/timeline/evidence, six tones, and opt-in
|
|
38
|
+
`draw`/`reveal`/`pulse`/`focus` motion that respects `prefers-reduced-motion`)
|
|
39
|
+
plus tiny geometry helpers that return SVG strings only — they own no chart
|
|
40
|
+
scales, mutate no DOM, and provide no edit mode. Documented in
|
|
41
|
+
[`docs/annotations.md`](docs/annotations.md) and gated by `check:report`.
|
|
42
|
+
- **Legends / data keys** (`@ponchia/ui/css/legend.css`, `.ui-legend*`,
|
|
43
|
+
`ui.legend()`/`ui.legendItem()`/`ui.legendSwatch()`, `initLegend`): an opt-in,
|
|
44
|
+
standalone data-key layer that reads the `--chart-*` palette tokens.
|
|
45
|
+
Categorical, continuous gradient (sequential + `--diverging`), threshold, and
|
|
46
|
+
pattern keys; swatch colour set inline (`--chart-color`) or via
|
|
47
|
+
`.ui-legend__swatch--1..8` index helpers; vertical/compact/with-values
|
|
48
|
+
layouts. WCAG 1.4.1 by construction (the text label is the non-colour
|
|
49
|
+
channel), with `forced-colors` and print care. Optional interactive
|
|
50
|
+
(series-toggling) entries are `<button aria-pressed>` controls: `initLegend`
|
|
51
|
+
flips `aria-pressed`/`.is-inactive` and emits `bronto:legend:toggle`
|
|
52
|
+
(`{ series, active }`) — the host owns hiding the series and any `aria-live`
|
|
53
|
+
announcement (it is never a chart engine). Optional `useLegend` hook in the
|
|
54
|
+
React/Solid/Qwik bindings. New `check:legend` gate proves swatch colours are a
|
|
55
|
+
subset of `tokens/charts.js` and never a raw hex. Documented in
|
|
56
|
+
[`docs/legends.md`](docs/legends.md).
|
|
57
|
+
- **Text marks / evidence** (`@ponchia/ui/css/marks.css`, `.ui-mark*`,
|
|
58
|
+
`.ui-bracket-note*`, `ui.mark()`/`ui.bracketNote()`): an opt-in layer of
|
|
59
|
+
sober, report-grade emphasis for running prose — the counterpart to SVG
|
|
60
|
+
annotations (annotations call out a figure, marks call out a sentence). Inline
|
|
61
|
+
`.ui-mark` (highlight/underline/box/strike; `--accent` + status
|
|
62
|
+
tones; `--draw` reduced-motion-safe sweep) for use on `<mark>`, and
|
|
63
|
+
`.ui-bracket-note` for bracketing a whole passage. Pure CSS on semantic
|
|
64
|
+
tokens, monochrome by default, with `forced-colors` care. Documented in
|
|
65
|
+
[`docs/marks.md`](docs/marks.md).
|
|
66
|
+
- **Connectors / leader lines** (`@ponchia/ui/css/connectors.css`,
|
|
67
|
+
`@ponchia/ui/connectors`, `.ui-connector*`, `initConnectors`, `ui.connector()`):
|
|
68
|
+
an opt-in layer that draws a line between two DOM elements (the
|
|
69
|
+
page-coordinate cousin of annotations). Pure geometry helpers
|
|
70
|
+
(`connectRects`/`connectorPath`/`arrowHead`/…) that return SVG strings and own
|
|
71
|
+
no DOM, an `.ui-connector` overlay grammar (straight/elbow/curve, arrow/dot
|
|
72
|
+
ends, tones, dashed, `--draw`), and an optional `initConnectors` behavior that
|
|
73
|
+
draws + tracks on resize/scroll. `useConnectors` in the bindings. Documented in
|
|
74
|
+
[`docs/connectors.md`](docs/connectors.md).
|
|
75
|
+
- **Spotlight / guided focus** (`@ponchia/ui/css/spotlight.css`, `.ui-spotlight*`,
|
|
76
|
+
`.ui-tour-note*`, `initSpotlight`, `ui.spotlight()`): an opt-in guided-focus
|
|
77
|
+
overlay — a box-shadow cutout over a target element, optional ring, and a
|
|
78
|
+
callout note. `initSpotlight` positions the cutout (`--spot-x/y/w/h`) and
|
|
79
|
+
re-places on resize/scroll and when `data-target` changes. Deliberately **not**
|
|
80
|
+
a tour engine — the host owns step order/advancing/visibility. `useSpotlight`
|
|
81
|
+
in the bindings. Documented in [`docs/spotlight.md`](docs/spotlight.md).
|
|
82
|
+
- **Crosshair / readout** (`@ponchia/ui/css/crosshair.css`, `.ui-crosshair*`,
|
|
83
|
+
`.ui-readout`, `initCrosshair`, `ui.crosshair()`): an opt-in plot ruler +
|
|
84
|
+
pinned readout. `initCrosshair` tracks the pointer over a
|
|
85
|
+
`[data-bronto-crosshair]` plot, sets `--crosshair-x/y`, and dispatches
|
|
86
|
+
`bronto:crosshair:move` with px + 0–1 fractions — it reports position only and
|
|
87
|
+
never maps pixels to data (that needs the host's scales). `useCrosshair` in the
|
|
88
|
+
bindings. Documented in [`docs/crosshair.md`](docs/crosshair.md).
|
|
89
|
+
- **Selection states** (`@ponchia/ui/css/selection.css`, `.ui-sel*`,
|
|
90
|
+
`ui.sel()`): a tiny cross-cutting selection-emphasis vocabulary
|
|
91
|
+
(`--on`/`--off`/`--maybe`) reusable on chart marks, table rows, list items, or
|
|
92
|
+
map regions. The carve-out from brush/lasso — Bronto styles the states; the
|
|
93
|
+
host owns the selection/hit-test logic. Documented in
|
|
94
|
+
[`docs/selection.md`](docs/selection.md).
|
|
95
|
+
- **Sources, citations & provenance** (`@ponchia/ui/css/sources.css`,
|
|
96
|
+
`.ui-citation`/`.ui-source-card`/`.ui-source-list`/`.ui-provenance`,
|
|
97
|
+
`ui.citation()`/`ui.source()`/`ui.provenance()`): an opt-in, CSS-only **trust
|
|
98
|
+
layer** for generated reports and AI output — the grammar for "where did this
|
|
99
|
+
come from?". A cross-cutting `.ui-src--*` state (verified/reviewed/generated/
|
|
100
|
+
unverified/stale/conflict) sets a rationed tone, always paired with an
|
|
101
|
+
author-written label (never colour alone). Bronto owns the grammar + states;
|
|
102
|
+
the host owns fetching, citation numbering, and trust. The first
|
|
103
|
+
frontier-primitive beyond the analytical suite. Documented in
|
|
104
|
+
[`docs/sources.md`](docs/sources.md).
|
|
105
|
+
- **Keyboard-shortcut hint** (`.ui-shortcut` + `.ui-shortcut__sep`, core): a tiny
|
|
106
|
+
universal-chrome primitive that lays out one or more `.ui-kbd` keys as a chord
|
|
107
|
+
(`⌘`+`K`) or sequence (`G` then `I`) with a dim connective. The command tier's
|
|
108
|
+
smallest piece, broadly useful outside a palette (menu items, buttons,
|
|
109
|
+
tooltips). Class-only, like `.ui-kbd`.
|
|
110
|
+
- **Lifecycle / system state** (`@ponchia/ui/css/state.css`, `.ui-state`
|
|
111
|
+
(+`__label`/`__detail`/`--busy`) with canonical state modifiers
|
|
112
|
+
(saving/saved/queued/offline/stale/conflict/error/locked/reviewed/
|
|
113
|
+
needs-review), `.ui-syncbar`, `ui.state()`): an opt-in, CSS-only vocabulary for
|
|
114
|
+
the states apps actually live in — a labelled state object with a rationed tone
|
|
115
|
+
and a page/document sync bar. The label is the state (never colour alone);
|
|
116
|
+
`--busy` pulses the indicator (reduced-motion-safe). Bronto ships the visual
|
|
117
|
+
states + canonical wording; the host owns the state machine, retry, and
|
|
118
|
+
persistence. Frontier candidate #2. Documented in [`docs/state.md`](docs/state.md).
|
|
119
|
+
- **Generated content & AI trust** (`@ponchia/ui/css/generated.css`,
|
|
120
|
+
`.ui-generated`/`.ui-origin-label`/`.ui-reasoning`/`.ui-tool-log`/`.ui-tool-call`,
|
|
121
|
+
`ui.originLabel()`): an opt-in, CSS-only set of **trust surfaces** for AI /
|
|
122
|
+
system-generated content — a marked region, an origin label, and quiet
|
|
123
|
+
native-`<details>` reasoning + tool-call logs. Not a chat kit; no
|
|
124
|
+
fabricated-confidence widget. Bronto styles disclosure/origin/trace, the host
|
|
125
|
+
owns model metadata, redaction, and safety. Pairs with the source layer.
|
|
126
|
+
Documented in [`docs/generated.md`](docs/generated.md).
|
|
127
|
+
- **Workbench** (`@ponchia/ui/css/workbench.css`, `.ui-inspector`/`.ui-property`/
|
|
128
|
+
`.ui-selectionbar`): an opt-in, CSS-only core for tool UIs — a selected-object
|
|
129
|
+
inspector panel, denser property rows, and a raised selection action bar.
|
|
130
|
+
Layout + affordances only; resizable split panes and drag handles are
|
|
131
|
+
deferred. Documented in [`docs/workbench.md`](docs/workbench.md).
|
|
132
|
+
- **Command palette** (`@ponchia/ui/css/command.css`, `.ui-command` (+
|
|
133
|
+
`__input`/`__list`/`__group`/`__item`/`__shortcut`/`__meta`/`__empty`),
|
|
134
|
+
`initCommand`, `useCommand`): an opt-in CSS shell + behavior — filter +
|
|
135
|
+
keyboard-navigate a DOM-authored command list (roving focus, group hiding,
|
|
136
|
+
full keyboard), emitting `bronto:command:select` ({ value, label }) and
|
|
137
|
+
`bronto:command:close`. Bronto navigates; the host owns the action registry,
|
|
138
|
+
routing, and execution. No global Cmd/Ctrl+K. Completes the command tier
|
|
139
|
+
(frontier #3) atop the shipped `ui-shortcut`. Documented in
|
|
140
|
+
[`docs/command.md`](docs/command.md).
|
|
141
|
+
- **Label declutter** (`@ponchia/ui/annotations` `declutterLabels`): a
|
|
142
|
+
deterministic, order-preserving **1-D** label de-overlap helper (sort, push
|
|
143
|
+
apart by `size + gap`, slide to fit `max`) — pure, no DOM/scales. Not a 2-D
|
|
144
|
+
collision solver. Documented in [`docs/annotations.md`](docs/annotations.md).
|
|
145
|
+
- **Direct labels** (`@ponchia/ui/annotations` `directLabels`): the
|
|
146
|
+
direct-labeling companion to `declutterLabels` — it declutters labels along an
|
|
147
|
+
axis **and** draws the leader from each anchor to its placed label, reusing the
|
|
148
|
+
connectors geometry kernel. Returns `[{ x, y, anchor, key, d }]` (the `d` feeds
|
|
149
|
+
a `ui-annotation__connector`). Deterministic and pure: no scales, no DOM, no
|
|
150
|
+
2-D placement (the 1-D core of Labella, completed with leaders). Documented in
|
|
151
|
+
[`docs/annotations.md`](docs/annotations.md).
|
|
152
|
+
- **Connectors** (`@ponchia/ui/connectors`, `@ponchia/ui/css/connectors.css`,
|
|
153
|
+
`initConnectors`, `useConnectors`, `ui.connector()`) and **Spotlight**
|
|
154
|
+
(`css/spotlight.css`, `initSpotlight`, `ui.spotlight()`) — leader lines between
|
|
155
|
+
DOM elements and a guided-focus overlay; both opt-in, geometry/visual only
|
|
156
|
+
(the host owns layout/tour state).
|
|
157
|
+
- **Crosshair / readout** (`css/crosshair.css`, `initCrosshair`,
|
|
158
|
+
`ui.crosshair()`) and **selection states** (`css/selection.css`, `ui.sel()`) —
|
|
159
|
+
a plot ruler that reports pointer position (not data), and a cross-cutting
|
|
160
|
+
`.ui-sel--on/off/maybe` emphasis vocabulary (the host owns brush/hit-test).
|
|
161
|
+
- **`@ponchia/ui/css/analytical.css`** — a convenience roll-up that bundles the
|
|
162
|
+
seven analytical leaves (annotations, legend, marks, connectors, spotlight,
|
|
163
|
+
crosshair, selection) into one import. Add `dataviz.css`/`report.css`
|
|
164
|
+
separately as needed.
|
|
165
|
+
|
|
166
|
+
### Fixed
|
|
167
|
+
|
|
168
|
+
- The optional Qwik binding (`@ponchia/ui/qwik`) is now built from the packed
|
|
169
|
+
tarball in CI **and** release, alongside React/Solid — closing a coverage gap
|
|
170
|
+
(it was documented as optimizer-proven but no job actually built it). Also
|
|
171
|
+
covered by `check:pack`, the size report, and the dead-code config.
|
|
172
|
+
|
|
173
|
+
### Changed
|
|
174
|
+
|
|
175
|
+
- **Breaking (opt-in report kit):** the chart data key moved out of
|
|
176
|
+
`css/report.css` into the standalone `css/legend.css`. `.ui-chart__legend` →
|
|
177
|
+
`.ui-legend` (now with `.ui-legend__item`/`.ui-legend__label` rows) and
|
|
178
|
+
`.ui-chart__swatch` → `.ui-legend__swatch`. Import `@ponchia/ui/css/legend.css`
|
|
179
|
+
beside the report kit; see [`MIGRATIONS.json`](MIGRATIONS.json) and
|
|
180
|
+
[`docs/legends.md`](docs/legends.md). The `--chart-color`/`--chart-pattern`
|
|
181
|
+
swatch contract is unchanged, so the rename is mechanical.
|
|
182
|
+
- **Breaking (opt-in marks):** the rationed-accent **tone** on `.ui-mark` and
|
|
183
|
+
`.ui-bracket-note` was renamed `evidence` → `accent` (`ui-mark--evidence` →
|
|
184
|
+
`ui-mark--accent`, `ui-bracket-note--evidence` → `ui-bracket-note--accent`;
|
|
185
|
+
`ui.mark({ tone: 'accent' })` / `ui.bracketNote({ tone: 'accent' })`) so the
|
|
186
|
+
accent tone reads the same across every analytical primitive (it already was
|
|
187
|
+
`accent` on `ui.connector`/`ui.annotation`). `.ui-annotation--evidence` is
|
|
188
|
+
**unchanged** — it is a marker _variant_ (a proof/source shape), not a tone.
|
|
189
|
+
Mechanical whole-token rename; see [`MIGRATIONS.json`](MIGRATIONS.json).
|
|
190
|
+
- **Consolidation:** the SVG geometry is single-sourced in the `connectors`
|
|
191
|
+
kernel — `@ponchia/ui/annotations` now builds its connectors on it, so a
|
|
192
|
+
line/curve/arrow/dot is drawn one way across both. `connectorLine`/`Curve`/
|
|
193
|
+
`EndDot` output is byte-identical; **`connectorEndArrow` is the one
|
|
194
|
+
(minor-breaking) shape change** — the arrowhead now matches the connectors
|
|
195
|
+
arrowhead. New `check:helpers-dts` gate keeps the hand-maintained
|
|
196
|
+
`annotations`/`connectors` `.d.ts` in parity with their runtime exports.
|
|
197
|
+
- The Doto webfont now ships as **woff2 only** (Brotli) instead of uncompressed
|
|
198
|
+
TTF: ~5.7 kB per weight vs ~137 kB, cutting the six-weight payload from ~823 kB
|
|
199
|
+
to ~35 kB (the dot-matrix glyphs compress ~96%) and shrinking the unpacked
|
|
200
|
+
tarball by roughly the same. No TTF fallback is carried — woff2 is supported by
|
|
201
|
+
the entire browser floor (ADR-0002: Chrome 125 / Safari 18 / Firefox 129).
|
|
202
|
+
`@font-face` is internal, so this is transparent to consumers; only self-hosts
|
|
203
|
+
that referenced `fonts/doto-*.ttf` directly need to point at `*.woff2`.
|
|
204
|
+
- `docs/architecture.md` now ships in the package, so the offline rationale the
|
|
205
|
+
shipped ADRs link to resolves inside the tarball.
|
|
206
|
+
- `docs/stability.md` clarifies that `data-surface`/`data-density`/
|
|
207
|
+
`data-contrast` are **convenience presets**, not part of the stability
|
|
208
|
+
contract; `data-theme` (light/dark) remains the contractual base.
|
|
209
|
+
|
|
210
|
+
### Internal
|
|
211
|
+
|
|
212
|
+
- Token values are single-sourced in `tokens/index.js` (`cssVars`); the
|
|
213
|
+
`css/tokens.css` palette is generated from it, so the dark palette is authored
|
|
214
|
+
once instead of in three places (the shipped CSS is byte-identical).
|
|
215
|
+
- `behaviors/index.js` is split into per-behavior modules behind the same public
|
|
216
|
+
barrel (no surface change).
|
|
217
|
+
- Drift-gate consolidation (`assertFresh`), a Qwik type smoke + stronger
|
|
218
|
+
class-recipe wiring test, the APCA advisory widened to the accent text across
|
|
219
|
+
the core palette and every colorway (still advisory; WCAG 2.1 AA stays the
|
|
220
|
+
hard gate), an OLED computed-style smoke test, and several doc reconciliations.
|
|
221
|
+
- New `demos.spec` e2e sweep runs the console-error / uncaught-exception /
|
|
222
|
+
failed-response guards **and** an axe scan over every per-feature demo page
|
|
223
|
+
(annotations, legends, marks, connectors, spotlight, crosshair, selection,
|
|
224
|
+
report) in both themes and cross-browser — previously only `/demo/` was
|
|
225
|
+
guarded, so a throw or 404 on those SVG-heavy pages could not fail CI.
|
|
226
|
+
- The `check:dist` payload ceiling was raised to 80 kB raw / 14.5 kB gzip (from
|
|
227
|
+
78 kB / 13.5 kB). The default bundle was sitting ~21 bytes under the old gzip
|
|
228
|
+
gate — the analytical primitives are opt-in leaves and stay out of it, so this
|
|
229
|
+
is residual prior growth; the bump restores a real ~3% raw / ~7% gzip margin
|
|
230
|
+
so an ordinary token addition no longer trips an unrelated PR.
|
|
231
|
+
|
|
232
|
+
## 0.4.1 — 2026-06-01
|
|
233
|
+
|
|
234
|
+
Patch hardening for the public framework surface, plus the first step of the
|
|
235
|
+
modern-platform motion direction (see [ADR-0002](docs/adr/0002-scope-and-2026-baseline.md)).
|
|
236
|
+
|
|
237
|
+
### Added
|
|
238
|
+
|
|
239
|
+
- **Static report kit — `@ponchia/ui/css/report.css` + `docs/reporting.md`.**
|
|
240
|
+
An opt-in, PDF-first report layer for LLM-authored and hand-authored HTML:
|
|
241
|
+
report covers, headers, section numbering, summaries, findings, evidence
|
|
242
|
+
blocks, source/appendix/footnote blocks, chart wrappers/legends/fallback
|
|
243
|
+
tables, and print utilities (`ui-print-only`, `ui-screen-only`,
|
|
244
|
+
`ui-break-before`, `ui-break-after`, `ui-keep`, `ui-print-exact`). It stays
|
|
245
|
+
out of the default bundle, ships with the offline LLM docs, and is covered by
|
|
246
|
+
a report fixture, package/export checks, and class-contract validation.
|
|
247
|
+
The layer also includes compact covers, unnumbered report sections, simple
|
|
248
|
+
static chart-bar primitives, and evidence-table framing rules so generated
|
|
249
|
+
reports need less private CSS.
|
|
250
|
+
- **Zero-JS enter _and_ exit motion for native-`<dialog>` overlays.** Modal and
|
|
251
|
+
drawer (and their backdrop) now fade/scale **both ways** via `@starting-style`
|
|
252
|
+
+ `transition-behavior: allow-discrete` — previously they only animated in and
|
|
253
|
+
vanished on close. Pure CSS, reduced-motion-aware (snaps with no flash), scoped
|
|
254
|
+
to `dialog.ui-modal` so the controlled `.is-open` path is unchanged.
|
|
255
|
+
- **Enter/exit motion extended to popover, toast, and accordion** (ADR-0002
|
|
256
|
+
"next, same approach"):
|
|
257
|
+
- **Popover** (`.ui-popover`) fades + slides both ways via the same
|
|
258
|
+
`@starting-style` + `allow-discrete` recipe, covering both the native
|
|
259
|
+
`[popover]` top-layer path and the `.is-open` fallback. Zero JS,
|
|
260
|
+
reduced-motion-aware.
|
|
261
|
+
- **Toast** (`.ui-toast`) now plays a CSS fade-out on dismiss instead of being
|
|
262
|
+
yanked from the DOM. The `toast()` behavior adds `.is-leaving` and removes
|
|
263
|
+
the node on `transitionend` (with a timeout fallback); it falls back to
|
|
264
|
+
instant removal under reduced-motion or where no transition is computed, so
|
|
265
|
+
the persistent `aria-live` region is undisturbed.
|
|
266
|
+
- **Accordion** (`.ui-accordion`, native `<details>`) animates auto-height
|
|
267
|
+
open/close via `::details-content` + `interpolate-size: allow-keywords` +
|
|
268
|
+
`content-visibility … allow-discrete`. Strict progressive enhancement —
|
|
269
|
+
gated on `@supports selector(::details-content)`; engines without it (today,
|
|
270
|
+
Firefox/Safari) simply snap, exactly as before.
|
|
271
|
+
- **Scroll-driven motion (progressive enhancement).** `.ui-scroll-progress` (a
|
|
272
|
+
reading-progress bar on a `scroll(root block)` timeline, RTL-aware) and
|
|
273
|
+
`.ui-scroll-reveal` (a JS-free, IntersectionObserver-free reveal on a `view()`
|
|
274
|
+
timeline). Both are gated on `@supports (animation-timeline: …)` and
|
|
275
|
+
`prefers-reduced-motion: no-preference`, so engines without scroll timelines
|
|
276
|
+
(today, Firefox/Safari) keep a static end-state and reduced-motion users get
|
|
277
|
+
no movement.
|
|
278
|
+
- **View Transitions (progressive enhancement).** A `.ui-vt` helper
|
|
279
|
+
(`view-transition-name: var(--ui-vt-name)`) to morph an element across a
|
|
280
|
+
same-document `startViewTransition()` or a cross-document navigation, an
|
|
281
|
+
on-brand default for the `::view-transition-*(root)` cross-fade, and a
|
|
282
|
+
**reduced-motion kill-switch** for the `::view-transition-*` pseudo-tree
|
|
283
|
+
(which the platform does *not* quiet automatically). Cross-document nav stays
|
|
284
|
+
a documented one-liner you add yourself (`@view-transition { navigation: auto }`
|
|
285
|
+
is document-global, so it can't be layered or scoped by the framework).
|
|
286
|
+
- **Optional Qwik bindings — `@ponchia/ui/qwik`.** Same thin-adapter shape as
|
|
287
|
+
the React/Solid bindings (`useDialog`, `useToast`, … `useBrontoBehavior`, plus
|
|
288
|
+
the `cls`/`ui`/`cx` + `applyStoredTheme` re-exports), wrapping the SSR-safe
|
|
289
|
+
behaviors in Qwik's `useVisibleTask$` (run on visible, cleanup on dispose) so a
|
|
290
|
+
resumable page stays zero-JS until interaction. Scope a behavior with a Qwik
|
|
291
|
+
signal: `useDialog({ root: useSignal() })`. `@builder.io/qwik` is an **optional**
|
|
292
|
+
peer dependency, so the core stays zero-dependency. New `examples/qwik-vite`
|
|
293
|
+
builds it through the real Qwik optimizer.
|
|
294
|
+
- **OLED true-black surface variant — `data-surface="oled"`.** The dark base is
|
|
295
|
+
now a readable elevated near-black (see Changed); this opt-in root attribute
|
|
296
|
+
restores pure black for OLED power-saving and the original "Nothing" look.
|
|
297
|
+
CSS-only preset (like `data-density`/`data-contrast`), scoped to the dark
|
|
298
|
+
theme. Documented in `docs/theming.md`.
|
|
299
|
+
- **APCA advisory for dark text.** `check:contrast` now emits a non-failing
|
|
300
|
+
warning when a dark text pairing falls below its perceptual APCA target (WCAG
|
|
301
|
+
stays the hard gate) — the early-warning that would have caught the illegible
|
|
302
|
+
dim text. The kitchen-sink demo gains a unified theme picker (theme × colorway
|
|
303
|
+
× surface, all persisted).
|
|
304
|
+
- **[ADR-0003](docs/adr/0003-theme-model.md)** records the theme model: a binary
|
|
305
|
+
light/dark base × one-knob derivation × orthogonal axes (colorway, surface,
|
|
306
|
+
contrast, density), and why a flat named-theme catalog is rejected.
|
|
307
|
+
- React and Solid Vite examples, CI/release matrix coverage for those examples,
|
|
308
|
+
runtime binding tests, public API stability docs, a release runbook, and
|
|
309
|
+
`npm run size:report`.
|
|
310
|
+
|
|
311
|
+
### Changed
|
|
312
|
+
|
|
313
|
+
- **Dark theme re-tuned for readability.** The dark base moved off pure `#000`
|
|
314
|
+
to an elevated near-black (`--bg #121212`, panels `#1c1c1c`/`#222`/`#242424`,
|
|
315
|
+
lines `#383838`/`#555`); body text eased `#f2f2f2 → #e6e6e6` (APCA Lc 99 → ~91,
|
|
316
|
+
removing halation) and **dim/meta text raised `#858585 → #a0a0a0`** (APCA
|
|
317
|
+
Lc ~36 → ~49 — the actual "hard to read" fix). WCAG 2.x over-rates contrast on
|
|
318
|
+
pure black, so pairings "passed" while reading poorly; the re-tune clears WCAG
|
|
319
|
+
AA on every pairing and lifts perceptual (APCA) contrast. Accent and status
|
|
320
|
+
colours are unchanged; true black stays available via `data-surface="oled"`.
|
|
321
|
+
- **Browser floor raised to Chrome/Edge 125+, Safari 18+, Firefox 129+**
|
|
322
|
+
(early–mid 2025). A deliberate greenfield stance (ADR-0002) so the framework
|
|
323
|
+
can build natively on `@starting-style`, `transition-behavior: allow-discrete`,
|
|
324
|
+
`oklch()`/relative color, and `light-dark()`. No fallbacks ship below the
|
|
325
|
+
floor; not-yet-cross-engine features (View Transitions, scroll-driven
|
|
326
|
+
animations) are enhancement-only and degrade to a static end-state.
|
|
327
|
+
- Bundle budget nudged for the new motion: gzip 13.0 → 13.5 kB (for the dialog
|
|
328
|
+
enter/exit work) and raw 76 → 77 kB (for the popover/toast/accordion motion
|
|
329
|
+
plus the scroll-driven + view-transition CSS). Gzip held at ~13.1 kB — it
|
|
330
|
+
compresses well — so the compressed payload still has headroom.
|
|
331
|
+
|
|
332
|
+
### Fixed
|
|
333
|
+
|
|
334
|
+
- React and Solid bindings now resolve scoped roots on mount, so `{ root: ref }`
|
|
335
|
+
and resolver callbacks work after framework refs are assigned. Nullish resolver
|
|
336
|
+
results normalize to default behavior instead of crashing destructuring
|
|
337
|
+
behavior initializers.
|
|
338
|
+
- Scoped behavior roots now resolve controlled ids root-first, then
|
|
339
|
+
document-wide. This keeps existing body/portal-mounted dialogs, popovers, and
|
|
340
|
+
disclosure panels working while preventing earlier duplicate ids outside an
|
|
341
|
+
island from shadowing the in-root target.
|
|
342
|
+
- `data-bronto-dismiss="<selector>"` ignores malformed selectors instead of
|
|
343
|
+
throwing during event handling.
|
|
344
|
+
- The one-node glyph mask path now includes a WebKit-prefixed mask declaration,
|
|
345
|
+
and the OKLCH accent ramp uses an explicit white/black neutral endpoint for
|
|
346
|
+
cross-engine browser parity.
|
|
347
|
+
|
|
7
348
|
## 0.4.0 — 2026-05-31
|
|
8
349
|
|
|
9
|
-
The color-system release — [ADR-0001](docs/adr/0001-color-system.md) steps 1–
|
|
350
|
+
The color-system release — [ADR-0001](docs/adr/0001-color-system.md) steps 1–8.
|
|
10
351
|
A governed evolution beyond pure monochrome: the tier model is written down and
|
|
11
352
|
**enforced** (`check:color-policy`), and the "Nothing" look is proven to be a
|
|
12
353
|
_skin, not the architecture_ — opt-in **colorways** (amber CRT · phosphor green ·
|
|
@@ -34,11 +375,11 @@ categorical color lands later it ships as a governed, opt-in data-viz module
|
|
|
34
375
|
### Added
|
|
35
376
|
|
|
36
377
|
- **The `--accent-1..6` ramp is now perceptually even (OKLCH).** Steps 1–4 mix
|
|
37
|
-
the accent
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
378
|
+
the accent `in oklch` instead of using the old sRGB ramp (ADR-0001 step 8), so
|
|
379
|
+
the ramp reads as evenly-spaced. `scripts/gen-resolved.mjs` learned to resolve
|
|
380
|
+
`color-mix(in oklch,…)` → hex with the same one-channel tolerance browsers
|
|
381
|
+
show, so `tokens/resolved.json`, the DTCG export, and `docs/reference.md` all
|
|
382
|
+
carry the new values. These are
|
|
42
383
|
token **values** (non-contractual under the 0.x policy) and the ramp is not
|
|
43
384
|
consumed by any shipped component, so there is **no change to any component's
|
|
44
385
|
rendering** — only consumers using `var(--accent-1..4)` directly see the
|
|
@@ -102,10 +443,9 @@ categorical color lands later it ships as a governed, opt-in data-viz module
|
|
|
102
443
|
- **`check:skins` gate** — `css/skins.css` can't drift from `tokens/skins.js`,
|
|
103
444
|
every skin defines `--accent`, and colorways stay out of the default bundle.
|
|
104
445
|
- **[ADR-0001 — Color system](docs/adr/0001-color-system.md)** — the five-tier
|
|
105
|
-
color constitution and the backward-compatible roadmap. Steps 1–
|
|
106
|
-
implemented in this release
|
|
107
|
-
work + APCA advisory
|
|
108
|
-
OKLCH migration are deliberately deferred.
|
|
446
|
+
color constitution and the backward-compatible roadmap. Steps 1–8 are
|
|
447
|
+
implemented in this release: gate + colorways + Tier-3 tokens + OKLCH for new
|
|
448
|
+
work + APCA advisory + data-viz + OKLCH core accent ramp.
|
|
109
449
|
|
|
110
450
|
## 0.3.6 — 2026-05-31
|
|
111
451
|
|
package/MIGRATIONS.json
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "Machine-readable rename/removal map for @ponchia/ui upgrades (classes, attributes, and tokens). Generated-by-hand from CHANGELOG BREAKING sections; consumed by docs/migrations/*.md and any codemod/sed recipe. 'safe' rules are mechanically rewritable (whole-token, no semantic change); 'manual' rules need human judgement (concept moved or removed, not a 1:1 rename).",
|
|
3
|
+
"migrations": [
|
|
4
|
+
{
|
|
5
|
+
"from": "0.2",
|
|
6
|
+
"to": "0.3",
|
|
7
|
+
"summary": "Entire non-ui-* legacy vocabulary removed; everything is now under the .ui-* contract and the check-classes drift gate.",
|
|
8
|
+
"safe": [
|
|
9
|
+
{ "old": "skip-link", "new": "ui-skiplink" },
|
|
10
|
+
{ "old": "site-nav", "new": "ui-sitenav" },
|
|
11
|
+
{ "old": "site-menu", "new": "ui-sitemenu" },
|
|
12
|
+
{ "old": "theme-toggle", "new": "ui-themetoggle", "prefix": true },
|
|
13
|
+
{ "old": "app-shell", "new": "ui-app-shell", "prefix": true },
|
|
14
|
+
{ "old": "app-rail", "new": "ui-app-rail", "prefix": true },
|
|
15
|
+
{ "old": "app-topbar", "new": "ui-app-topbar", "prefix": true },
|
|
16
|
+
{ "old": "app-toolbar", "new": "ui-app-toolbar", "prefix": true },
|
|
17
|
+
{ "old": "app-nav", "new": "ui-app-nav", "prefix": true },
|
|
18
|
+
{ "old": "app-panel", "new": "ui-app-panel", "prefix": true },
|
|
19
|
+
{ "old": "app-content", "new": "ui-app-content", "prefix": true },
|
|
20
|
+
{ "old": "app-main", "new": "ui-app-main", "prefix": true },
|
|
21
|
+
{ "old": "app-metrics", "new": "ui-app-metrics", "prefix": true },
|
|
22
|
+
{ "old": "app-metric", "new": "ui-app-metric", "prefix": true },
|
|
23
|
+
{ "old": "app-empty-state", "new": "ui-app-empty-state", "prefix": true }
|
|
24
|
+
],
|
|
25
|
+
"manual": [
|
|
26
|
+
{
|
|
27
|
+
"old": "hero / project-* / post-card / essay-* / page-* / home-* / signal-panel / worklog-summary",
|
|
28
|
+
"new": "the ui-* content layer",
|
|
29
|
+
"note": "Long-form content: .ui-prose / .ui-quote. Cards: .ui-card. Layout: .ui-grid / .ui-stack. Site chrome: the ui-site* shell. No 1:1 mapping — re-compose with the content primitives."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"old": "callout",
|
|
33
|
+
"new": "ui-alert",
|
|
34
|
+
"note": "Tone modifiers differ (.ui-alert--info/-success/-warning/-danger); re-pick the tone."
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"old": "metric-tile",
|
|
38
|
+
"new": "ui-app-metric",
|
|
39
|
+
"note": "Now scoped to the admin shell vocabulary; standalone stat usage should wrap in .ui-app-metrics."
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"old": "tag-list / tag",
|
|
43
|
+
"new": "ui-tags / ui-tag",
|
|
44
|
+
"note": "Compact variant .tag-list--compact → .ui-tags--compact; verify accent-on-accent contrast (see CHANGELOG 0.3.0 a11y fix)."
|
|
45
|
+
}
|
|
46
|
+
],
|
|
47
|
+
"codemod": "See docs/migrations/0.2-to-0.3.md for a ready-to-run ripgrep+sed recipe covering the 'safe' rules."
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"from": "0.3",
|
|
51
|
+
"to": "0.4",
|
|
52
|
+
"summary": "Additive colour-system release (ADR-0001); the default dist/bronto.css renders identically. No class or attribute renames. One orphan token pair removed.",
|
|
53
|
+
"safe": [],
|
|
54
|
+
"manual": [
|
|
55
|
+
{
|
|
56
|
+
"old": "--orange / --orange-soft",
|
|
57
|
+
"new": "(removed — re-declare in a consumer :root override if referenced)",
|
|
58
|
+
"note": "Orphan token pair: defined in the token mirrors but referenced by no shipped component and documented nowhere, and untiered under the new colour model. Removed under the CONTRIBUTING 'provably-unreferenced surface' exception. If you used it: :root { --orange: #a85f32; --orange-soft: rgb(168 95 50 / 0.13); }"
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"codemod": "No class codemod needed (no renames). See docs/migrations/0.3-to-0.4.md; audit usage with: rg -- '--orange' ."
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"from": "0.4",
|
|
65
|
+
"to": "0.5",
|
|
66
|
+
"summary": "Adds the analytical-primitives suite (annotations, legend, marks, connectors, spotlight, crosshair, selection + the analytical.css roll-up); all additive/opt-in. Three breaking changes: the chart data key moved out of the report kit into the standalone Legends layer (`.ui-chart__legend`/`.ui-chart__swatch` removed); annotation arrowheads now render via the shared connectors geometry kernel (a small visual path change, no API change); and the marks/bracket-note rationed-accent tone was renamed `evidence`→`accent` to match the annotation/connector tone vocabulary (`.ui-annotation--evidence` stays — it's a marker variant, not a tone).",
|
|
67
|
+
"safe": [
|
|
68
|
+
{ "old": "ui-chart__swatch", "new": "ui-legend__swatch" },
|
|
69
|
+
{ "old": "ui-mark--evidence", "new": "ui-mark--accent" },
|
|
70
|
+
{ "old": "ui-bracket-note--evidence", "new": "ui-bracket-note--accent" }
|
|
71
|
+
],
|
|
72
|
+
"manual": [
|
|
73
|
+
{
|
|
74
|
+
"old": "ui.mark({ tone: 'evidence' }) / ui.bracketNote({ tone: 'evidence' })",
|
|
75
|
+
"new": "tone: 'accent'",
|
|
76
|
+
"note": "The rationed-accent tone option on the mark/bracket-note recipes is now 'accent' (was 'evidence'), matching ui.connector/ui.annotation. Do NOT rewrite ui.annotation({ variant: 'evidence' }) or the 'evidence' subject marker — those are a marker shape, not a tone, and are unchanged."
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"old": "ui-chart__legend",
|
|
80
|
+
"new": "ui-legend",
|
|
81
|
+
"note": "Also import '@ponchia/ui/css/legend.css' beside report.css, and wrap each entry's content as <li class=\"ui-legend__item\"> … <span class=\"ui-legend__label\">…</span>. The swatch's --chart-color/--chart-pattern inline contract is unchanged; the categorical --chart-N colour is also available via .ui-legend__swatch--N. See docs/legends.md."
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"old": "connectorEndArrow (annotations)",
|
|
85
|
+
"new": "connectorEndArrow (unchanged API)",
|
|
86
|
+
"note": "No code change needed. The function signature is identical; only the rendered arrowhead path differs slightly now that it shares the connectors geometry kernel. Re-baseline any exact-path SVG snapshot tests of annotation arrowheads."
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
"codemod": "rg -l 'ui-chart__legend|ui-chart__swatch' then s/ui-chart__swatch/ui-legend__swatch/g and rework the ul.ui-chart__legend wrapper into ul.ui-legend with li.ui-legend__item rows. See docs/legends.md."
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
}
|