@ponchia/ui 0.7.0 → 0.8.1
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 +178 -0
- package/README.md +3 -3
- package/classes/classes.json +79 -7
- package/classes/index.d.ts +53 -1
- package/classes/index.js +60 -0
- package/classes/vscode.css-custom-data.json +24 -0
- package/css/app.css +14 -3
- package/css/disclosure.css +7 -7
- package/css/feedback.css +11 -8
- package/css/forms.css +3 -3
- package/css/navigation.css +1 -1
- package/css/overlay.css +19 -5
- package/css/primitives.css +101 -6
- package/css/site.css +11 -5
- package/css/skins.css +97 -3
- package/css/state.css +161 -0
- package/css/table.css +1 -1
- package/css/tokens.css +6 -0
- package/css/workbench.css +151 -0
- package/dist/bronto.css +1 -1
- package/dist/css/app.css +1 -1
- package/dist/css/disclosure.css +1 -1
- package/dist/css/feedback.css +1 -1
- package/dist/css/forms.css +1 -1
- package/dist/css/navigation.css +1 -1
- package/dist/css/overlay.css +1 -1
- package/dist/css/primitives.css +1 -1
- package/dist/css/report-kit.css +1 -1
- package/dist/css/site.css +1 -1
- package/dist/css/skins.css +1 -1
- package/dist/css/state.css +1 -1
- package/dist/css/table.css +1 -1
- package/dist/css/tokens.css +1 -1
- package/dist/css/workbench.css +1 -1
- package/docs/adr/0001-color-system.md +32 -3
- package/docs/contrast.md +102 -18
- package/docs/migrations/0.7-to-0.8.md +216 -0
- package/docs/package-contract.md +1 -0
- package/docs/reference.md +52 -1
- package/docs/reporting.md +8 -8
- package/docs/stability.md +31 -2
- package/docs/state.md +51 -1
- package/docs/theming.md +18 -0
- package/docs/usage.md +62 -2
- package/docs/workbench.md +83 -4
- package/llms.txt +1 -1
- package/package.json +13 -12
- package/tokens/figma.variables.json +84 -0
- package/tokens/index.d.ts +2 -2
- package/tokens/index.js +23 -0
- package/tokens/index.json +12 -0
- package/tokens/resolved.json +6 -0
- package/tokens/skins.js +117 -7
- package/tokens/tokens.dtcg.json +7 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,184 @@
|
|
|
5
5
|
|> `^0` / `*` wildcard does **not** protect you. See README → Versioning, and
|
|
6
6
|
|> the deprecation policy in CONTRIBUTING.md.
|
|
7
7
|
|
|
8
|
+
## 0.8.1 — 2026-08-11
|
|
9
|
+
|
|
10
|
+
A packaging fix, plus dependency hygiene. **No published CSS, token, class, or
|
|
11
|
+
type artifact changed** — `dist/`, `css/`, `tokens/` and `classes/` are byte-for-byte
|
|
12
|
+
identical to 0.8.0. If you are on 0.8.0 and do not read the migration guide from
|
|
13
|
+
the package, there is nothing here for you.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **`docs/migrations/0.7-to-0.8.md` was missing from the published package.**
|
|
18
|
+
0.8.0's one breaking change is the colorway canvas re-point, `CHANGELOG.md`
|
|
19
|
+
and `MIGRATIONS.json` both point at that guide, and it was not in the tarball —
|
|
20
|
+
so a consumer following the pointer from an offline install got nothing. The
|
|
21
|
+
guide was written, linked, and gated by `check:doc-links`; it was simply never
|
|
22
|
+
added to `package.json`'s hand-maintained `files` array.
|
|
23
|
+
- **The gate that should have caught it was circular.** `check-pack.mjs` derived
|
|
24
|
+
its set of shipped docs *from* `files`, so it proved every listed doc ships and
|
|
25
|
+
could never prove a doc that exists is listed. It now asserts the other
|
|
26
|
+
direction for the two directories the published package itself references —
|
|
27
|
+
`docs/migrations/` (from `MIGRATIONS.json`) and `docs/adr/` (from
|
|
28
|
+
`docs/architecture.md`) — where a missing file costs a reader a dead pointer.
|
|
29
|
+
Other `docs/` pages stay opt-in: the package ships a curated subset by design.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- **Dependency sweep** — ten Dependabot PRs landed as one reviewed change. Every
|
|
34
|
+
advisory was **devDependency-scoped**; the package declares no runtime
|
|
35
|
+
dependencies and `npm audit --omit=dev` was already clean, so none of them
|
|
36
|
+
ever reached a consumer. `npm audit` now reports 0 across the whole tree
|
|
37
|
+
(`fast-uri`, `js-yaml`, `nanoid`, `pdfjs-dist`, `postcss`, `shell-quote`,
|
|
38
|
+
`tar`, `undici`), the toolchain moved (`jsdom` 30, `knip` 6.32, `prettier`
|
|
39
|
+
3.9.6, `publint` 0.3.23, `react`/`react-dom` 19.2.8, `solid-js` 1.9.14,
|
|
40
|
+
`stylelint` 17.14.1, `vega` 6.3.1, `@arethetypeswrong/cli` 0.18.5), the pinned
|
|
41
|
+
action SHAs moved, and the Astro example moved to Astro 7 (verified building
|
|
42
|
+
against the packed 0.8.0 tarball).
|
|
43
|
+
|
|
44
|
+
### Not taken
|
|
45
|
+
|
|
46
|
+
- **TypeScript 7.** Its default export is now `{ version, versionMajorMinor }` —
|
|
47
|
+
the compiler-API namespace moved in the native port — so `ts.ScriptTarget` is
|
|
48
|
+
`undefined` and `scripts/lib/import-policy.mjs` throws at `check:exports`.
|
|
49
|
+
Adapting this repository's AST tooling to that API is real work with its own
|
|
50
|
+
review, and there is no security driver: TypeScript is not in any advisory
|
|
51
|
+
here. Pinned to `^6.0.3`; Dependabot's dev-group PR stays open for it.
|
|
52
|
+
|
|
53
|
+
## 0.8.0 — 2026-08-11
|
|
54
|
+
|
|
55
|
+
A single-consumer release. A full-surface audit of the largest downstream
|
|
56
|
+
consumer — a Yjs-collaborative spatial canvas workspace with roughly ten
|
|
57
|
+
thousand lines of its own CSS — found it using 26 of the 646 published classes
|
|
58
|
+
and hand-rebuilding much of the rest. Everything here comes from what that
|
|
59
|
+
consumer had to write because the framework did not provide it, or got wrong.
|
|
60
|
+
|
|
61
|
+
### BREAKING
|
|
62
|
+
|
|
63
|
+
- **A colorway now re-points the neutral canvas, so every skinned surface
|
|
64
|
+
changes appearance.** No class, token, attribute, or export was removed or
|
|
65
|
+
renamed, and `bronto-ui-check` will report nothing — the break is *visual*,
|
|
66
|
+
which is why it is called out here rather than left in Changed. Until 0.7,
|
|
67
|
+
`data-bronto-skin` moved `--accent` and nothing else, and ADR-0001 step 4 said
|
|
68
|
+
so explicitly; a consumer could reasonably have relied on the canvas staying
|
|
69
|
+
neutral. From 0.8 the ten `SKIN_CANVAS_TOKENS` (`--bg`, `--bg-elevated`,
|
|
70
|
+
`--panel`, `--panel-strong`, `--panel-soft`, `--line`, `--line-strong`,
|
|
71
|
+
`--text`, `--text-soft`, `--text-dim`) are re-pointed per skin per theme.
|
|
72
|
+
- **If you want the old look**, re-declare those ten tokens after the skin
|
|
73
|
+
import; they are ordinary custom properties on `:root[data-bronto-skin=…]`
|
|
74
|
+
and un-layered app CSS wins.
|
|
75
|
+
- **If you already hand-wrote a canvas** for a skin — the case this change
|
|
76
|
+
exists to serve — delete it and check the result; yours was almost certainly
|
|
77
|
+
not contrast-gated, and this one is.
|
|
78
|
+
- **Contrast is not a regression risk.** Each neutral keeps the core token's
|
|
79
|
+
OKLCH lightness exactly, and `check-contrast` re-measures all 21 gated
|
|
80
|
+
pairings per skin per theme. Status colours are untouched by design.
|
|
81
|
+
|
|
82
|
+
### Fixed
|
|
83
|
+
|
|
84
|
+
- **The coarse-pointer tap target was 43.5px, not 44px.** The floor was written
|
|
85
|
+
as a bare `2.9rem` at 23 sites across 8 stylesheets, and `css/base.css` sets
|
|
86
|
+
`html { font-size: 0.9375rem }` — so every control the framework floats on
|
|
87
|
+
touch landed half a pixel under WCAG 2.5.5 and both platform HIGs, and drifted
|
|
88
|
+
further under any host that shrank the root. Several comments asserted
|
|
89
|
+
"≈ 44px". Both floors are now published tokens clamped in px
|
|
90
|
+
(`--tap-target: max(44px, 2.9rem)`, `--tap-target-min: max(24px, 1.6rem)`) —
|
|
91
|
+
the same `max()` shape the 24px floor already used correctly in five places.
|
|
92
|
+
The e2e that should have caught this was derived from the token (`2.9 * rem`),
|
|
93
|
+
so it agreed with the bug; it now asserts the external 44px standard, and a
|
|
94
|
+
unit gate walks every `@media (pointer: coarse)` block and fails on any floor
|
|
95
|
+
written as a bare length. That gate immediately found one more:
|
|
96
|
+
`.ui-table__sort`.
|
|
97
|
+
|
|
98
|
+
### Added
|
|
99
|
+
|
|
100
|
+
- **`.ui-button__label`** — the label slot for icon buttons. Wrap a button's
|
|
101
|
+
text in it and `--icon` decides whether the words are painted; they stay in
|
|
102
|
+
the accessible name and in text-based test selectors either way. One markup
|
|
103
|
+
shape serves both the labelled and icon-only forms, and no `aria-label` can
|
|
104
|
+
drift out of sync with the visible wording. The slot also ellipsises rather
|
|
105
|
+
than wrapping, so a labelled button in a tight bar shrinks instead of pushing
|
|
106
|
+
its neighbours out. `ui.button()` is unchanged; `cls.buttonLabel` is new.
|
|
107
|
+
- **`.ui-button--dense`** — a size tier for bars whose *height* is the
|
|
108
|
+
constraint (a pane title bar, a packed toolbar, a table row's actions). It
|
|
109
|
+
lowers only the visual floor, to `--tap-target-min`; the coarse-pointer block
|
|
110
|
+
still floats it to the full `--tap-target`, so a control shrunk for a mouse is
|
|
111
|
+
never shrunk for a finger. `ui.button({ size: 'dense' })`.
|
|
112
|
+
- **A canonical severity ladder** (`css/state.css`, opt-in). Bronto shipped the
|
|
113
|
+
*tones* long ago but never the *scale* — the tier names, their order, and the
|
|
114
|
+
attribute carrying them — so every consumer invented the ladder and it drifted
|
|
115
|
+
inside a single app: one surface saying `critical|error|warning|note`, the
|
|
116
|
+
next `bad|warn`, a third `critical|warning|info|ok`, under two different
|
|
117
|
+
attribute names, so findings did not sort against alerts. The ladder is
|
|
118
|
+
`critical` › `error` › `warning` › `notice` › `ok`, carried on **one**
|
|
119
|
+
attribute (`data-level`) across `.ui-severity`, `.ui-severity-dot` and
|
|
120
|
+
`.ui-severity-row`, with `SEVERITY_LEVELS` and `severity()` exported so a host
|
|
121
|
+
drives filters and sorts from the same list the CSS paints. `unknown` sits
|
|
122
|
+
deliberately *outside* the ordering: it means "not measured", and collapsing
|
|
123
|
+
it into `ok` is how a dead collector reads as a healthy system.
|
|
124
|
+
- **`.ui-pane`** (`css/workbench.css`, opt-in) — the window that `.ui-panel`
|
|
125
|
+
(a padded card) and `.ui-inspector` (head plus body) are not: a grab header,
|
|
126
|
+
a title that renames in place via `__title-input` without moving layout, and
|
|
127
|
+
an `__actions` slot that **scrolls rather than pushing** its last control past
|
|
128
|
+
the pane's clipped edge — the failure that leaves a Focus or Disconnect button
|
|
129
|
+
present, in the a11y tree, and unreachable.
|
|
130
|
+
- **`.ui-toolstrip--pane`** — the app has one toolstrip; a workbench full of
|
|
131
|
+
panes has one *per pane*, and those need different framing (no frame of their
|
|
132
|
+
own, a rule against the content below) and must not wrap, since a second row
|
|
133
|
+
would resize live content on every state change. `.ui-toolstrip__fill` marks
|
|
134
|
+
the element that absorbs slack and gives it back first.
|
|
135
|
+
- **`--anchored` / `--anchor-block-start` / `--anchor-block-end`** on
|
|
136
|
+
`.ui-selectionbar` and `.ui-toolstrip`. Both `--floating` bars were raised but
|
|
137
|
+
position-less, so every consumer re-derived the placement — including the
|
|
138
|
+
`max(offset, inset)` shape that keeps a bar out from under the home indicator.
|
|
139
|
+
- **Empty-state slots and an invite variant.** `.ui-empty-state` was a dashed
|
|
140
|
+
box that styled a `<p>`, so every empty surface in an app re-invented the same
|
|
141
|
+
three parts under a different name and they drifted. `__glyph` / `__lead` /
|
|
142
|
+
`__hint` name them, and `--invite` is the different job: an empty state
|
|
143
|
+
*reports absence*, an invite *offers the next action*, so it drops the dashed
|
|
144
|
+
frame and centres in the space it is given.
|
|
145
|
+
- **Safe-area tokens** — `--safe-area-top / -right / -bottom / -left`, defaulting
|
|
146
|
+
to `env(safe-area-inset-*, 0px)`. The framework had **no** `env()` awareness
|
|
147
|
+
while shipping eight viewport-anchored surfaces; all eight now read them: the
|
|
148
|
+
app rail and topbar, a sticky site header, the skip link, both toast stacks,
|
|
149
|
+
the drawer modal and the lightbox. Every rule uses
|
|
150
|
+
`max(<authored>, var(--safe-area-*))`, so desktop rendering is unchanged. The
|
|
151
|
+
values are indirected through custom properties rather than called at the
|
|
152
|
+
point of use because `env()` cannot be emulated by a desktop test runner —
|
|
153
|
+
and because a host inside its own chrome (embedded webview, kiosk frame) needs
|
|
154
|
+
to declare the real insets.
|
|
155
|
+
|
|
156
|
+
### Changed
|
|
157
|
+
|
|
158
|
+
- **ADR-0001 step 4 amended** to permit the canvas re-point above (see
|
|
159
|
+
BREAKING). "Amber CRT" used to leave the surface grey, which is what drove the
|
|
160
|
+
consumer to hand-write an amber canvas in raw hex — dark theme only, outside
|
|
161
|
+
OKLCH, outside the contrast gate, with `e-ink` silently un-tinted. The canvas
|
|
162
|
+
is **derived rather than picked**: every neutral keeps the core token's OKLCH
|
|
163
|
+
*lightness* exactly and moves only hue and a small role-scaled chroma.
|
|
164
|
+
`check-skins` now rejects a partial canvas and a one-theme-only canvas, the
|
|
165
|
+
two shapes the hand-written version had.
|
|
166
|
+
- **`check:recipe-types` no longer mis-attributes options.** It sliced the
|
|
167
|
+
factory body to end-of-file, so the *last* recipe's chunk swallowed everything
|
|
168
|
+
declared after the `ui` object — an unrelated helper exported below it had its
|
|
169
|
+
string branches blamed on whichever recipe happened to be last. It now stops
|
|
170
|
+
at the object's own closing brace.
|
|
171
|
+
- `docs/stability.md` records the audit and the correction it forces on this
|
|
172
|
+
project's adoption model: "no inspected consumer imports the surface" has been
|
|
173
|
+
measuring **discoverability, not demand**. Those thirteen zero-use primitives
|
|
174
|
+
were never rejected; they were never found. Non-adoption of a leaf the
|
|
175
|
+
consumer never imported is not evidence for retiring it at 1.0.
|
|
176
|
+
|
|
177
|
+
### Notes
|
|
178
|
+
|
|
179
|
+
- Anything that reads `tokens.dtcg.json` should know that six new scale tokens
|
|
180
|
+
are **deliberately absent** from it, listed in the root extension's
|
|
181
|
+
`omittedCssVariables`: the two tap-target floors are `max()` comparisons and
|
|
182
|
+
the four safe-area insets are `env()` reads, neither of which has a conforming
|
|
183
|
+
DTCG shape. `tokens.json` carries the authored CSS. This is the same treatment
|
|
184
|
+
`--shadow` and the em trackings already get.
|
|
185
|
+
|
|
8
186
|
## 0.7.0 — 2026-07-20
|
|
9
187
|
|
|
10
188
|
A consumer-first contract-hardening release. Ten real applications and tools,
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@ponchia/ui)
|
|
4
4
|
[](https://www.npmjs.com/package/@ponchia/ui#provenance)
|
|
5
5
|
[](https://github.com/Ponchia/bronto-ui/blob/main/package.json)
|
|
6
|
-
[](https://github.com/Ponchia/bronto-ui/blob/main/scripts/check-dist.mjs)
|
|
7
7
|
[](https://github.com/Ponchia/bronto-ui/actions/workflows/ci.yml)
|
|
8
8
|
[](https://scorecard.dev/viewer/?uri=github.com/Ponchia/bronto-ui)
|
|
9
9
|
[](https://github.com/Ponchia/bronto-ui/blob/main/LICENSE)
|
|
@@ -81,12 +81,12 @@ Or drop it in with no build step, straight from a CDN (replace the version only
|
|
|
81
81
|
when deliberately upgrading across a breaking pre-1.0 minor):
|
|
82
82
|
|
|
83
83
|
```html
|
|
84
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.
|
|
84
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.8.1/dist/bronto.css">
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
## Quick start
|
|
88
88
|
|
|
89
|
-
**1. Load the CSS.** One flattened, minified default CSS bundle — the standard component set, one request (~
|
|
89
|
+
**1. Load the CSS.** One flattened, minified default CSS bundle — the standard component set, one request (~92 kB raw / ~16 kB gzip) — that is `dist/bronto.css`, not the whole package tarball:
|
|
90
90
|
|
|
91
91
|
```css
|
|
92
92
|
@import '@ponchia/ui'; /* via a bundler */
|
package/classes/classes.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "@ponchia/ui class vocabulary as language-neutral data — validate emitted markup without executing the ESM cls map or parsing the .d.ts. Generated from classes/index.js — do not edit by hand; run `npm run classes:json:build`. Drift-checked in CI. `groups[].base` is null for a parts-only namespace (no standalone base class — do NOT emit it). A modifier whose name contains `__` (e.g. `ui-spark__bar--pos`) attaches to THAT part, not the base host. `states` is the author-applied `is-*` hooks (runtime/behavior-managed hooks are excluded); `behaviorAttributes` are the `data-bronto-*` wiring hooks the optional behaviors delegate on; `requiredAria` is the role/aria a generator must emit per component. `states` + `customProperties` are documented in docs/reference.md and ship outside `cls` by design.",
|
|
3
3
|
"counts": {
|
|
4
|
-
"classes":
|
|
5
|
-
"groups":
|
|
4
|
+
"classes": 669,
|
|
5
|
+
"groups": 183
|
|
6
6
|
},
|
|
7
7
|
"groups": {
|
|
8
8
|
"ui-accordion": {
|
|
@@ -242,13 +242,16 @@
|
|
|
242
242
|
"base": "ui-button",
|
|
243
243
|
"modifiers": [
|
|
244
244
|
"ui-button--danger",
|
|
245
|
+
"ui-button--dense",
|
|
245
246
|
"ui-button--ghost",
|
|
246
247
|
"ui-button--icon",
|
|
247
248
|
"ui-button--lg",
|
|
248
249
|
"ui-button--sm",
|
|
249
250
|
"ui-button--subtle"
|
|
250
251
|
],
|
|
251
|
-
"parts": [
|
|
252
|
+
"parts": [
|
|
253
|
+
"ui-button__label"
|
|
254
|
+
]
|
|
252
255
|
},
|
|
253
256
|
"ui-card": {
|
|
254
257
|
"base": "ui-card",
|
|
@@ -545,8 +548,14 @@
|
|
|
545
548
|
},
|
|
546
549
|
"ui-empty-state": {
|
|
547
550
|
"base": "ui-empty-state",
|
|
548
|
-
"modifiers": [
|
|
549
|
-
|
|
551
|
+
"modifiers": [
|
|
552
|
+
"ui-empty-state--invite"
|
|
553
|
+
],
|
|
554
|
+
"parts": [
|
|
555
|
+
"ui-empty-state__glyph",
|
|
556
|
+
"ui-empty-state__hint",
|
|
557
|
+
"ui-empty-state__lead"
|
|
558
|
+
]
|
|
550
559
|
},
|
|
551
560
|
"ui-error-summary": {
|
|
552
561
|
"base": "ui-error-summary",
|
|
@@ -910,6 +919,17 @@
|
|
|
910
919
|
"ui-pagination__item"
|
|
911
920
|
]
|
|
912
921
|
},
|
|
922
|
+
"ui-pane": {
|
|
923
|
+
"base": "ui-pane",
|
|
924
|
+
"modifiers": [],
|
|
925
|
+
"parts": [
|
|
926
|
+
"ui-pane__actions",
|
|
927
|
+
"ui-pane__body",
|
|
928
|
+
"ui-pane__head",
|
|
929
|
+
"ui-pane__title",
|
|
930
|
+
"ui-pane__title-input"
|
|
931
|
+
]
|
|
932
|
+
},
|
|
913
933
|
"ui-panel": {
|
|
914
934
|
"base": "ui-panel",
|
|
915
935
|
"modifiers": [],
|
|
@@ -1104,12 +1124,34 @@
|
|
|
1104
1124
|
},
|
|
1105
1125
|
"ui-selectionbar": {
|
|
1106
1126
|
"base": "ui-selectionbar",
|
|
1107
|
-
"modifiers": [
|
|
1127
|
+
"modifiers": [
|
|
1128
|
+
"ui-selectionbar--anchor-block-end",
|
|
1129
|
+
"ui-selectionbar--anchor-block-start",
|
|
1130
|
+
"ui-selectionbar--anchored"
|
|
1131
|
+
],
|
|
1108
1132
|
"parts": [
|
|
1109
1133
|
"ui-selectionbar__actions",
|
|
1110
1134
|
"ui-selectionbar__count"
|
|
1111
1135
|
]
|
|
1112
1136
|
},
|
|
1137
|
+
"ui-severity": {
|
|
1138
|
+
"base": "ui-severity",
|
|
1139
|
+
"modifiers": [],
|
|
1140
|
+
"parts": []
|
|
1141
|
+
},
|
|
1142
|
+
"ui-severity-dot": {
|
|
1143
|
+
"base": "ui-severity-dot",
|
|
1144
|
+
"modifiers": [],
|
|
1145
|
+
"parts": []
|
|
1146
|
+
},
|
|
1147
|
+
"ui-severity-row": {
|
|
1148
|
+
"base": "ui-severity-row",
|
|
1149
|
+
"modifiers": [],
|
|
1150
|
+
"parts": [
|
|
1151
|
+
"ui-severity-row__meta",
|
|
1152
|
+
"ui-severity-row__title"
|
|
1153
|
+
]
|
|
1154
|
+
},
|
|
1113
1155
|
"ui-shortcut": {
|
|
1114
1156
|
"base": "ui-shortcut",
|
|
1115
1157
|
"modifiers": [],
|
|
@@ -1447,13 +1489,18 @@
|
|
|
1447
1489
|
"ui-toolstrip": {
|
|
1448
1490
|
"base": "ui-toolstrip",
|
|
1449
1491
|
"modifiers": [
|
|
1492
|
+
"ui-toolstrip--anchor-block-end",
|
|
1493
|
+
"ui-toolstrip--anchor-block-start",
|
|
1494
|
+
"ui-toolstrip--anchored",
|
|
1450
1495
|
"ui-toolstrip--compact",
|
|
1451
|
-
"ui-toolstrip--floating"
|
|
1496
|
+
"ui-toolstrip--floating",
|
|
1497
|
+
"ui-toolstrip--pane"
|
|
1452
1498
|
],
|
|
1453
1499
|
"parts": [
|
|
1454
1500
|
"ui-toolstrip__actions",
|
|
1455
1501
|
"ui-toolstrip__brand",
|
|
1456
1502
|
"ui-toolstrip__context",
|
|
1503
|
+
"ui-toolstrip__fill",
|
|
1457
1504
|
"ui-toolstrip__group",
|
|
1458
1505
|
"ui-toolstrip__search"
|
|
1459
1506
|
]
|
|
@@ -1610,11 +1657,13 @@
|
|
|
1610
1657
|
"ui-bullet__target",
|
|
1611
1658
|
"ui-button",
|
|
1612
1659
|
"ui-button--danger",
|
|
1660
|
+
"ui-button--dense",
|
|
1613
1661
|
"ui-button--ghost",
|
|
1614
1662
|
"ui-button--icon",
|
|
1615
1663
|
"ui-button--lg",
|
|
1616
1664
|
"ui-button--sm",
|
|
1617
1665
|
"ui-button--subtle",
|
|
1666
|
+
"ui-button__label",
|
|
1618
1667
|
"ui-card",
|
|
1619
1668
|
"ui-card--accent",
|
|
1620
1669
|
"ui-card--interactive",
|
|
@@ -1748,6 +1797,10 @@
|
|
|
1748
1797
|
"ui-dotspinner--lg",
|
|
1749
1798
|
"ui-dotspinner--sm",
|
|
1750
1799
|
"ui-empty-state",
|
|
1800
|
+
"ui-empty-state--invite",
|
|
1801
|
+
"ui-empty-state__glyph",
|
|
1802
|
+
"ui-empty-state__hint",
|
|
1803
|
+
"ui-empty-state__lead",
|
|
1751
1804
|
"ui-error-summary",
|
|
1752
1805
|
"ui-error-summary__list",
|
|
1753
1806
|
"ui-error-summary__title",
|
|
@@ -1907,6 +1960,12 @@
|
|
|
1907
1960
|
"ui-pagehead__title",
|
|
1908
1961
|
"ui-pagination",
|
|
1909
1962
|
"ui-pagination__item",
|
|
1963
|
+
"ui-pane",
|
|
1964
|
+
"ui-pane__actions",
|
|
1965
|
+
"ui-pane__body",
|
|
1966
|
+
"ui-pane__head",
|
|
1967
|
+
"ui-pane__title",
|
|
1968
|
+
"ui-pane__title-input",
|
|
1910
1969
|
"ui-panel",
|
|
1911
1970
|
"ui-panel__head",
|
|
1912
1971
|
"ui-popover",
|
|
@@ -1994,8 +2053,16 @@
|
|
|
1994
2053
|
"ui-sel--on",
|
|
1995
2054
|
"ui-select",
|
|
1996
2055
|
"ui-selectionbar",
|
|
2056
|
+
"ui-selectionbar--anchor-block-end",
|
|
2057
|
+
"ui-selectionbar--anchor-block-start",
|
|
2058
|
+
"ui-selectionbar--anchored",
|
|
1997
2059
|
"ui-selectionbar__actions",
|
|
1998
2060
|
"ui-selectionbar__count",
|
|
2061
|
+
"ui-severity",
|
|
2062
|
+
"ui-severity-dot",
|
|
2063
|
+
"ui-severity-row",
|
|
2064
|
+
"ui-severity-row__meta",
|
|
2065
|
+
"ui-severity-row__title",
|
|
1999
2066
|
"ui-shortcut",
|
|
2000
2067
|
"ui-shortcut__sep",
|
|
2001
2068
|
"ui-sidebar",
|
|
@@ -2124,11 +2191,16 @@
|
|
|
2124
2191
|
"ui-tool-call__status",
|
|
2125
2192
|
"ui-tool-log",
|
|
2126
2193
|
"ui-toolstrip",
|
|
2194
|
+
"ui-toolstrip--anchor-block-end",
|
|
2195
|
+
"ui-toolstrip--anchor-block-start",
|
|
2196
|
+
"ui-toolstrip--anchored",
|
|
2127
2197
|
"ui-toolstrip--compact",
|
|
2128
2198
|
"ui-toolstrip--floating",
|
|
2199
|
+
"ui-toolstrip--pane",
|
|
2129
2200
|
"ui-toolstrip__actions",
|
|
2130
2201
|
"ui-toolstrip__brand",
|
|
2131
2202
|
"ui-toolstrip__context",
|
|
2203
|
+
"ui-toolstrip__fill",
|
|
2132
2204
|
"ui-toolstrip__group",
|
|
2133
2205
|
"ui-toolstrip__search",
|
|
2134
2206
|
"ui-tooltip",
|
package/classes/index.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export declare const cls: {
|
|
|
21
21
|
readonly buttonIcon: 'ui-button--icon';
|
|
22
22
|
readonly buttonSm: 'ui-button--sm';
|
|
23
23
|
readonly buttonLg: 'ui-button--lg';
|
|
24
|
+
readonly buttonDense: 'ui-button--dense';
|
|
25
|
+
readonly buttonLabel: 'ui-button__label';
|
|
24
26
|
readonly card: 'ui-card';
|
|
25
27
|
readonly cardHead: 'ui-card__head';
|
|
26
28
|
readonly cardAccent: 'ui-card--accent';
|
|
@@ -54,6 +56,10 @@ export declare const cls: {
|
|
|
54
56
|
readonly linkCta: 'ui-link--cta';
|
|
55
57
|
readonly keyValue: 'ui-key-value';
|
|
56
58
|
readonly emptyState: 'ui-empty-state';
|
|
59
|
+
readonly emptyStateInvite: 'ui-empty-state--invite';
|
|
60
|
+
readonly emptyStateGlyph: 'ui-empty-state__glyph';
|
|
61
|
+
readonly emptyStateLead: 'ui-empty-state__lead';
|
|
62
|
+
readonly emptyStateHint: 'ui-empty-state__hint';
|
|
57
63
|
readonly dot: 'ui-dot';
|
|
58
64
|
readonly dotAccent: 'ui-dot--accent';
|
|
59
65
|
readonly dotSuccess: 'ui-dot--success';
|
|
@@ -560,6 +566,11 @@ export declare const cls: {
|
|
|
560
566
|
readonly jobBlocked: 'ui-job--blocked';
|
|
561
567
|
readonly jobFailed: 'ui-job--failed';
|
|
562
568
|
readonly jobComplete: 'ui-job--complete';
|
|
569
|
+
readonly severity: 'ui-severity';
|
|
570
|
+
readonly severityDot: 'ui-severity-dot';
|
|
571
|
+
readonly severityRow: 'ui-severity-row';
|
|
572
|
+
readonly severityRowTitle: 'ui-severity-row__title';
|
|
573
|
+
readonly severityRowMeta: 'ui-severity-row__meta';
|
|
563
574
|
readonly generated: 'ui-generated';
|
|
564
575
|
readonly generatedLabel: 'ui-generated__label';
|
|
565
576
|
readonly originLabel: 'ui-origin-label';
|
|
@@ -577,11 +588,22 @@ export declare const cls: {
|
|
|
577
588
|
readonly toolstrip: 'ui-toolstrip';
|
|
578
589
|
readonly toolstripFloating: 'ui-toolstrip--floating';
|
|
579
590
|
readonly toolstripCompact: 'ui-toolstrip--compact';
|
|
591
|
+
readonly toolstripPane: 'ui-toolstrip--pane';
|
|
592
|
+
readonly toolstripAnchored: 'ui-toolstrip--anchored';
|
|
593
|
+
readonly toolstripAnchorBlockStart: 'ui-toolstrip--anchor-block-start';
|
|
594
|
+
readonly toolstripAnchorBlockEnd: 'ui-toolstrip--anchor-block-end';
|
|
580
595
|
readonly toolstripBrand: 'ui-toolstrip__brand';
|
|
581
596
|
readonly toolstripContext: 'ui-toolstrip__context';
|
|
582
597
|
readonly toolstripGroup: 'ui-toolstrip__group';
|
|
583
598
|
readonly toolstripActions: 'ui-toolstrip__actions';
|
|
599
|
+
readonly toolstripFill: 'ui-toolstrip__fill';
|
|
584
600
|
readonly toolstripSearch: 'ui-toolstrip__search';
|
|
601
|
+
readonly pane: 'ui-pane';
|
|
602
|
+
readonly paneHead: 'ui-pane__head';
|
|
603
|
+
readonly paneTitle: 'ui-pane__title';
|
|
604
|
+
readonly paneTitleInput: 'ui-pane__title-input';
|
|
605
|
+
readonly paneActions: 'ui-pane__actions';
|
|
606
|
+
readonly paneBody: 'ui-pane__body';
|
|
585
607
|
readonly segmentedButtons: 'ui-segmented-buttons';
|
|
586
608
|
readonly segmentedButtonsButton: 'ui-segmented-buttons__button';
|
|
587
609
|
readonly property: 'ui-property';
|
|
@@ -590,6 +612,9 @@ export declare const cls: {
|
|
|
590
612
|
readonly selectionbar: 'ui-selectionbar';
|
|
591
613
|
readonly selectionbarCount: 'ui-selectionbar__count';
|
|
592
614
|
readonly selectionbarActions: 'ui-selectionbar__actions';
|
|
615
|
+
readonly selectionbarAnchored: 'ui-selectionbar--anchored';
|
|
616
|
+
readonly selectionbarAnchorBlockStart: 'ui-selectionbar--anchor-block-start';
|
|
617
|
+
readonly selectionbarAnchorBlockEnd: 'ui-selectionbar--anchor-block-end';
|
|
593
618
|
readonly splitter: 'ui-splitter';
|
|
594
619
|
readonly splitterVertical: 'ui-splitter--vertical';
|
|
595
620
|
readonly splitterHorizontal: 'ui-splitter--horizontal';
|
|
@@ -666,7 +691,17 @@ export declare function cx(...parts: readonly ClassValue[]): string;
|
|
|
666
691
|
export interface ButtonOpts {
|
|
667
692
|
variant?: 'ghost' | 'subtle' | 'danger';
|
|
668
693
|
icon?: boolean;
|
|
669
|
-
size?: 'sm' | 'lg';
|
|
694
|
+
size?: 'sm' | 'lg' | 'dense';
|
|
695
|
+
}
|
|
696
|
+
export interface EmptyStateOpts {
|
|
697
|
+
invite?: boolean;
|
|
698
|
+
}
|
|
699
|
+
export interface ToolstripOpts {
|
|
700
|
+
variant?: 'floating' | 'compact' | 'pane';
|
|
701
|
+
anchor?: 'block-start' | 'block-end';
|
|
702
|
+
}
|
|
703
|
+
export interface SelectionbarOpts {
|
|
704
|
+
anchor?: 'block-start' | 'block-end';
|
|
670
705
|
}
|
|
671
706
|
export interface CardOpts {
|
|
672
707
|
accent?: boolean;
|
|
@@ -952,11 +987,28 @@ export interface Ui {
|
|
|
952
987
|
state(opts?: StateOpts): string;
|
|
953
988
|
job(opts?: JobOpts): string;
|
|
954
989
|
originLabel(opts?: OriginLabelOpts): string;
|
|
990
|
+
emptyState(opts?: EmptyStateOpts): string;
|
|
991
|
+
toolstrip(opts?: ToolstripOpts): string;
|
|
992
|
+
selectionbar(opts?: SelectionbarOpts): string;
|
|
955
993
|
}
|
|
956
994
|
|
|
957
995
|
export declare const ui: Ui;
|
|
958
996
|
export default ui;
|
|
959
997
|
|
|
998
|
+
/** The canonical severity ladder, worst to best. `unknown` is deliberately not
|
|
999
|
+
* a member: it means "not measured", not "nearly ok". */
|
|
1000
|
+
export declare const SEVERITY_LEVELS: readonly ['critical', 'error', 'warning', 'notice', 'ok'];
|
|
1001
|
+
|
|
1002
|
+
export type SeverityLevel = (typeof SEVERITY_LEVELS)[number];
|
|
1003
|
+
|
|
1004
|
+
/** Bundles `data-level` with the severity class so the attribute that carries
|
|
1005
|
+
* the meaning cannot be forgotten. An unrecognised level resolves to
|
|
1006
|
+
* `'unknown'`, which paints the neutral tone. */
|
|
1007
|
+
export declare function severity(
|
|
1008
|
+
level: SeverityLevel | (string & {}) | null | undefined,
|
|
1009
|
+
opts?: { part?: 'chip' | 'dot' | 'row' },
|
|
1010
|
+
): { class: string; 'data-level': string };
|
|
1011
|
+
|
|
960
1012
|
/** Min/max for the value-bearing fills; defaults to 0–100. */
|
|
961
1013
|
export interface ValueRangeOpts {
|
|
962
1014
|
min?: number;
|
package/classes/index.js
CHANGED
|
@@ -25,6 +25,8 @@ export const cls = Object.freeze({
|
|
|
25
25
|
buttonIcon: 'ui-button--icon',
|
|
26
26
|
buttonSm: 'ui-button--sm',
|
|
27
27
|
buttonLg: 'ui-button--lg',
|
|
28
|
+
buttonDense: 'ui-button--dense',
|
|
29
|
+
buttonLabel: 'ui-button__label',
|
|
28
30
|
card: 'ui-card',
|
|
29
31
|
cardHead: 'ui-card__head',
|
|
30
32
|
cardAccent: 'ui-card--accent',
|
|
@@ -58,6 +60,10 @@ export const cls = Object.freeze({
|
|
|
58
60
|
linkCta: 'ui-link--cta',
|
|
59
61
|
keyValue: 'ui-key-value',
|
|
60
62
|
emptyState: 'ui-empty-state',
|
|
63
|
+
emptyStateInvite: 'ui-empty-state--invite',
|
|
64
|
+
emptyStateGlyph: 'ui-empty-state__glyph',
|
|
65
|
+
emptyStateLead: 'ui-empty-state__lead',
|
|
66
|
+
emptyStateHint: 'ui-empty-state__hint',
|
|
61
67
|
// dots
|
|
62
68
|
dot: 'ui-dot',
|
|
63
69
|
dotAccent: 'ui-dot--accent',
|
|
@@ -597,6 +603,12 @@ export const cls = Object.freeze({
|
|
|
597
603
|
jobBlocked: 'ui-job--blocked',
|
|
598
604
|
jobFailed: 'ui-job--failed',
|
|
599
605
|
jobComplete: 'ui-job--complete',
|
|
606
|
+
// severity ladder — the second axis of state (css/state.css)
|
|
607
|
+
severity: 'ui-severity',
|
|
608
|
+
severityDot: 'ui-severity-dot',
|
|
609
|
+
severityRow: 'ui-severity-row',
|
|
610
|
+
severityRowTitle: 'ui-severity-row__title',
|
|
611
|
+
severityRowMeta: 'ui-severity-row__meta',
|
|
600
612
|
// generated content / AI-trust surfaces (css/generated.css)
|
|
601
613
|
generated: 'ui-generated',
|
|
602
614
|
generatedLabel: 'ui-generated__label',
|
|
@@ -616,11 +628,22 @@ export const cls = Object.freeze({
|
|
|
616
628
|
toolstrip: 'ui-toolstrip',
|
|
617
629
|
toolstripFloating: 'ui-toolstrip--floating',
|
|
618
630
|
toolstripCompact: 'ui-toolstrip--compact',
|
|
631
|
+
toolstripPane: 'ui-toolstrip--pane',
|
|
632
|
+
toolstripAnchored: 'ui-toolstrip--anchored',
|
|
633
|
+
toolstripAnchorBlockStart: 'ui-toolstrip--anchor-block-start',
|
|
634
|
+
toolstripAnchorBlockEnd: 'ui-toolstrip--anchor-block-end',
|
|
619
635
|
toolstripBrand: 'ui-toolstrip__brand',
|
|
620
636
|
toolstripContext: 'ui-toolstrip__context',
|
|
621
637
|
toolstripGroup: 'ui-toolstrip__group',
|
|
622
638
|
toolstripActions: 'ui-toolstrip__actions',
|
|
639
|
+
toolstripFill: 'ui-toolstrip__fill',
|
|
623
640
|
toolstripSearch: 'ui-toolstrip__search',
|
|
641
|
+
pane: 'ui-pane',
|
|
642
|
+
paneHead: 'ui-pane__head',
|
|
643
|
+
paneTitle: 'ui-pane__title',
|
|
644
|
+
paneTitleInput: 'ui-pane__title-input',
|
|
645
|
+
paneActions: 'ui-pane__actions',
|
|
646
|
+
paneBody: 'ui-pane__body',
|
|
624
647
|
segmentedButtons: 'ui-segmented-buttons',
|
|
625
648
|
segmentedButtonsButton: 'ui-segmented-buttons__button',
|
|
626
649
|
property: 'ui-property',
|
|
@@ -629,6 +652,9 @@ export const cls = Object.freeze({
|
|
|
629
652
|
selectionbar: 'ui-selectionbar',
|
|
630
653
|
selectionbarCount: 'ui-selectionbar__count',
|
|
631
654
|
selectionbarActions: 'ui-selectionbar__actions',
|
|
655
|
+
selectionbarAnchored: 'ui-selectionbar--anchored',
|
|
656
|
+
selectionbarAnchorBlockStart: 'ui-selectionbar--anchor-block-start',
|
|
657
|
+
selectionbarAnchorBlockEnd: 'ui-selectionbar--anchor-block-end',
|
|
632
658
|
splitter: 'ui-splitter',
|
|
633
659
|
splitterVertical: 'ui-splitter--vertical',
|
|
634
660
|
splitterHorizontal: 'ui-splitter--horizontal',
|
|
@@ -934,6 +960,7 @@ export const ui = {
|
|
|
934
960
|
icon && cls.buttonIcon,
|
|
935
961
|
size === 'sm' && cls.buttonSm,
|
|
936
962
|
size === 'lg' && cls.buttonLg,
|
|
963
|
+
size === 'dense' && cls.buttonDense,
|
|
937
964
|
),
|
|
938
965
|
card: ({ accent, interactive } = {}) =>
|
|
939
966
|
j(cls.card, accent && cls.cardAccent, interactive && cls.cardInteractive),
|
|
@@ -1092,8 +1119,41 @@ export const ui = {
|
|
|
1092
1119
|
state: ({ state, busy } = {}) => j(cls.state, stateTone(state), busy && cls.stateBusy),
|
|
1093
1120
|
job: ({ state, compact } = {}) => j(cls.job, jobTone(state), compact && cls.jobCompact),
|
|
1094
1121
|
originLabel: ({ ai } = {}) => j(cls.originLabel, ai && cls.originLabelAi),
|
|
1122
|
+
emptyState: ({ invite } = {}) => j(cls.emptyState, invite && cls.emptyStateInvite),
|
|
1123
|
+
toolstrip: ({ variant, anchor } = {}) =>
|
|
1124
|
+
j(
|
|
1125
|
+
cls.toolstrip,
|
|
1126
|
+
variant === 'floating' && cls.toolstripFloating,
|
|
1127
|
+
variant === 'compact' && cls.toolstripCompact,
|
|
1128
|
+
variant === 'pane' && cls.toolstripPane,
|
|
1129
|
+
anchor && cls.toolstripAnchored,
|
|
1130
|
+
anchor === 'block-start' && cls.toolstripAnchorBlockStart,
|
|
1131
|
+
anchor === 'block-end' && cls.toolstripAnchorBlockEnd,
|
|
1132
|
+
),
|
|
1133
|
+
selectionbar: ({ anchor } = {}) =>
|
|
1134
|
+
j(
|
|
1135
|
+
cls.selectionbar,
|
|
1136
|
+
anchor && cls.selectionbarAnchored,
|
|
1137
|
+
anchor === 'block-start' && cls.selectionbarAnchorBlockStart,
|
|
1138
|
+
anchor === 'block-end' && cls.selectionbarAnchorBlockEnd,
|
|
1139
|
+
),
|
|
1095
1140
|
};
|
|
1096
1141
|
|
|
1142
|
+
/** The canonical severity ladder, worst to best. `unknown` is deliberately NOT
|
|
1143
|
+
* in the ordering — it means "not measured", not "nearly ok", and sorting it
|
|
1144
|
+
* next to `ok` is how a dead collector reads as a healthy system. Exported as
|
|
1145
|
+
* data so a host can drive filters and sorts from the same list the CSS
|
|
1146
|
+
* paints, instead of re-typing the tiers. */
|
|
1147
|
+
export const SEVERITY_LEVELS = Object.freeze(['critical', 'error', 'warning', 'notice', 'ok']);
|
|
1148
|
+
|
|
1149
|
+
/** `data-level` + the severity class, bundled so the attribute that carries the
|
|
1150
|
+
* meaning cannot be forgotten — the class alone paints the neutral tone and
|
|
1151
|
+
* silently loses the level. Unknown/absent levels resolve to `unknown`. */
|
|
1152
|
+
export const severity = (level, { part = 'chip' } = {}) => ({
|
|
1153
|
+
class: part === 'dot' ? cls.severityDot : part === 'row' ? cls.severityRow : cls.severity,
|
|
1154
|
+
'data-level': SEVERITY_LEVELS.includes(level) ? level : 'unknown',
|
|
1155
|
+
});
|
|
1156
|
+
|
|
1097
1157
|
// Attribute + style bundle for the data-bearing fills (`ui-meter`/`ui-progress`).
|
|
1098
1158
|
// The class string alone paints a 0-width, unannounced bar: the fill width is a
|
|
1099
1159
|
// UNITLESS `--value` (0–100) and AT needs role + aria-valuenow/min/max. This sets
|
|
@@ -257,6 +257,22 @@
|
|
|
257
257
|
"name": "--radius-xl",
|
|
258
258
|
"description": "Global scale token. Value: `4px`"
|
|
259
259
|
},
|
|
260
|
+
{
|
|
261
|
+
"name": "--safe-area-bottom",
|
|
262
|
+
"description": "Global scale token. Value: `env(safe-area-inset-bottom, 0px)`"
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"name": "--safe-area-left",
|
|
266
|
+
"description": "Global scale token. Value: `env(safe-area-inset-left, 0px)`"
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"name": "--safe-area-right",
|
|
270
|
+
"description": "Global scale token. Value: `env(safe-area-inset-right, 0px)`"
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"name": "--safe-area-top",
|
|
274
|
+
"description": "Global scale token. Value: `env(safe-area-inset-top, 0px)`"
|
|
275
|
+
},
|
|
260
276
|
{
|
|
261
277
|
"name": "--sans",
|
|
262
278
|
"description": "Global scale token. Value: `'Inter', 'SF Pro Text', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif`"
|
|
@@ -341,6 +357,14 @@
|
|
|
341
357
|
"name": "--surface-raised",
|
|
342
358
|
"description": "Global scale token. Value: `var(--panel-strong)`"
|
|
343
359
|
},
|
|
360
|
+
{
|
|
361
|
+
"name": "--tap-target",
|
|
362
|
+
"description": "Global scale token. Value: `max(44px, 2.9rem)`"
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
"name": "--tap-target-min",
|
|
366
|
+
"description": "Global scale token. Value: `max(24px, 1.6rem)`"
|
|
367
|
+
},
|
|
344
368
|
{
|
|
345
369
|
"name": "--text",
|
|
346
370
|
"description": "Theme token. Light: `#0a0a0a` · Dark: `#e6e6e6`"
|