@ponchia/ui 0.5.0 → 0.6.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.
Files changed (117) hide show
  1. package/CHANGELOG.md +322 -0
  2. package/MIGRATIONS.json +14 -0
  3. package/README.md +28 -5
  4. package/annotations/index.d.ts +398 -276
  5. package/annotations/index.d.ts.map +1 -0
  6. package/annotations/index.js +315 -45
  7. package/behaviors/carousel.js +17 -16
  8. package/behaviors/combobox.js +47 -16
  9. package/behaviors/command.js +18 -15
  10. package/behaviors/connectors.js +4 -5
  11. package/behaviors/crosshair.js +4 -5
  12. package/behaviors/dialog.js +3 -2
  13. package/behaviors/disclosure.js +3 -2
  14. package/behaviors/dismissible.js +3 -2
  15. package/behaviors/forms.js +41 -13
  16. package/behaviors/glyph.js +4 -5
  17. package/behaviors/internal.js +47 -0
  18. package/behaviors/legend.js +23 -2
  19. package/behaviors/menu.js +3 -2
  20. package/behaviors/popover.js +78 -7
  21. package/behaviors/spotlight.js +4 -5
  22. package/behaviors/table.js +39 -12
  23. package/behaviors/tabs.js +14 -14
  24. package/behaviors/theme.js +5 -3
  25. package/behaviors/toast.js +13 -1
  26. package/classes/classes.json +1857 -0
  27. package/classes/index.d.ts +28 -13
  28. package/classes/index.js +34 -18
  29. package/classes/vscode.css-custom-data.json +12 -0
  30. package/connectors/index.d.ts +189 -69
  31. package/connectors/index.d.ts.map +1 -0
  32. package/connectors/index.js +120 -24
  33. package/css/app.css +43 -13
  34. package/css/base.css +15 -10
  35. package/css/connectors.css +17 -0
  36. package/css/content.css +7 -1
  37. package/css/dataviz.css +5 -1
  38. package/css/disclosure.css +38 -6
  39. package/css/dots.css +57 -0
  40. package/css/feedback.css +60 -2
  41. package/css/forms.css +42 -1
  42. package/css/legend.css +11 -7
  43. package/css/marks.css +38 -8
  44. package/css/motion.css +24 -44
  45. package/css/navigation.css +7 -0
  46. package/css/overlay.css +31 -1
  47. package/css/primitives.css +91 -5
  48. package/css/report.css +40 -63
  49. package/css/site.css +16 -2
  50. package/css/sources.css +43 -1
  51. package/css/spotlight.css +1 -1
  52. package/css/tokens.css +36 -1
  53. package/css/workbench.css +1 -1
  54. package/dist/bronto.css +1 -1
  55. package/dist/css/analytical.css +1 -1
  56. package/dist/css/app.css +1 -1
  57. package/dist/css/base.css +1 -1
  58. package/dist/css/connectors.css +1 -1
  59. package/dist/css/content.css +1 -1
  60. package/dist/css/disclosure.css +1 -1
  61. package/dist/css/dots.css +1 -1
  62. package/dist/css/feedback.css +1 -1
  63. package/dist/css/forms.css +1 -1
  64. package/dist/css/legend.css +1 -1
  65. package/dist/css/marks.css +1 -1
  66. package/dist/css/motion.css +1 -1
  67. package/dist/css/navigation.css +1 -1
  68. package/dist/css/overlay.css +1 -1
  69. package/dist/css/primitives.css +1 -1
  70. package/dist/css/report.css +1 -1
  71. package/dist/css/site.css +1 -1
  72. package/dist/css/sources.css +1 -1
  73. package/dist/css/spotlight.css +1 -1
  74. package/dist/css/tokens.css +1 -1
  75. package/dist/css/workbench.css +1 -1
  76. package/docs/adr/0003-theme-model.md +1 -1
  77. package/docs/annotations.md +94 -14
  78. package/docs/architecture.md +50 -6
  79. package/docs/contrast.md +116 -92
  80. package/docs/d2.md +195 -0
  81. package/docs/legends.md +18 -2
  82. package/docs/marks.md +9 -2
  83. package/docs/mermaid.md +152 -0
  84. package/docs/reference.md +78 -22
  85. package/docs/reporting.md +395 -57
  86. package/docs/sources.md +27 -0
  87. package/docs/stability.md +9 -2
  88. package/docs/usage.md +101 -4
  89. package/docs/vega.md +225 -0
  90. package/docs/workbench.md +7 -1
  91. package/glyphs/glyphs.js +6 -4
  92. package/llms.txt +139 -14
  93. package/package.json +50 -12
  94. package/qwik/index.d.ts +42 -59
  95. package/qwik/index.d.ts.map +1 -0
  96. package/qwik/index.js +55 -3
  97. package/react/index.d.ts +39 -61
  98. package/react/index.d.ts.map +1 -0
  99. package/react/index.js +57 -3
  100. package/solid/index.d.ts +64 -61
  101. package/solid/index.d.ts.map +1 -0
  102. package/solid/index.js +60 -3
  103. package/tokens/d2.d.ts +38 -0
  104. package/tokens/d2.js +71 -0
  105. package/tokens/d2.json +43 -0
  106. package/tokens/index.d.ts +5 -5
  107. package/tokens/index.js +15 -1
  108. package/tokens/index.json +9 -0
  109. package/tokens/mermaid.d.ts +23 -0
  110. package/tokens/mermaid.js +181 -0
  111. package/tokens/mermaid.json +163 -0
  112. package/tokens/resolved.json +45 -1
  113. package/tokens/skins.js +3 -2
  114. package/tokens/tokens.dtcg.json +26 -0
  115. package/tokens/vega.d.ts +34 -0
  116. package/tokens/vega.js +155 -0
  117. package/tokens/vega.json +179 -0
