@ponchia/ui 0.5.0 → 0.6.3
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 +386 -4
- package/MIGRATIONS.json +14 -0
- package/README.md +29 -6
- package/annotations/index.d.ts +398 -276
- package/annotations/index.d.ts.map +1 -0
- package/annotations/index.js +350 -77
- package/behaviors/carousel.d.ts +28 -0
- package/behaviors/carousel.d.ts.map +1 -0
- package/behaviors/carousel.js +20 -16
- package/behaviors/combobox.d.ts +40 -0
- package/behaviors/combobox.d.ts.map +1 -0
- package/behaviors/combobox.js +111 -29
- package/behaviors/command.d.ts +41 -0
- package/behaviors/command.d.ts.map +1 -0
- package/behaviors/command.js +27 -15
- package/behaviors/connectors.d.ts +17 -0
- package/behaviors/connectors.d.ts.map +1 -0
- package/behaviors/connectors.js +7 -5
- package/behaviors/crosshair.d.ts +42 -0
- package/behaviors/crosshair.d.ts.map +1 -0
- package/behaviors/crosshair.js +23 -6
- package/behaviors/dialog.d.ts +20 -0
- package/behaviors/dialog.d.ts.map +1 -0
- package/behaviors/dialog.js +6 -2
- package/behaviors/disclosure.d.ts +10 -0
- package/behaviors/disclosure.d.ts.map +1 -0
- package/behaviors/disclosure.js +6 -2
- package/behaviors/dismissible.d.ts +10 -0
- package/behaviors/dismissible.d.ts.map +1 -0
- package/behaviors/dismissible.js +6 -2
- package/behaviors/forms.d.ts +27 -0
- package/behaviors/forms.d.ts.map +1 -0
- package/behaviors/forms.js +54 -13
- package/behaviors/glyph.d.ts +14 -0
- package/behaviors/glyph.d.ts.map +1 -0
- package/behaviors/glyph.js +28 -5
- package/behaviors/index.d.ts +31 -237
- package/behaviors/index.d.ts.map +1 -0
- package/behaviors/index.js +17 -0
- package/behaviors/inert.d.ts +20 -0
- package/behaviors/inert.d.ts.map +1 -0
- package/behaviors/inert.js +46 -0
- package/behaviors/internal.d.ts +25 -0
- package/behaviors/internal.d.ts.map +1 -0
- package/behaviors/internal.js +77 -1
- package/behaviors/legend.d.ts +35 -0
- package/behaviors/legend.d.ts.map +1 -0
- package/behaviors/legend.js +32 -2
- package/behaviors/menu.d.ts +16 -0
- package/behaviors/menu.d.ts.map +1 -0
- package/behaviors/menu.js +6 -2
- package/behaviors/modal.d.ts +41 -0
- package/behaviors/modal.d.ts.map +1 -0
- package/behaviors/modal.js +124 -0
- package/behaviors/popover.d.ts +28 -0
- package/behaviors/popover.d.ts.map +1 -0
- package/behaviors/popover.js +78 -7
- package/behaviors/spotlight.d.ts +17 -0
- package/behaviors/spotlight.d.ts.map +1 -0
- package/behaviors/spotlight.js +7 -5
- package/behaviors/table.d.ts +36 -0
- package/behaviors/table.d.ts.map +1 -0
- package/behaviors/table.js +84 -17
- package/behaviors/tabs.d.ts +20 -0
- package/behaviors/tabs.d.ts.map +1 -0
- package/behaviors/tabs.js +17 -14
- package/behaviors/theme.d.ts +54 -0
- package/behaviors/theme.d.ts.map +1 -0
- package/behaviors/theme.js +22 -3
- package/behaviors/toast.d.ts +49 -0
- package/behaviors/toast.d.ts.map +1 -0
- package/behaviors/toast.js +47 -3
- package/classes/classes.json +2527 -0
- package/classes/index.d.ts +134 -15
- package/classes/index.js +280 -80
- package/classes/vscode.css-custom-data.json +12 -0
- package/connectors/index.d.ts +201 -69
- package/connectors/index.d.ts.map +1 -0
- package/connectors/index.js +142 -25
- package/css/app.css +69 -13
- package/css/base.css +15 -10
- package/css/bullet.css +108 -0
- package/css/code.css +98 -0
- package/css/connectors.css +17 -0
- package/css/content.css +22 -3
- package/css/crosshair.css +7 -7
- package/css/dataviz.css +5 -1
- package/css/diff.css +153 -0
- package/css/disclosure.css +53 -7
- package/css/dots.css +94 -7
- package/css/feedback.css +97 -7
- package/css/forms.css +113 -4
- package/css/legend.css +16 -9
- package/css/marks.css +38 -8
- package/css/motion.css +98 -53
- package/css/navigation.css +7 -0
- package/css/overlay.css +90 -3
- package/css/primitives.css +158 -13
- package/css/report.css +73 -56
- package/css/sidenote.css +67 -0
- package/css/site.css +16 -2
- package/css/sources.css +43 -1
- package/css/spark.css +62 -0
- package/css/spotlight.css +1 -1
- package/css/table.css +9 -2
- package/css/term.css +110 -0
- package/css/textref.css +63 -0
- package/css/toc.css +91 -0
- package/css/tokens.css +49 -1
- package/css/tree.css +134 -0
- package/css/workbench.css +1 -1
- package/dist/bronto.css +1 -1
- package/dist/css/analytical.css +1 -1
- package/dist/css/app.css +1 -1
- package/dist/css/base.css +1 -1
- package/dist/css/bullet.css +1 -0
- package/dist/css/code.css +1 -0
- package/dist/css/connectors.css +1 -1
- package/dist/css/content.css +1 -1
- package/dist/css/crosshair.css +1 -1
- package/dist/css/diff.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/forms.css +1 -1
- package/dist/css/legend.css +1 -1
- package/dist/css/marks.css +1 -1
- package/dist/css/motion.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.css +1 -1
- package/dist/css/sidenote.css +1 -0
- package/dist/css/site.css +1 -1
- package/dist/css/sources.css +1 -1
- package/dist/css/spark.css +1 -0
- package/dist/css/spotlight.css +1 -1
- package/dist/css/table.css +1 -1
- package/dist/css/term.css +1 -0
- package/dist/css/textref.css +1 -0
- package/dist/css/toc.css +1 -0
- package/dist/css/tokens.css +1 -1
- package/dist/css/tree.css +1 -0
- package/dist/css/workbench.css +1 -1
- package/docs/adr/0003-theme-model.md +1 -1
- package/docs/annotations.md +133 -14
- package/docs/architecture.md +49 -6
- package/docs/bullet.md +78 -0
- package/docs/code.md +76 -0
- package/docs/contrast.md +116 -92
- package/docs/d2.md +196 -0
- package/docs/diff.md +146 -0
- package/docs/legends.md +23 -3
- package/docs/marks.md +9 -2
- package/docs/mermaid.md +169 -0
- package/docs/reference.md +201 -26
- package/docs/reporting.md +416 -57
- package/docs/sidenote.md +64 -0
- package/docs/sources.md +27 -0
- package/docs/spark.md +78 -0
- package/docs/stability.md +10 -2
- package/docs/term.md +81 -0
- package/docs/textref.md +78 -0
- package/docs/theming.md +44 -5
- package/docs/toc.md +83 -0
- package/docs/tree.md +74 -0
- package/docs/usage.md +354 -16
- package/docs/vega.md +244 -0
- package/docs/workbench.md +7 -1
- package/glyphs/glyphs.js +13 -5
- package/llms.txt +285 -14
- package/package.json +95 -17
- package/qwik/index.d.ts +44 -59
- package/qwik/index.d.ts.map +1 -0
- package/qwik/index.js +65 -3
- package/react/index.d.ts +41 -61
- package/react/index.d.ts.map +1 -0
- package/react/index.js +63 -3
- package/solid/index.d.ts +68 -61
- package/solid/index.d.ts.map +1 -0
- package/solid/index.js +66 -3
- package/tokens/d2.d.ts +38 -0
- package/tokens/d2.js +71 -0
- package/tokens/d2.json +43 -0
- package/tokens/index.d.ts +5 -5
- package/tokens/index.js +15 -1
- package/tokens/index.json +9 -0
- package/tokens/mermaid.d.ts +23 -0
- package/tokens/mermaid.js +181 -0
- package/tokens/mermaid.json +163 -0
- package/tokens/resolved.json +45 -1
- package/tokens/skins.js +3 -2
- package/tokens/tokens.dtcg.json +26 -0
- package/tokens/vega.d.ts +34 -0
- package/tokens/vega.js +155 -0
- package/tokens/vega.json +179 -0
package/docs/vega.md
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# Vega-Lite
|
|
2
|
+
|
|
3
|
+
[Vega-Lite](https://vega.github.io/vega-lite/) is a **declarative JSON grammar
|
|
4
|
+
of graphics** — you describe a chart as data and it compiles (through
|
|
5
|
+
[Vega](https://vega.github.io/vega/)) to **SVG or canvas**. Like the
|
|
6
|
+
[Mermaid](./mermaid.md) and [D2](./d2.md) integrations, `@ponchia/ui` doesn't
|
|
7
|
+
render charts — it **themes** them from your tokens. Two things ship:
|
|
8
|
+
|
|
9
|
+
- `@ponchia/ui/vega` — `brontoVegaConfig(theme)`, the on-brand Vega-Lite
|
|
10
|
+
[`config`](https://vega.github.io/vega-lite/docs/config.html) object.
|
|
11
|
+
- `@ponchia/ui/vega.json` — the resolved per-theme config, for any consumer.
|
|
12
|
+
|
|
13
|
+
This is the idiomatic Vega theme shape — a `config`, the same kind the
|
|
14
|
+
[`vega-themes`](https://github.com/vega/vega-themes) package ships. Vega stays
|
|
15
|
+
the consumer's renderer; this is config only, and **Vega is not a dependency**
|
|
16
|
+
of bronto (the dev-only render-probe aside).
|
|
17
|
+
|
|
18
|
+
> Why Vega-Lite and not a bronto chart component? A chart needs **scales**
|
|
19
|
+
> (data → pixels) and **data binding** — the two things the analytical layer
|
|
20
|
+
> [refuses to own](./architecture.md). A spec is also something an
|
|
21
|
+
> LLM-from-another-system can emit as data, the same way it emits Mermaid/D2.
|
|
22
|
+
> So bronto themes a real charting grammar instead of shipping a fragile one.
|
|
23
|
+
|
|
24
|
+
## Theme a chart
|
|
25
|
+
|
|
26
|
+
`brontoVegaConfig(theme)` returns a `config` object. Spread it into a spec, or
|
|
27
|
+
hand it to [vega-embed](https://github.com/vega/vega-embed):
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
import vegaEmbed from 'vega-embed';
|
|
31
|
+
import { brontoVegaConfig } from '@ponchia/ui/vega';
|
|
32
|
+
|
|
33
|
+
const theme = document.documentElement.dataset.theme === 'dark' ? 'dark' : 'light';
|
|
34
|
+
|
|
35
|
+
vegaEmbed('#chart', {
|
|
36
|
+
data: { values: [
|
|
37
|
+
{ quarter: 'Q1', value: 42 },
|
|
38
|
+
{ quarter: 'Q2', value: 58 },
|
|
39
|
+
{ quarter: 'Q3', value: 50 },
|
|
40
|
+
] },
|
|
41
|
+
mark: 'bar',
|
|
42
|
+
encoding: {
|
|
43
|
+
x: { field: 'quarter', type: 'nominal' },
|
|
44
|
+
y: { field: 'value', type: 'quantitative' },
|
|
45
|
+
},
|
|
46
|
+
}, { config: brontoVegaConfig(theme), renderer: 'svg', actions: false });
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Pass **`renderer: 'svg'`** (not vega-embed's `canvas` default): an SVG chart is
|
|
50
|
+
inspectable, themeable, survives the print/PDF pipeline, and is what the
|
|
51
|
+
[annotation layer](#annotate-a-chart) composes onto — a canvas chart prints as a
|
|
52
|
+
raster and carries no text alternative.
|
|
53
|
+
|
|
54
|
+
### From a CDN, no bundler
|
|
55
|
+
|
|
56
|
+
Load Vega + Vega-Lite + vega-embed from **pinned `/build/*.min.js` UMD files**,
|
|
57
|
+
then pass the config. Pin exact versions and use the `/build/` path — a bare
|
|
58
|
+
`cdn.jsdelivr.net/npm/vega@6` redirect resolves to a module bundle that does
|
|
59
|
+
**not** register the global `window.vega`, so vega-embed throws and nothing
|
|
60
|
+
renders. Keep the three majors aligned: **Vega-Lite 6 targets Vega 6** (and
|
|
61
|
+
vega-embed 7), so don't mix a Vega-Lite 6 with a Vega 5 runtime:
|
|
62
|
+
|
|
63
|
+
```html
|
|
64
|
+
<script src="https://cdn.jsdelivr.net/npm/vega@6.2.0/build/vega.min.js"></script>
|
|
65
|
+
<script src="https://cdn.jsdelivr.net/npm/vega-lite@6.4.3/build/vega-lite.min.js"></script>
|
|
66
|
+
<script src="https://cdn.jsdelivr.net/npm/vega-embed@7.1.0/build/vega-embed.min.js"></script>
|
|
67
|
+
<script>
|
|
68
|
+
// INLINE the config — generate the paste-ready literal with
|
|
69
|
+
// `npm run emit:theme vega light` (mirrors the annotations author-time-copy
|
|
70
|
+
// pattern). This is the only path that also works from a file:// report.
|
|
71
|
+
const brontoLight = {
|
|
72
|
+
/* …paste tokens/vega.json → light here… */
|
|
73
|
+
};
|
|
74
|
+
vegaEmbed('#chart', spec, { config: brontoLight, renderer: 'svg', actions: false });
|
|
75
|
+
</script>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
> **file:// portability.** A report opened straight from disk (`file://`) cannot
|
|
79
|
+
> `import` the `@ponchia/ui/vega` module **nor** `fetch('…/vega.json')` — the
|
|
80
|
+
> browser blocks both across the `null`/file origin (CORS). So for a
|
|
81
|
+
> double-clickable or PDF-bound report, **inline the resolved config object**
|
|
82
|
+
> (as above) rather than fetching it. Generate the paste-ready, sentinel-tagged
|
|
83
|
+
> literal with `npm run emit:theme vega light` (or `dark`); re-running
|
|
84
|
+
> `npm run emit:theme:check <file>` re-derives every tagged block and fails if a
|
|
85
|
+
> token change has left an inlined copy stale. Over an `http(s)` origin (a dev server, a
|
|
86
|
+
> static host, a bundler), the `import { brontoVegaConfig }` form and a
|
|
87
|
+
> `fetch('https://cdn.jsdelivr.net/npm/@ponchia/ui@VERSION/tokens/vega.json')`
|
|
88
|
+
> both work — pin the package version in the URL, since the unversioned latest
|
|
89
|
+
> may predate this target.
|
|
90
|
+
|
|
91
|
+
**Over `http(s)`, skip the inline copy — import the helper as an ES module.**
|
|
92
|
+
`tokens/vega.js` (the `@ponchia/ui/vega` entry) has **zero dependencies**, so it
|
|
93
|
+
loads straight from a CDN as a browser ES module with no bundler and no
|
|
94
|
+
import-map. You get `brontoVegaConfig(theme)` itself (live theme switching), not
|
|
95
|
+
a frozen object to keep in sync. Pin the package version; this needs a real
|
|
96
|
+
origin (it does **not** work from `file://` — use the inline form above there):
|
|
97
|
+
|
|
98
|
+
```html
|
|
99
|
+
<script type="module">
|
|
100
|
+
import { brontoVegaConfig } from 'https://cdn.jsdelivr.net/npm/@ponchia/ui@VERSION/tokens/vega.js';
|
|
101
|
+
// vegaEmbed loaded from its UMD bundle above (window.vegaEmbed), or import it as ESM too.
|
|
102
|
+
vegaEmbed('#chart', spec, { config: brontoVegaConfig('light'), renderer: 'svg', actions: false });
|
|
103
|
+
</script>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
For a build step or non-JS host, read `@ponchia/ui/vega.json` directly
|
|
107
|
+
(`{ light, dark }`, each a ready Vega-Lite `config`).
|
|
108
|
+
|
|
109
|
+
### Why resolved colours, not `var(--x)`
|
|
110
|
+
|
|
111
|
+
Vega-Lite compiles a spec to a Vega scene that renders to **SVG or canvas** —
|
|
112
|
+
colours are **baked into the output** and parsed by `d3-color`, which understands
|
|
113
|
+
real hex/rgb but **not** `var()` (nor `oklch()`). So the config ships **resolved
|
|
114
|
+
hex per theme**, projected from the same token source as
|
|
115
|
+
[`tokens/resolved.json`](./architecture.md) / [`charts.json`](./theming.md).
|
|
116
|
+
Re-call `brontoVegaConfig()` when the theme toggles and re-embed.
|
|
117
|
+
|
|
118
|
+
### What the slots paint
|
|
119
|
+
|
|
120
|
+
The config keeps a chart **monochrome by default** — the rationed accent is the
|
|
121
|
+
one chromatic default (series 1 / the lone mark), never the chrome:
|
|
122
|
+
|
|
123
|
+
| Slot | Paint | bronto token |
|
|
124
|
+
| --- | --- | --- |
|
|
125
|
+
| `background` | Chart canvas | `--bg` |
|
|
126
|
+
| `view.stroke` | Plot frame | `--line` |
|
|
127
|
+
| `mark.color` | Default / single-series mark | `--accent` |
|
|
128
|
+
| `rule.color` | Reference rules, annotations | `--line-strong` |
|
|
129
|
+
| `axis.domainColor` · `tickColor` | Axis line · ticks | `--line-strong` |
|
|
130
|
+
| `axis.gridColor` | Gridlines | `--line` |
|
|
131
|
+
| `axis.labelColor` · `titleColor` | Tick labels · axis title | `--text-soft` · `--text` |
|
|
132
|
+
| `text.color` | Free `text`/`label` marks | `--text` |
|
|
133
|
+
| `legend.*` · `header.*` · `title.*` | Legend, facet headers, title | `--text-soft` / `--text` / `--text-dim` |
|
|
134
|
+
| `*.font` / `*Font` | All text | `--sans` |
|
|
135
|
+
| `range.category` | 8-series categorical palette | `charts.json` categorical (series 1 = accent) |
|
|
136
|
+
| `range.ordinal` · `ramp` · `heatmap` | Single-hue sequential ramp | `charts.json` sequential |
|
|
137
|
+
| `range.diverging` | − … neutral … + ramp | `charts.json` diverging |
|
|
138
|
+
|
|
139
|
+
The palette is the same CVD-safe, pattern-paired set documented in
|
|
140
|
+
[theming](./theming.md#data-viz) — colour is never the sole channel. When a
|
|
141
|
+
series needs the redundant second channel, drive the mark's fill from the
|
|
142
|
+
`--chart-pattern-*` tokens or pair a [legend](./legends.md) swatch.
|
|
143
|
+
|
|
144
|
+
### Spending the accent
|
|
145
|
+
|
|
146
|
+
Series 1 of `range.category` **is** the live accent, so a single-series chart and
|
|
147
|
+
the first category re-skin for free with `--accent`. To emphasise one mark in a
|
|
148
|
+
multi-series chart, paint just that mark with the accent and leave the rest
|
|
149
|
+
neutral — the same "reserve the accent for the one thing a reader must not miss"
|
|
150
|
+
rule the rest of the system follows. Two small helpers hand you the exact
|
|
151
|
+
per-theme hexes so you never hard-code a palette array index:
|
|
152
|
+
|
|
153
|
+
```js
|
|
154
|
+
import { brontoVegaAccent, brontoVegaNeutral } from '@ponchia/ui/vega';
|
|
155
|
+
|
|
156
|
+
// e.g. a bar chart where only the 'Alert' category is loud:
|
|
157
|
+
const spec = {
|
|
158
|
+
/* …data… */
|
|
159
|
+
mark: 'bar',
|
|
160
|
+
encoding: {
|
|
161
|
+
x: { field: 'name', type: 'nominal' },
|
|
162
|
+
y: { field: 'value', type: 'quantitative' },
|
|
163
|
+
color: {
|
|
164
|
+
condition: { test: "datum.name === 'Alert'", value: brontoVegaAccent(theme) },
|
|
165
|
+
value: brontoVegaNeutral(theme),
|
|
166
|
+
},
|
|
167
|
+
legend: null,
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
`brontoVegaAccent(theme)` is `range.category[0]` (the live accent) and
|
|
173
|
+
`brontoVegaNeutral(theme)` is the last category (the quiet neutral); re-read both
|
|
174
|
+
when the theme toggles. Prefer them over digging the hex out of
|
|
175
|
+
`tokens/resolved.json` — they are guaranteed to match the palette the config
|
|
176
|
+
already ships. In token terms the accent is `--chart-1` and the neutral is
|
|
177
|
+
`--chart-8`, so a [legend](./legends.md#swatch-colour) for an accent-rationed
|
|
178
|
+
chart keys those two series with `ui-legend__swatch--1` and
|
|
179
|
+
`ui-legend__swatch--8` — the swatches mirror the marks exactly.
|
|
180
|
+
|
|
181
|
+
### Selecting the themed ramp in a spec
|
|
182
|
+
|
|
183
|
+
The config registers the ramps as **named ranges**, so a quantitative encoding
|
|
184
|
+
opts in with `scale: { range: 'heatmap' }` (or `'ramp'` / `'diverging'`) — the
|
|
185
|
+
range **name**, not a colour scheme:
|
|
186
|
+
|
|
187
|
+
```js
|
|
188
|
+
{
|
|
189
|
+
mark: 'rect',
|
|
190
|
+
encoding: {
|
|
191
|
+
x: { field: 'x', type: 'nominal' },
|
|
192
|
+
y: { field: 'y', type: 'nominal' },
|
|
193
|
+
color: { field: 'v', type: 'quantitative', scale: { range: 'heatmap' } },
|
|
194
|
+
},
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
> Use `scale: { range: 'heatmap' }`, **not** `scale: { scheme: 'heatmap' }`.
|
|
199
|
+
> `scheme:` looks up a registered Vega/d3 scheme by name and **throws** for
|
|
200
|
+
> `'heatmap'` (no such scheme) — the ramp is a custom `range` the bronto config
|
|
201
|
+
> defines, addressed by range name. A `quantitative` colour encoding already
|
|
202
|
+
> defaults to `range.heatmap`; name it explicitly only when a chart has several
|
|
203
|
+
> quantitative scales and you want a specific one (`'diverging'` for a signed
|
|
204
|
+
> domain around a neutral centre).
|
|
205
|
+
|
|
206
|
+
### Sequential & diverging ramps invert by theme
|
|
207
|
+
|
|
208
|
+
`range.heatmap` / `ramp` / `ordinal` is a single-hue ramp that runs **pale → deep
|
|
209
|
+
as the value rises in light theme, and deep → pale in dark theme** (the bg flips,
|
|
210
|
+
so the ramp flips to stay legible against it). Two consequences:
|
|
211
|
+
|
|
212
|
+
- **Don't hard-code ink on a heatmap cell.** A fixed black (or white) label is
|
|
213
|
+
readable at one end of the ramp and invisible at the other — and the readable
|
|
214
|
+
end swaps between themes. Either omit per-cell labels and rely on the fallback
|
|
215
|
+
`ui-table`, or compute the label colour from the cell's luminance at render
|
|
216
|
+
time. bronto themes the ramp; it can't know your data domain, so it does not
|
|
217
|
+
ship a cell-ink helper.
|
|
218
|
+
- **A CSS gradient key won't pixel-match the Vega ramp.** A native
|
|
219
|
+
[`ui-legend--gradient`](./legends.md) track is interpolated in OKLCH; Vega
|
|
220
|
+
interpolates its `range.*` ramp in d3's RGB space. They share endpoints but
|
|
221
|
+
drift in the mid-tones, so a continuous gradient key placed beside a Vega
|
|
222
|
+
heatmap will not match its mid cells exactly. Use a **stepped** legend (one
|
|
223
|
+
swatch per band, each from the same `charts.json` ramp stop) when the key sits
|
|
224
|
+
next to the chart.
|
|
225
|
+
|
|
226
|
+
## Annotate a chart
|
|
227
|
+
|
|
228
|
+
Vega renders to SVG, so the [annotation layer](./annotations.md) composes onto it
|
|
229
|
+
exactly as in the [Mermaid recipe](./mermaid.md#annotate-a-diagram): render to a
|
|
230
|
+
frozen SVG (vega-embed's `view.toSVG()`, or the Vega CLI), read the target mark's
|
|
231
|
+
box, and paste a `<g class="ui-annotation">` computed with
|
|
232
|
+
`@ponchia/ui/annotations`. The same caveat applies — Vega's internal SVG (element
|
|
233
|
+
ids, the `role`/`aria` structure, the scene transform) is **not a public
|
|
234
|
+
contract**, so pin your Vega version and key off the data, not generated ids.
|
|
235
|
+
|
|
236
|
+
## Scope
|
|
237
|
+
|
|
238
|
+
bronto owns the theme config — gated structurally by `check:vega` (every colour
|
|
239
|
+
slot resolves, both themes, no `var()` leaks, every `range.*` ramp populated),
|
|
240
|
+
and separately a dev-only render-probe (`npm test`, via the `vega`/`vega-lite`
|
|
241
|
+
dev deps) asserts the colours actually land on a rendered chart — and the
|
|
242
|
+
annotation geometry. It does not own Vega's grammar, its rendering, or its internal SVG —
|
|
243
|
+
those stay Vega's, and the chart is a documented composition, not a shipped
|
|
244
|
+
runtime binding.
|
package/docs/workbench.md
CHANGED
|
@@ -22,7 +22,7 @@ a `__body` of property rows.
|
|
|
22
22
|
|
|
23
23
|
```html
|
|
24
24
|
<aside class="ui-inspector">
|
|
25
|
-
<div class="ui-
|
|
25
|
+
<div class="ui-inspector__head">
|
|
26
26
|
<h2 class="ui-eyebrow">Rectangle</h2>
|
|
27
27
|
<button class="ui-button ui-button--subtle ui-button--sm" type="button">Reset</button>
|
|
28
28
|
</div>
|
|
@@ -50,6 +50,12 @@ A label/value pair, denser than `ui-key-value` and tuned for an inspector. The
|
|
|
50
50
|
|
|
51
51
|
## Selection bar — `.ui-selectionbar`
|
|
52
52
|
|
|
53
|
+
> **Name note:** `.ui-selectionbar` is the workbench bulk-action bar (this
|
|
54
|
+
> section). It is unrelated to the `.ui-sel--on` / `.ui-sel--off` /
|
|
55
|
+
> `.ui-sel--maybe` selection-emphasis state classes in
|
|
56
|
+
> [`css/selection.css`](./selection.md), which style host-managed selection
|
|
57
|
+
> state on individual items.
|
|
58
|
+
|
|
53
59
|
A raised bar of actions on the current selection: a `__count` on one side,
|
|
54
60
|
`__actions` on the other. The host owns what is selected and what the actions do.
|
|
55
61
|
|
package/glyphs/glyphs.js
CHANGED
|
@@ -23,7 +23,7 @@ export const GLYPH_SIZE = 16;
|
|
|
23
23
|
|
|
24
24
|
// Raw bitmaps. Each is GLYPH_SIZE rows of GLYPH_SIZE chars over [.#*]:
|
|
25
25
|
// `.` off · `#` hot · `*` accent. Only `spark` uses accent dots — it is the
|
|
26
|
-
// canonical two-tone demo;
|
|
26
|
+
// canonical two-tone demo; test/glyphs.test.mjs asserts the spark-only-* rule.
|
|
27
27
|
const RAW = {
|
|
28
28
|
circle: [
|
|
29
29
|
'................',
|
|
@@ -941,9 +941,9 @@ function esc(s) {
|
|
|
941
941
|
.replace(/"/g, '"');
|
|
942
942
|
}
|
|
943
943
|
|
|
944
|
-
// `dot
|
|
945
|
-
//
|
|
946
|
-
//
|
|
944
|
+
// `dot`, `gap`, and `size` land in an inline-CSS context (`style="…"`), where
|
|
945
|
+
// HTML-escaping a `"` stops attribute breakout but a `;` would still open a
|
|
946
|
+
// second CSS declaration (overlay/clickjacking, selector exfil). So restrict
|
|
947
947
|
// them to length/calc syntax — digits, units, %, whitespace and `()+-*/.,` for
|
|
948
948
|
// calc()/clamp()/var() — and drop anything else rather than emit it.
|
|
949
949
|
function cssLen(v) {
|
|
@@ -1004,6 +1004,8 @@ function maskUrl(rows) {
|
|
|
1004
1004
|
* bitmap (one DOM node, not GLYPH_SIZE²) — the icon-at-scale path: it sizes to
|
|
1005
1005
|
* `size` (or `--icon-size` / `1em`) and inherits `currentColor`. The
|
|
1006
1006
|
* cell-mode options (grid/solid/anim/dot/gap) don't apply; `label` does.
|
|
1007
|
+
* Mask mode is single-tone: accent `*` cells (used by `spark`) render
|
|
1008
|
+
* identically to hot `#` cells — both become opaque mask regions.
|
|
1007
1009
|
* Needs `@ponchia/ui/css` (the `.ui-icon` rule).
|
|
1008
1010
|
*/
|
|
1009
1011
|
export function renderGlyph(name, options = {}) {
|
|
@@ -1025,7 +1027,13 @@ export function renderGlyph(name, options = {}) {
|
|
|
1025
1027
|
const style = [`--dotmatrix-cols:${GLYPH_SIZE}`];
|
|
1026
1028
|
const dotLen = dot && cssLen(dot);
|
|
1027
1029
|
const gapLen = gap && cssLen(gap);
|
|
1028
|
-
|
|
1030
|
+
// Default the dot track to an intrinsic icon scale when the author set no
|
|
1031
|
+
// (valid) `--dotmatrix-dot`. Without it the CSS grid falls back to
|
|
1032
|
+
// `minmax(0, 1fr)` and the 16×16 matrix balloons to fill its container
|
|
1033
|
+
// (full-bleed, ~1250px) — the string API would then render an icon-intent call
|
|
1034
|
+
// very differently from the DOM `initDotGlyph` path, which already defaults to
|
|
1035
|
+
// 0.08em. Mirror that default here so both paths render the same icon. (C7.)
|
|
1036
|
+
style.push(`--dotmatrix-dot:${dotLen || '0.08em'}`);
|
|
1029
1037
|
// Solid mode fuses the dots into a crisp pixel glyph: square cells, no gap.
|
|
1030
1038
|
if (solid) style.push('--dotmatrix-dot-radius:0', '--dotmatrix-gap:0');
|
|
1031
1039
|
else if (gapLen) style.push(`--dotmatrix-gap:${gapLen}`);
|