package/css/report.css CHANGED
@@ -7,6 +7,9 @@
7
7
  ========================================================================== */
8
8
 
9
9
  .ui-report {
10
+ /* Declare override-surface tokens first so authors can set them. */
11
+ --report-width: 72rem;
12
+ --report-padding-block: var(--space-2xl);
10
13
  --report-gap: var(--space-lg);
11
14
  --report-measure: 74ch;
12
15
  --report-page-margin: 18mm;
@@ -14,9 +17,9 @@
14
17
  color: var(--text-soft);
15
18
  display: grid;
16
19
  gap: var(--report-gap);
17
- inline-size: min(100%, var(--report-width, 72rem));
20
+ inline-size: min(100%, var(--report-width));
18
21
  margin-inline: auto;
19
- padding: var(--report-padding-block, var(--space-2xl)) var(--space-md);
22
+ padding: var(--report-padding-block) var(--space-md);
20
23
  }
21
24
 
22
25
  .ui-report--compact {
@@ -42,7 +45,7 @@
42
45
  padding-block: var(--space-xl) var(--space-lg);
43
46
  }
44
47
 
45
- .ui-report__header {
48
+ .ui-report__head {
46
49
  align-items: end;
47
50
  border-block-end: 1px solid var(--line);
48
51
  display: flex;
@@ -56,6 +59,7 @@
56
59
  color: var(--text);
57
60
  font-family: var(--display);
58
61
  font-size: calc(var(--text-xl) * 1.35);
62
+ font-weight: var(--display-weight-strong);
59
63
  letter-spacing: 0;
60
64
  line-height: 1.05;
61
65
  margin: 0;
@@ -171,6 +175,7 @@
171
175
  color: var(--text);
172
176
  font-family: var(--display);
173
177
  font-size: var(--text-xl);
178
+ font-weight: var(--display-weight);
174
179
  letter-spacing: 0;
175
180
  line-height: 1.1;
176
181
  margin: 0;
@@ -195,8 +200,7 @@
195
200
  margin: 0;
196
201
  }
197
202
 
198
- .ui-report__caption,
199
- .ui-chart__caption {
203
+ .ui-report__caption {
200
204
  color: var(--text-dim);
201
205
  font-family: var(--mono);
202
206
  font-size: var(--text-2xs);
@@ -216,64 +220,47 @@
216
220
  padding-block-start: var(--space-md);
217
221
  }
218
222
 
219
- .ui-chart {
220
- border: 1px solid var(--line);
221
- border-radius: var(--radius-md);
222
- display: grid;
223
- gap: var(--space-sm);
224
- padding: var(--space-md);
225
- }
226
-
227
- /* The chart's data key lives in the standalone, portable `.ui-legend`
228
- (css/legend.css), not here — import it beside this kit when a chart needs
229
- a legend. The chart owns only its plot + bars + fallback below. */
230
- .ui-chart__plot {
223
+ /* --- Comparison layout ---
224
+ The report layer's "A vs B" / before-after grid — the side-by-side layout
225
+ reports lean on that the grammar was missing. Fluid-first: columns wrap to
226
+ a single stack on a narrow screen via auto-fit, so two panels never
227
+ overflow. `ui-compare__col` is one side, `ui-compare__head` labels it.
228
+ `ui-compare--2up` pins exactly two equal columns for a hard before/after
229
+ pairing (still collapsing to one column on a phone). */
230
+ .ui-compare {
231
231
  display: grid;
232
- gap: var(--space-xs);
232
+ gap: var(--space-md);
233
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
233
234
  }
234
235
 
235
- .ui-chart__bar {
236
- --chart-value: 0%;
237
-
238
- display: grid;
239
- gap: 0.35rem;
236
+ .ui-compare--2up {
237
+ grid-template-columns: repeat(2, minmax(0, 1fr));
240
238
  }
241
239
 
242
- /* An author `display` outranks the UA `[hidden]` rule, so re-assert it: a host
243
- toggling a series (e.g. from a `bronto:legend:toggle` event) expects
244
- `bar.hidden = true` to actually hide the bar. */
245
- .ui-chart__bar[hidden] {
246
- display: none;
240
+ @media (max-width: 33rem) {
241
+ .ui-compare--2up {
242
+ grid-template-columns: 1fr;
243
+ }
247
244
  }
248
245
 
249
- .ui-chart__label {
250
- align-items: center;
251
- color: var(--text-soft);
252
- display: flex;
253
- font-family: var(--mono);
254
- font-size: var(--text-xs);
246
+ .ui-compare__col {
247
+ align-content: start;
248
+ display: grid;
255
249
  gap: var(--space-sm);
256
- justify-content: space-between;
257
- }
258
-
259
- .ui-chart__track {
260
- background: var(--panel-soft);
261
- border: 1px solid var(--line);
262
- block-size: 0.8rem;
263
- min-inline-size: 0;
264
250
  }
265
251
 
266
- .ui-chart__fill {
267
- background: var(--chart-color, var(--chart-1, var(--accent)));
268
- background-image: var(--chart-pattern, var(--chart-pattern-1, none));
269
- background-size: var(--chart-pattern-size, 8px);
270
- block-size: 100%;
271
- inline-size: clamp(0%, var(--chart-value), 100%);
252
+ .ui-compare__head {
253
+ color: var(--text-dim);
254
+ font-family: var(--mono);
255
+ font-size: var(--text-2xs);
256
+ letter-spacing: var(--tracking-wide);
257
+ text-transform: uppercase;
272
258
  }
273
259
 
274
- .ui-chart__fallback {
275
- margin-block-start: var(--space-sm);
276
- }
260
+ /* A chart is NOT a bronto component — it needs scales + data binding, which the
261
+ analytical layer refuses to own. Theme Vega-Lite with `@ponchia/ui/vega`
262
+ (docs/vega.md), or hand-author a token-themed inline `<svg>`, and drop it in a
263
+ `.ui-report__figure` with a `.ui-report__caption` + a `.ui-legend` key. */
277
264
 
278
265
  .ui-print-only {
279
266
  display: none !important;
@@ -313,27 +300,17 @@
313
300
  padding: 0;
314
301
  }
315
302
 
316
- /* Meaning-carrying chart fills must survive the print "economy" default
317
- (which drops backgrounds) without relying on a `.ui-print-exact`
318
- ancestor. The accent on `.ui-report__summary` is a border, so it already
319
- prints. (Legend swatches print-protect themselves in css/legend.css.) */
320
- .ui-chart__fill {
321
- -webkit-print-color-adjust: exact;
322
- print-color-adjust: exact;
323
- }
324
-
325
303
  .ui-report__cover {
326
304
  min-block-size: auto;
327
305
  }
328
306
 
329
307
  .ui-report__cover,
330
- .ui-report__header,
308
+ .ui-report__head,
331
309
  .ui-report__section,
332
310
  .ui-report__summary,
333
311
  .ui-report__finding,
334
312
  .ui-report__evidence,
335
- .ui-report__figure,
336
- .ui-chart {
313
+ .ui-report__figure {
337
314
  break-inside: avoid;
338
315
  }
339
316
 
package/css/site.css CHANGED
@@ -162,11 +162,11 @@
162
162
  transform var(--duration-fast) var(--ease-spring);
163
163
  }
164
164
 
165
- .ui-sitenav a[aria-current] {
165
+ .ui-sitenav a[aria-current]:not([aria-current='false']) {
166
166
  color: var(--accent-text);
167
167
  }
168
168
 
169
- .ui-sitenav a[aria-current]::before {
169
+ .ui-sitenav a[aria-current]:not([aria-current='false'])::before {
170
170
  opacity: 1;
171
171
  transform: scale(1);
172
172
  }
@@ -182,6 +182,13 @@
182
182
  }
183
183
  }
184
184
 
185
+ @media (pointer: coarse) {
186
+ .ui-sitenav a {
187
+ min-block-size: 2.9rem;
188
+ padding-inline: 0.9rem;
189
+ }
190
+ }
191
+
185
192
  /* --- Mobile menu — native <details>, no JS required --- */
186
193
 
187
194
  .ui-sitemenu {
@@ -247,6 +254,13 @@
247
254
  }
248
255
  }
249
256
 
257
+ @media (pointer: coarse) {
258
+ .ui-sitemenu > summary {
259
+ min-block-size: 2.9rem;
260
+ padding-inline: 0.9rem;
261
+ }
262
+ }
263
+
250
264
  /* --- Footer --- */
251
265
 
252
266
  .ui-sitefooter {
package/css/sources.css CHANGED
@@ -19,6 +19,37 @@
19
19
  --src-tone: var(--text-dim);
20
20
  }
21
21
 
22
+ /* Standalone trust pill — wears a `.ui-src--*` tone on its own, for a bare
23
+ "verified" / "stale" label outside a citation or source card (the tone setters
24
+ below only paint a `--src-tone` custom property, so without this host a lone
25
+ `.ui-src--verified` validates against classes.json yet renders nothing). Tone
26
+ is a leading dot + a tinted border AND the author's written label, never colour
27
+ alone (WCAG 1.4.1). Declared before the `--*` setters so their tone wins. */
28
+ .ui-src {
29
+ --src-tone: var(--text-dim);
30
+
31
+ align-items: center;
32
+ background: var(--panel-soft);
33
+ border: 1px solid color-mix(in srgb, var(--src-tone) 45%, var(--line));
34
+ border-radius: var(--radius-pill);
35
+ color: var(--text-soft);
36
+ display: inline-flex;
37
+ font-size: var(--text-2xs);
38
+ gap: 0.35rem;
39
+ padding: 0.08rem 0.55rem;
40
+ vertical-align: baseline;
41
+ }
42
+
43
+ .ui-src::before {
44
+ background: var(--src-tone);
45
+ border-radius: 50%;
46
+ block-size: 0.45rem;
47
+ content: '';
48
+ flex: none;
49
+ inline-size: 0.45rem;
50
+ print-color-adjust: exact;
51
+ }
52
+
22
53
  .ui-src--verified {
23
54
  --src-tone: var(--success);
24
55
  }
@@ -169,7 +200,8 @@
169
200
  1.4.1). Keep the marks visible as CanvasText rather than letting them vanish. */
170
201
  @media (forced-colors: active) {
171
202
  .ui-citation--chip::before,
172
- .ui-provenance__item::before {
203
+ .ui-provenance__item::before,
204
+ .ui-src::before {
173
205
  background: CanvasText;
174
206
  }
175
207
 
@@ -177,3 +209,13 @@
177
209
  border-inline-start-color: CanvasText;
178
210
  }
179
211
  }
212
+
213
+ /* Print: an inline citation marker points into the references list, so never
214
+ expand its href inline. base.css expands `.ui-prose a[href^="http"]` with a
215
+ trailing "(url)"; on a superscript marker that dumps a full URL mid-sentence.
216
+ !important + print-scoped because base's rule is more specific. */
217
+ @media print {
218
+ .ui-citation[href]::after {
219
+ content: none !important;
220
+ }
221
+ }
package/css/spotlight.css CHANGED
@@ -66,7 +66,7 @@
66
66
  color: var(--text);
67
67
  display: grid;
68
68
  gap: var(--space-sm);
69
- max-inline-size: 22rem;
69
+ max-inline-size: min(22rem, calc(100vw - 2rem));
70
70
  padding: var(--space-md);
71
71
  pointer-events: auto;
72
72
  }
package/css/tokens.css CHANGED
@@ -3,7 +3,7 @@
3
3
  Single source of truth: tokens/index.js (`cssVars`). Edit token VALUES
4
4
  there, then run `npm run tokens:css:build`. The four :root blocks below are
5
5
  emitted from cssVars — the dark palette is authored ONCE (not the former two
6
- CSS blocks + the JS mirror). check-tokens.mjs gates this file against cssVars.
6
+ CSS blocks + the JS mirror). Drift-checked by `npm run check:fresh` (scripts/check-fresh.mjs).
7
7
  The Doto @font-face lives in fonts.css; override --display / --dot-font to
8
8
  self-host. CSS-only presets (density / contrast / OLED) are hand-authored
9
9
  below the marker — they are intentionally not part of the JS token model.
@@ -31,6 +31,8 @@
31
31
  --sans: 'Inter', 'SF Pro Text', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
32
32
  --dot-font: 'Doto', var(--mono);
33
33
  --display: var(--dot-font);
34
+ --display-weight: 700;
35
+ --display-weight-strong: 800;
34
36
  --text-2xs: 0.68rem;
35
37
  --text-xs: 0.76rem;
36
38
  --text-sm: 0.86rem;
@@ -122,6 +124,7 @@
122
124
  --accent-ramp-end: #ffffff;
123
125
  --accent-strong: color-mix(in srgb, var(--accent) 83%, #000);
124
126
  --accent-text: var(--accent-strong);
127
+ --on-accent: var(--button-text);
125
128
  --accent-soft: color-mix(in srgb, var(--accent) 10%, transparent);
126
129
  --success: #2f7d4f;
127
130
  --success-soft: rgb(47, 125, 79, 0.12);
@@ -165,6 +168,7 @@
165
168
  --accent-ramp-end: #000000;
166
169
  --accent-strong: color-mix(in srgb, var(--accent) 84%, #fff);
167
170
  --accent-text: var(--accent-strong);
171
+ --on-accent: var(--button-text);
168
172
  --accent-soft: color-mix(in srgb, var(--accent) 14%, transparent);
169
173
  --success: #4ec27e;
170
174
  --success-soft: rgb(78, 194, 126, 0.14);
@@ -203,6 +207,7 @@
203
207
  --accent-ramp-end: #000000;
204
208
  --accent-strong: color-mix(in srgb, var(--accent) 84%, #fff);
205
209
  --accent-text: var(--accent-strong);
210
+ --on-accent: var(--button-text);
206
211
  --accent-soft: color-mix(in srgb, var(--accent) 14%, transparent);
207
212
  --success: #4ec27e;
208
213
  --success-soft: rgb(78, 194, 126, 0.14);
@@ -311,3 +316,33 @@
311
316
  --panel-soft: #1a1a1a;
312
317
  }
313
318
  }
319
+
320
+ /* --------------------------------------------------------------------------
321
+ Print — force an ink-on-white document regardless of the on-screen theme.
322
+ The palette tokens are [data-theme]-scoped raw values, so `color-scheme`
323
+ alone can't flip them: re-point the neutrals to achromatic ink/paper and the
324
+ status/accent hues to their light-theme (print-legible) values. This lifts
325
+ the same remap report.css scopes to `.ui-report` up to :root, so a bare
326
+ .ui-card / .ui-statgrid / .ui-table (the markup an external LLM emits) also
327
+ prints dark-on-white instead of light-grey text or a dark panel on white.
328
+ Lives here, in the exempt tier-definition file, because it is a token-value
329
+ override (ADR-0001), not component styling. CSS-only, like the presets above.
330
+ -------------------------------------------------------------------------- */
331
+ @media print {
332
+ :root {
333
+ color-scheme: light;
334
+
335
+ --text: #111;
336
+ --text-soft: #2a2a2a;
337
+ --text-dim: #555;
338
+ --panel: #fff;
339
+ --panel-soft: #f7f7f7;
340
+ --line: #d9d9d9;
341
+ --line-strong: #b3b3b3;
342
+ --success: #2f7d4f;
343
+ --danger: #c01622;
344
+ --warning: #806414;
345
+ --info: #1f63c4;
346
+ --accent: #d71921;
347
+ }
348
+ }
package/css/workbench.css CHANGED
@@ -19,7 +19,7 @@
19
19
  padding: var(--space-md);
20
20
  }
21
21
 
22
- .ui-inspector__header {
22
+ .ui-inspector__head {
23
23
  align-items: baseline;
24
24
  border-block-end: 1px solid var(--line);
25
25
  display: flex;