@adia-ai/web-components 0.6.50 → 0.7.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 +134 -0
- package/components/action-list/action-list.css +1 -1
- package/components/agent-artifact/agent-artifact.class.js +10 -10
- package/components/agent-artifact/agent-artifact.css +1 -1
- package/components/agent-reasoning/agent-reasoning.class.js +51 -0
- package/components/agent-reasoning/agent-reasoning.css +49 -22
- package/components/alert/alert.class.js +8 -1
- package/components/alert/alert.css +13 -1
- package/components/avatar/avatar.a2ui.json +2 -14
- package/components/avatar/avatar.class.js +3 -15
- package/components/avatar/avatar.d.ts +2 -4
- package/components/avatar/avatar.yaml +1 -18
- package/components/breadcrumb/breadcrumb.css +4 -1
- package/components/button/button.a2ui.json +3 -0
- package/components/button/button.css +14 -3
- package/components/button/button.yaml +5 -0
- package/components/calendar-grid/calendar-grid.css +1 -1
- package/components/calendar-picker/calendar-picker.css +5 -2
- package/components/chart/chart.a2ui.json +0 -18
- package/components/chart/chart.class.js +8 -50
- package/components/chart/chart.css +1 -15
- package/components/chart/chart.d.ts +0 -4
- package/components/chart/chart.yaml +0 -24
- package/components/color-input/color-input.css +4 -1
- package/components/combobox/combobox.class.js +11 -0
- package/components/combobox/combobox.css +8 -0
- package/components/date-range-picker/date-range-picker.class.js +5 -1
- package/components/date-range-picker/date-range-picker.css +12 -2
- package/components/datetime-picker/datetime-picker.class.js +3 -0
- package/components/datetime-picker/datetime-picker.css +16 -2
- package/components/empty-state/empty-state.css +11 -4
- package/components/field/field.css +17 -6
- package/components/grid/grid.a2ui.json +5 -0
- package/components/grid/grid.class.js +16 -6
- package/components/grid/grid.css +17 -3
- package/components/grid/grid.d.ts +2 -0
- package/components/grid/grid.yaml +9 -0
- package/components/heatmap/heatmap.class.js +9 -3
- package/components/heatmap/heatmap.css +19 -2
- package/components/image/image.css +4 -1
- package/components/input/input.class.js +38 -0
- package/components/input/input.css +9 -5
- package/components/input/input.test.js +57 -0
- package/components/integration-card/integration-card.class.js +31 -7
- package/components/integration-card/integration-card.test.js +12 -1
- package/components/kbd/kbd.a2ui.json +3 -2
- package/components/kbd/kbd.css +7 -4
- package/components/kbd/kbd.d.ts +2 -2
- package/components/kbd/kbd.yaml +2 -1
- package/components/list/list.class.js +8 -1
- package/components/menu/menu.class.js +12 -3
- package/components/menu/menu.css +4 -1
- package/components/menu/menu.test.js +130 -0
- package/components/modal/modal.class.js +10 -1
- package/components/modal/modal.css +9 -0
- package/components/option-card/option-card.a2ui.json +3 -0
- package/components/option-card/option-card.css +44 -19
- package/components/option-card/option-card.yaml +5 -0
- package/components/otp-input/otp-input.css +25 -10
- package/components/page/page.css +64 -11
- package/components/pagination/pagination.class.js +1 -1
- package/components/pagination/pagination.css +9 -1
- package/components/pipeline-status/pipeline-status.css +6 -0
- package/components/popover/popover.css +12 -1
- package/components/preview/preview.css +30 -3
- package/components/progress-row/progress-row.css +3 -1
- package/components/qr-code/qr-code.css +4 -1
- package/components/segmented/segmented.css +4 -1
- package/components/select/select.a2ui.json +1 -1
- package/components/select/select.class.js +63 -7
- package/components/select/select.css +18 -0
- package/components/select/select.yaml +9 -2
- package/components/stack/stack.a2ui.json +12 -1
- package/components/stack/stack.d.ts +2 -2
- package/components/stack/stack.yaml +13 -1
- package/components/stat/stat.a2ui.json +5 -0
- package/components/stat/stat.css +55 -0
- package/components/stat/stat.d.ts +2 -0
- package/components/stat/stat.js +4 -0
- package/components/stat/stat.yaml +9 -0
- package/components/swiper/swiper.class.js +14 -6
- package/components/switch/switch.css +13 -0
- package/components/table/table.a2ui.json +2 -2
- package/components/table/table.css +13 -1
- package/components/table/table.yaml +2 -2
- package/components/time-picker/time-picker.css +4 -1
- package/components/timeline/timeline.class.js +3 -3
- package/components/timeline/timeline.css +23 -5
- package/components/toggle-group/toggle-group.css +4 -1
- package/components/toggle-scheme/toggle-scheme.css +4 -1
- package/components/tree/tree.class.js +24 -4
- package/components/tree/tree.test.js +108 -0
- package/dist/web-components.min.css +1 -1
- package/dist/web-components.min.js +83 -83
- package/package.json +3 -3
- package/styles/api/layout.css +7 -0
- package/styles/api/text.css +9 -5
- package/styles/index.css +11 -2
- package/styles/prose.css +8 -0
- package/styles/resets.css +5 -5
- package/styles/themes.css +8 -1
- package/styles/tokens.css +3 -3
- package/styles/type/elements.css +73 -0
- package/styles/type/roles.css +14 -49
- package/styles/type/scale.css +0 -5
- package/styles/typography.css +3 -3
|
@@ -25,12 +25,15 @@
|
|
|
25
25
|
|
|
26
26
|
:scope {
|
|
27
27
|
box-sizing: border-box;
|
|
28
|
-
display:
|
|
28
|
+
display: flex;
|
|
29
29
|
align-items: center;
|
|
30
30
|
gap: var(--breadcrumb-gap, var(--breadcrumb-gap-default));
|
|
31
31
|
font-size: var(--breadcrumb-font-size, var(--breadcrumb-font-size-default));
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
/* Display convention (ADR-0037): block-level by default; [inline] opts back to inline-level. */
|
|
35
|
+
:scope[inline] { display: inline-flex; }
|
|
36
|
+
|
|
34
37
|
/* Separator — standalone span, never inside <a> */
|
|
35
38
|
[data-sep] {
|
|
36
39
|
color: var(--breadcrumb-separator-fg, var(--breadcrumb-separator-fg-default));
|
|
@@ -131,6 +131,9 @@
|
|
|
131
131
|
"Link"
|
|
132
132
|
],
|
|
133
133
|
"slots": {
|
|
134
|
+
"icon-trailing": {
|
|
135
|
+
"description": "Trailing icon, after the label. Stamped from the `icon-trailing` prop, or slot a custom `<icon-ui slot=\"icon-trailing\">` directly (the consumer's element wins over the prop-stamped one). Sized to --content-height."
|
|
136
|
+
},
|
|
134
137
|
"leading": {
|
|
135
138
|
"description": "Icon container (start), sized to --content-height"
|
|
136
139
|
},
|
|
@@ -72,15 +72,19 @@ button-ui[color="danger"]:not([disabled]):hover {
|
|
|
72
72
|
|
|
73
73
|
/* ── Trailing slot ── */
|
|
74
74
|
--button-trailing-font-size-default: var(--a-ui-sm);
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
/* kbd-pill tracks the button's OWN text color (currentColor) so it reads
|
|
76
|
+
on any variant fill — on a primary button the fixed --a-fg-muted gray
|
|
77
|
+
was nearly invisible against the white label. Border is a translucent
|
|
78
|
+
slice of the same color so the pill outline adapts too. */
|
|
79
|
+
--button-trailing-fg-default: currentColor;
|
|
80
|
+
--button-trailing-border-default: color-mix(in oklab, currentColor 28%, transparent);
|
|
77
81
|
--button-trailing-radius-default: var(--a-radius-sm);
|
|
78
82
|
--button-trailing-px-default: var(--a-space-0-5);
|
|
79
83
|
}
|
|
80
84
|
|
|
81
85
|
:scope {
|
|
82
86
|
box-sizing: border-box;
|
|
83
|
-
display:
|
|
87
|
+
display: flex;
|
|
84
88
|
align-items: center;
|
|
85
89
|
justify-content: center;
|
|
86
90
|
gap: var(--button-gap, var(--button-gap-default));
|
|
@@ -113,6 +117,13 @@ button-ui[color="danger"]:not([disabled]):hover {
|
|
|
113
117
|
min-width: 0;
|
|
114
118
|
}
|
|
115
119
|
|
|
120
|
+
/* Display convention (ADR-0037): block-level by default — a text button used
|
|
121
|
+
directly in block flow fills its container. Icon-only buttons (no [text])
|
|
122
|
+
stay inline-level, and [inline] forces inline for any button. Inside
|
|
123
|
+
row-ui/col-ui/grid-ui this is moot (flex/grid items are blockified). */
|
|
124
|
+
:scope:not([text]) { display: inline-flex; }
|
|
125
|
+
:scope[inline] { display: inline-flex; }
|
|
126
|
+
|
|
116
127
|
/* Trailing icon slot — for forward-affordance carets ("Next →"), distinct
|
|
117
128
|
from `[slot="trailing"]` which is styled as a kbd-pill for shortcut
|
|
118
129
|
indicators. Auto-stamped when `[icon-trailing]` is set. */
|
|
@@ -103,6 +103,11 @@ slots:
|
|
|
103
103
|
description: Icon container (start), sized to --content-height
|
|
104
104
|
trailing:
|
|
105
105
|
description: Icon container (end), sized to --content-height
|
|
106
|
+
icon-trailing:
|
|
107
|
+
description: >-
|
|
108
|
+
Trailing icon, after the label. Stamped from the `icon-trailing` prop, or
|
|
109
|
+
slot a custom `<icon-ui slot="icon-trailing">` directly (the consumer's
|
|
110
|
+
element wins over the prop-stamped one). Sized to --content-height.
|
|
106
111
|
states:
|
|
107
112
|
- name: idle
|
|
108
113
|
description: Default, ready for interaction.
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
|
|
32
32
|
/* Nav buttons (prev/next) — secondary chrome at one notch below the
|
|
33
33
|
control height (mirrors select's `calc(height - gap)` idiom); icon
|
|
34
|
-
is a directional
|
|
34
|
+
is a directional caret sized from the universal --a-caret-size. */
|
|
35
35
|
--calendar-grid-nav-size-default: calc(var(--a-size) - var(--a-space-2));
|
|
36
36
|
--calendar-grid-nav-radius-default: var(--a-radius-sm);
|
|
37
37
|
--calendar-grid-nav-bg-default: transparent;
|
|
@@ -16,7 +16,10 @@
|
|
|
16
16
|
--calendar-picker-trigger-radius-default: var(--a-radius);
|
|
17
17
|
--calendar-picker-trigger-bg-default: var(--a-ui-bg);
|
|
18
18
|
--calendar-picker-trigger-bg-hover-default: var(--a-ui-bg-hover);
|
|
19
|
-
|
|
19
|
+
/* Committed value reads at full text strength (matches input-ui / select-ui
|
|
20
|
+
value color); the placeholder state drops to -placeholder below via the
|
|
21
|
+
:not([value]) override. Was -subtle, which muted the committed date. (bug-15/16) */
|
|
22
|
+
--calendar-picker-trigger-fg-default: var(--a-ui-text);
|
|
20
23
|
--calendar-picker-trigger-border-default: var(--a-ui-border);
|
|
21
24
|
--calendar-picker-trigger-border-hover-default: var(--a-ui-border-hover);
|
|
22
25
|
--calendar-picker-trigger-focus-ring-default: var(--a-focus-ring);
|
|
@@ -45,7 +48,7 @@
|
|
|
45
48
|
|
|
46
49
|
/* Nav buttons (prev/next) — secondary chrome at one notch below the
|
|
47
50
|
control height (mirrors select's `calc(height - gap)` idiom); icon
|
|
48
|
-
is a directional
|
|
51
|
+
is a directional caret sized from the universal --a-caret-size. */
|
|
49
52
|
--calendar-picker-nav-size-default: calc(var(--a-size) - var(--a-space-2));
|
|
50
53
|
--calendar-picker-nav-radius-default: var(--a-radius-sm);
|
|
51
54
|
--calendar-picker-nav-bg-default: transparent;
|
|
@@ -38,18 +38,6 @@
|
|
|
38
38
|
],
|
|
39
39
|
"default": "bar"
|
|
40
40
|
},
|
|
41
|
-
"aspect": {
|
|
42
|
-
"description": "DEPRECATED (OD-CHART-02). Parents should size the chart directly (width/height on the enclosing card or container). Still honored for back-compat; emits a one-shot console.warn per instance when set.",
|
|
43
|
-
"type": "string",
|
|
44
|
-
"enum": [
|
|
45
|
-
"std",
|
|
46
|
-
"wide",
|
|
47
|
-
"square",
|
|
48
|
-
"tall"
|
|
49
|
-
],
|
|
50
|
-
"default": "std",
|
|
51
|
-
"deprecated": true
|
|
52
|
-
},
|
|
53
41
|
"color": {
|
|
54
42
|
"description": "Color scheme",
|
|
55
43
|
"type": "string",
|
|
@@ -81,12 +69,6 @@
|
|
|
81
69
|
],
|
|
82
70
|
"default": "abbr"
|
|
83
71
|
},
|
|
84
|
-
"heading": {
|
|
85
|
-
"description": "DEPRECATED (OD-CHART-02). Place chart titles in an enclosing card-ui's `<header><span slot=\"heading\">...</span></header>` instead. Still honored for back-compat; emits a one-shot console.warn per instance when set. Used as the chart's `aria-label` when no explicit label is provided.",
|
|
86
|
-
"type": "string",
|
|
87
|
-
"default": "",
|
|
88
|
-
"deprecated": true
|
|
89
|
-
},
|
|
90
72
|
"hideAverage": {
|
|
91
73
|
"description": "When true, suppress the overlaid average line",
|
|
92
74
|
"type": "boolean",
|
|
@@ -12,14 +12,13 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* <chart-ui type="bar" x="month" y="revenue"
|
|
15
|
+
* <chart-ui type="bar" x="month" y="revenue"></chart-ui>
|
|
16
16
|
*
|
|
17
17
|
* Declarative chart component supporting bar, line, pie, donut, radar,
|
|
18
18
|
* sparkline, stacked-bar, grouped-bar, and multi-line chart types.
|
|
19
19
|
*
|
|
20
20
|
* Attributes:
|
|
21
21
|
* type — chart type (default: 'bar')
|
|
22
|
-
* heading — chart heading text
|
|
23
22
|
* x — key for X-axis data
|
|
24
23
|
* y — key(s) for Y-axis, comma-separated for multi-series
|
|
25
24
|
* hide-average — suppress the overlaid average line on bar/line (default: false — line shown)
|
|
@@ -202,19 +201,16 @@ function topRoundedBarPath(x, y, w, h, r = 0) {
|
|
|
202
201
|
|
|
203
202
|
/* ── Aspect ratios ─────────────────────────────────────────────── */
|
|
204
203
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
tall: { ratio: 3 / 4 }, // vertical column
|
|
210
|
-
};
|
|
204
|
+
// Implicit aspect ratio — a chart derives its height from width ÷ this ratio when
|
|
205
|
+
// no explicit height is set. The per-chart [aspect] attribute (std/wide/square/tall)
|
|
206
|
+
// was retired (OD-CHART-02); parents size charts directly now.
|
|
207
|
+
const ASPECTS = { std: { ratio: 4 / 3 } };
|
|
211
208
|
|
|
212
209
|
/* ── Component ──────────────────────────────────────────────────── */
|
|
213
210
|
|
|
214
211
|
export class UIChart extends UIElement {
|
|
215
212
|
static properties = {
|
|
216
213
|
type: { type: String, default: 'bar', reflect: true },
|
|
217
|
-
heading: { type: String, default: '', reflect: true },
|
|
218
214
|
x: { type: String, default: '', reflect: true },
|
|
219
215
|
y: { type: String, default: '', reflect: true },
|
|
220
216
|
hideAverage: { type: Boolean, default: false, reflect: true, attribute: 'hide-average' },
|
|
@@ -223,7 +219,6 @@ export class UIChart extends UIElement {
|
|
|
223
219
|
hideValues: { type: Boolean, default: false, reflect: true, attribute: 'hide-values' },
|
|
224
220
|
radius: { type: Number, default: null, reflect: true },
|
|
225
221
|
smooth: { type: Number, default: 0.4, reflect: true },
|
|
226
|
-
aspect: { type: String, default: 'std', reflect: true },
|
|
227
222
|
size: { type: String, default: '', reflect: true },
|
|
228
223
|
format: { type: String, default: 'abbr', reflect: true },
|
|
229
224
|
loading: { type: Boolean, default: false, reflect: true },
|
|
@@ -304,7 +299,7 @@ export class UIChart extends UIElement {
|
|
|
304
299
|
|
|
305
300
|
connected() {
|
|
306
301
|
if (!this.hasAttribute('role')) this.setAttribute('role', 'img');
|
|
307
|
-
if (!this.hasAttribute('aria-label')) this.setAttribute('aria-label',
|
|
302
|
+
if (!this.hasAttribute('aria-label')) this.setAttribute('aria-label', `${this.type} chart`);
|
|
308
303
|
|
|
309
304
|
/* Hydrate from inline `data="[…]"` HTML attribute. The canonical
|
|
310
305
|
entry point is the `.data` property (set programmatically), but
|
|
@@ -332,9 +327,7 @@ export class UIChart extends UIElement {
|
|
|
332
327
|
move a virtual focus across datums in DOM order, Enter/Space fires
|
|
333
328
|
chart-select, Escape clears focus. Per-datum focus dispatches the
|
|
334
329
|
same chart-hover event the pointer path uses, so tooltip-ui[for]
|
|
335
|
-
tracks keyboard focus transparently.
|
|
336
|
-
Deprecation warnings for `aspect=` and `heading=` also fire here
|
|
337
|
-
per OD-CHART-02 — one-shot per instance to keep the console clean. */
|
|
330
|
+
tracks keyboard focus transparently. */
|
|
338
331
|
if (!this.hasAttribute('tabindex')) this.setAttribute('tabindex', '0');
|
|
339
332
|
this.addEventListener('keydown', this.#onKeydown);
|
|
340
333
|
this.addEventListener('focus', this.#onFocus);
|
|
@@ -347,7 +340,6 @@ export class UIChart extends UIElement {
|
|
|
347
340
|
this.addEventListener('pointerleave', this.#onPointerLeave);
|
|
348
341
|
this.addEventListener('pointerdown', this.#onPointerDown);
|
|
349
342
|
this.addEventListener('click', this.#onClick);
|
|
350
|
-
this.#warnDeprecatedAttrs();
|
|
351
343
|
|
|
352
344
|
this.#resizeObs = new ResizeObserver((entries) => {
|
|
353
345
|
const { inlineSize: w, blockSize: h } = entries[0].contentBoxSize[0];
|
|
@@ -394,7 +386,7 @@ export class UIChart extends UIElement {
|
|
|
394
386
|
#dims() {
|
|
395
387
|
const containerW = this.clientWidth || 300;
|
|
396
388
|
const containerH = this.clientHeight || 0;
|
|
397
|
-
const aspect = ASPECTS
|
|
389
|
+
const aspect = ASPECTS.std;
|
|
398
390
|
const n = this.#data.length || 1;
|
|
399
391
|
|
|
400
392
|
const width = Math.max(containerW, 120);
|
|
@@ -470,13 +462,6 @@ export class UIChart extends UIElement {
|
|
|
470
462
|
|
|
471
463
|
this.#injectSeriesColors();
|
|
472
464
|
|
|
473
|
-
if (this.heading) {
|
|
474
|
-
const headingEl = document.createElement('div');
|
|
475
|
-
headingEl.setAttribute('data-chart-heading', '');
|
|
476
|
-
headingEl.textContent = this.heading;
|
|
477
|
-
this.appendChild(headingEl);
|
|
478
|
-
}
|
|
479
|
-
|
|
480
465
|
const svgWrap = document.createElement('div');
|
|
481
466
|
if (this.type === 'sparkline') svgWrap.setAttribute('data-sparkline', '');
|
|
482
467
|
this.appendChild(svgWrap);
|
|
@@ -609,33 +594,6 @@ export class UIChart extends UIElement {
|
|
|
609
594
|
return !!key && this.#hiddenSeriesKeys.has(key);
|
|
610
595
|
}
|
|
611
596
|
|
|
612
|
-
/* ── Deprecation warnings (OD-CHART-02) ─────────────────────────
|
|
613
|
-
`aspect=` and `heading=` were part of the pre-composition model —
|
|
614
|
-
`aspect` is stale because parents now size the chart; `heading`
|
|
615
|
-
because card headers are the semantic location for chart titles.
|
|
616
|
-
Warn once per instance so the console stays readable. Attrs still
|
|
617
|
-
honored; removal planned for the next major. */
|
|
618
|
-
#deprecationWarned = false;
|
|
619
|
-
#warnDeprecatedAttrs() {
|
|
620
|
-
if (this.#deprecationWarned) return;
|
|
621
|
-
if (this.aspect && this.aspect !== 'std') {
|
|
622
|
-
console.warn(
|
|
623
|
-
`[chart-ui] aspect="${this.aspect}" is deprecated. ` +
|
|
624
|
-
`Parents should size the chart directly (width/height on the card ` +
|
|
625
|
-
`or container). The attribute will be removed in a future major.`
|
|
626
|
-
);
|
|
627
|
-
this.#deprecationWarned = true;
|
|
628
|
-
}
|
|
629
|
-
if (this.heading) {
|
|
630
|
-
console.warn(
|
|
631
|
-
`[chart-ui] heading="${this.heading}" is deprecated. ` +
|
|
632
|
-
`Place the title in an enclosing card-ui <header><span slot="heading"> ` +
|
|
633
|
-
`instead. The attribute will be removed in a future major.`
|
|
634
|
-
);
|
|
635
|
-
this.#deprecationWarned = true;
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
|
|
639
597
|
/* ── Number formatting (OD-CHART-03) ────────────────────────────
|
|
640
598
|
`format` attribute selects how datum values are displayed on axis
|
|
641
599
|
labels, bar/line value overlays, donut centers, etc. Falls back to
|
|
@@ -42,10 +42,6 @@
|
|
|
42
42
|
--chart-segments-gap-default: 2px;
|
|
43
43
|
--chart-pie-gap-default: 1.25px;
|
|
44
44
|
|
|
45
|
-
/* Heading */
|
|
46
|
-
--chart-heading-size-default: var(--a-ui-size);
|
|
47
|
-
--chart-heading-weight-default: var(--a-weight-medium);
|
|
48
|
-
|
|
49
45
|
/* Transitions */
|
|
50
46
|
--chart-duration-default: var(--a-duration-fast);
|
|
51
47
|
--chart-easing-default: var(--a-easing);
|
|
@@ -106,7 +102,6 @@
|
|
|
106
102
|
/* Title + legend are fixed-height siblings; SVG gets the remaining
|
|
107
103
|
vertical budget. min-height:0 lets the SVG wrapper shrink to fit
|
|
108
104
|
inside the max-height envelope instead of pushing the legend out. */
|
|
109
|
-
[data-chart-heading] { flex: 0 0 auto; }
|
|
110
105
|
[data-legend] { flex: 0 0 auto; }
|
|
111
106
|
|
|
112
107
|
/* Empty-state slot — author places <empty-state-ui slot="empty"> inside
|
|
@@ -121,7 +116,7 @@
|
|
|
121
116
|
min-height: 0;
|
|
122
117
|
}
|
|
123
118
|
|
|
124
|
-
:scope > div:not([data-
|
|
119
|
+
:scope > div:not([data-legend]) {
|
|
125
120
|
flex: 1 1 auto;
|
|
126
121
|
min-height: 0;
|
|
127
122
|
}
|
|
@@ -150,15 +145,6 @@
|
|
|
150
145
|
overflow: visible;
|
|
151
146
|
}
|
|
152
147
|
|
|
153
|
-
/* ── Heading ── */
|
|
154
|
-
|
|
155
|
-
[data-chart-heading] {
|
|
156
|
-
font-size: var(--chart-heading-size, var(--chart-heading-size-default));
|
|
157
|
-
font-weight: var(--chart-heading-weight, var(--chart-heading-weight-default));
|
|
158
|
-
color: var(--chart-fg, var(--chart-fg-default));
|
|
159
|
-
margin-bottom: var(--chart-space-md, var(--chart-space-md-default));
|
|
160
|
-
}
|
|
161
|
-
|
|
162
148
|
/* ── Grid lines ── */
|
|
163
149
|
|
|
164
150
|
[data-grid] {
|
|
@@ -20,16 +20,12 @@ export type ChartLegendUpdateEvent = CustomEvent<unknown>;
|
|
|
20
20
|
export class UIChart extends UIElement {
|
|
21
21
|
/** Chart type. All 18 enum values have dedicated render paths in chart.js. */
|
|
22
22
|
type: 'bar' | 'line' | 'pie' | 'donut' | 'radar' | 'sparkline' | 'segments' | 'area' | 'scatter' | 'radial-bar' | 'gauge' | 'stacked-bar' | 'grouped-bar' | 'multi-line' | 'funnel' | 'treemap' | 'sankey' | 'composed';
|
|
23
|
-
/** DEPRECATED (OD-CHART-02). Parents should size the chart directly (width/height on the enclosing card or container). Still honored for back-compat; emits a one-shot console.warn per instance when set. */
|
|
24
|
-
aspect: 'std' | 'wide' | 'square' | 'tall';
|
|
25
23
|
/** Color scheme */
|
|
26
24
|
color: 'accent' | 'success' | 'warning' | 'danger' | 'info';
|
|
27
25
|
/** JS property (set programmatically — `el.data = [...]`). An array of plain objects; each object's keys are named by the `x` and `y` attributes — e.g. `<chart-ui x="month" y="revenue">` consumes `[{month:'Jan', revenue:3200}, {month:'Feb', revenue:4100}]`. The Chart.js `{labels, datasets}` envelope is NOT chart-ui's API — passing it (or any non-array value) renders an empty chart. May also be supplied declaratively as a JSON-array `data="[…]"` attribute, hydrated once at connect. Custom accessor on the element class, not a reflected attribute. */
|
|
28
26
|
data: unknown[];
|
|
29
27
|
/** Number-format mode applied to axis labels + value overlays + donut total + gauge value + treemap value + funnel value + internal tooltip. `abbr` is the legacy 1.2K / 3M format; `decimal` fixes 2 decimals; `currency` prefixes via `--chart-currency-prefix` token (default "$"); `percent` multiplies × 100 and adds a % suffix. */
|
|
30
28
|
format: 'abbr' | 'decimal' | 'currency' | 'percent';
|
|
31
|
-
/** DEPRECATED (OD-CHART-02). Place chart titles in an enclosing card-ui's `<header><span slot="heading">...</span></header>` instead. Still honored for back-compat; emits a one-shot console.warn per instance when set. Used as the chart's `aria-label` when no explicit label is provided. */
|
|
32
|
-
heading: string;
|
|
33
29
|
/** When true, suppress the overlaid average line */
|
|
34
30
|
hideAverage: boolean;
|
|
35
31
|
/** Hide gridlines */
|
|
@@ -36,19 +36,6 @@ props:
|
|
|
36
36
|
- treemap
|
|
37
37
|
- sankey
|
|
38
38
|
- composed
|
|
39
|
-
aspect:
|
|
40
|
-
description: >-
|
|
41
|
-
DEPRECATED (OD-CHART-02). Parents should size the chart directly
|
|
42
|
-
(width/height on the enclosing card or container). Still honored for
|
|
43
|
-
back-compat; emits a one-shot console.warn per instance when set.
|
|
44
|
-
type: string
|
|
45
|
-
default: std
|
|
46
|
-
enum:
|
|
47
|
-
- std
|
|
48
|
-
- wide
|
|
49
|
-
- square
|
|
50
|
-
- tall
|
|
51
|
-
deprecated: true
|
|
52
39
|
format:
|
|
53
40
|
description: >-
|
|
54
41
|
Number-format mode applied to axis labels + value overlays + donut
|
|
@@ -115,17 +102,6 @@ props:
|
|
|
115
102
|
type: boolean
|
|
116
103
|
default: false
|
|
117
104
|
reflect: true
|
|
118
|
-
heading:
|
|
119
|
-
description: >-
|
|
120
|
-
DEPRECATED (OD-CHART-02). Place chart titles in an enclosing
|
|
121
|
-
card-ui's `<header><span slot="heading">...</span></header>`
|
|
122
|
-
instead. Still honored for back-compat; emits a one-shot
|
|
123
|
-
console.warn per instance when set. Used as the chart's
|
|
124
|
-
`aria-label` when no explicit label is provided.
|
|
125
|
-
type: string
|
|
126
|
-
default: ""
|
|
127
|
-
reflect: true
|
|
128
|
-
deprecated: true
|
|
129
105
|
x:
|
|
130
106
|
description: Data key for x-axis (category) values
|
|
131
107
|
type: string
|
|
@@ -11,10 +11,13 @@
|
|
|
11
11
|
:scope {
|
|
12
12
|
--color-input-swatch-size: 1em;
|
|
13
13
|
|
|
14
|
-
display:
|
|
14
|
+
display: flex;
|
|
15
15
|
vertical-align: middle;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/* Display convention (ADR-0037): block-level by default; [inline] opts back to inline-level. */
|
|
19
|
+
:scope[inline] { display: inline-flex; }
|
|
20
|
+
|
|
18
21
|
:scope[disabled] {
|
|
19
22
|
opacity: 0.55;
|
|
20
23
|
pointer-events: none;
|
|
@@ -481,6 +481,10 @@ export class UICombobox extends UIFormElement {
|
|
|
481
481
|
if (this.#suppressInput) return;
|
|
482
482
|
const text = this.#inputEl.textContent || '';
|
|
483
483
|
this.#query = text.trim();
|
|
484
|
+
// Hide the placeholder pseudo as soon as anything is typed — it's keyed
|
|
485
|
+
// off [data-empty], which the programmatic text-setter toggles but the
|
|
486
|
+
// typing path did not, so the placeholder bled THROUGH the typed text.
|
|
487
|
+
this.#inputEl.toggleAttribute('data-empty', !text);
|
|
484
488
|
|
|
485
489
|
if (!this.open) {
|
|
486
490
|
this.open = true;
|
|
@@ -489,6 +493,13 @@ export class UICombobox extends UIFormElement {
|
|
|
489
493
|
|
|
490
494
|
this.#renderOptions();
|
|
491
495
|
|
|
496
|
+
// WAI-APG list-autocomplete: pre-activate the first match while typing so
|
|
497
|
+
// pressing Enter commits it (and the user sees which option Enter will
|
|
498
|
+
// pick). #renderOptions() reset the active index; only activate when a
|
|
499
|
+
// query is present and there is something to match.
|
|
500
|
+
const opts = this.#renderedOptions();
|
|
501
|
+
if (this.#query && opts.length) this.#setActiveIndex(0);
|
|
502
|
+
|
|
492
503
|
this.dispatchEvent(new CustomEvent('input', {
|
|
493
504
|
bubbles: true,
|
|
494
505
|
detail: { value: text, query: this.#query.toLowerCase() },
|
|
@@ -166,6 +166,14 @@
|
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
+
/* Higher-specificity guard: the editable [data-input] picked up 8px block
|
|
170
|
+
padding from an outer source that out-cascaded the @scope rule above, pinning
|
|
171
|
+
the field to ~36px at every [size]. This wins the cascade so the field height
|
|
172
|
+
tracks --a-size (sm/md/lg) like input-ui. */
|
|
173
|
+
combobox-ui [data-field] [data-input] {
|
|
174
|
+
padding-block: 0;
|
|
175
|
+
}
|
|
176
|
+
|
|
169
177
|
/* ── Top-layer popover: cannot inherit @scope component tokens ── */
|
|
170
178
|
|
|
171
179
|
combobox-ui [data-listbox] {
|
|
@@ -435,7 +435,11 @@ export class UIDateRangePicker extends UIFormElement {
|
|
|
435
435
|
// Mirror reactive props onto the part nodes — runs in the element's
|
|
436
436
|
// effect every time a tracked prop changes.
|
|
437
437
|
if (!this.#triggerRef) return;
|
|
438
|
-
|
|
438
|
+
const display = this.#displayText();
|
|
439
|
+
this.#triggerRef.setAttribute('text', display);
|
|
440
|
+
// Filled vs placeholder color (matches input/select) — #displayText()
|
|
441
|
+
// returns the placeholder verbatim only when no range is committed.
|
|
442
|
+
this.#triggerRef.toggleAttribute('data-has-value', display !== this.placeholder);
|
|
439
443
|
this.#triggerRef.toggleAttribute('disabled', this.disabled);
|
|
440
444
|
this.#triggerRef.setAttribute('aria-haspopup', 'dialog');
|
|
441
445
|
this.#triggerRef.setAttribute('aria-expanded', this.open ? 'true' : 'false');
|
|
@@ -48,7 +48,9 @@
|
|
|
48
48
|
--date-range-picker-trigger-radius-default: var(--a-radius);
|
|
49
49
|
--date-range-picker-trigger-bg-default: var(--a-ui-bg);
|
|
50
50
|
--date-range-picker-trigger-bg-hover-default: var(--a-ui-bg-hover);
|
|
51
|
-
|
|
51
|
+
/* Placeholder state by default; a committed value bumps to --a-ui-text
|
|
52
|
+
via [data-has-value] (matches input-ui / select-ui value vs placeholder). */
|
|
53
|
+
--date-range-picker-trigger-fg-default: var(--a-ui-text-placeholder);
|
|
52
54
|
--date-range-picker-trigger-border-default: var(--a-ui-border);
|
|
53
55
|
--date-range-picker-trigger-border-hover-default: var(--a-ui-border-hover);
|
|
54
56
|
--date-range-picker-trigger-focus-ring-default: var(--a-focus-ring);
|
|
@@ -72,11 +74,14 @@
|
|
|
72
74
|
:scope {
|
|
73
75
|
box-sizing: border-box;
|
|
74
76
|
position: relative;
|
|
75
|
-
display:
|
|
77
|
+
display: block;
|
|
76
78
|
color: var(--date-range-picker-fg, var(--date-range-picker-fg-default));
|
|
77
79
|
font-size: var(--a-ui-size);
|
|
78
80
|
}
|
|
79
81
|
|
|
82
|
+
/* Display convention (ADR-0037): block-level by default; [inline] opts back to inline-level. */
|
|
83
|
+
:scope[inline] { display: inline-block; }
|
|
84
|
+
|
|
80
85
|
/* ── Trigger ──
|
|
81
86
|
Canonical trigger surface matching <select-ui> + <calendar-picker-ui>:
|
|
82
87
|
flex row, --a-size min-height, --a-ui-px padding, --a-radius corner,
|
|
@@ -108,6 +113,11 @@
|
|
|
108
113
|
border-color: var(--date-range-picker-trigger-border-hover, var(--date-range-picker-trigger-border-hover-default));
|
|
109
114
|
background: var(--date-range-picker-trigger-bg-hover, var(--date-range-picker-trigger-bg-hover-default));
|
|
110
115
|
}
|
|
116
|
+
/* Committed value reads as filled content (matches input-ui/select-ui),
|
|
117
|
+
not as the muted placeholder. Marked by the class when a range is set. */
|
|
118
|
+
:scope [slot="trigger"][data-has-value] {
|
|
119
|
+
color: var(--a-ui-text);
|
|
120
|
+
}
|
|
111
121
|
:scope:focus-visible { outline: none; }
|
|
112
122
|
:scope:focus-visible [slot="trigger"] {
|
|
113
123
|
box-shadow: var(--date-range-picker-trigger-focus-ring, var(--date-range-picker-trigger-focus-ring-default));
|
|
@@ -381,6 +381,9 @@ export class UIDatetimePicker extends UIFormElement {
|
|
|
381
381
|
|
|
382
382
|
// Trigger reflection — text, disabled, ARIA expansion.
|
|
383
383
|
this.#triggerRef.setAttribute('text', this.#displayText());
|
|
384
|
+
// Mark a committed value so the trigger brightens to --a-ui-text (the
|
|
385
|
+
// empty placeholder stays muted) — mirrors date-range-picker.
|
|
386
|
+
this.#triggerRef.toggleAttribute('data-has-value', this.#displayText() !== this.placeholder);
|
|
384
387
|
this.#triggerRef.toggleAttribute('disabled', this.disabled);
|
|
385
388
|
this.#triggerRef.setAttribute('aria-haspopup', 'dialog');
|
|
386
389
|
this.#triggerRef.setAttribute('aria-expanded', this.open ? 'true' : 'false');
|
|
@@ -48,15 +48,29 @@
|
|
|
48
48
|
:scope {
|
|
49
49
|
box-sizing: border-box;
|
|
50
50
|
position: relative;
|
|
51
|
-
display:
|
|
51
|
+
display: block;
|
|
52
52
|
color: var(--datetime-picker-fg, var(--datetime-picker-fg-default));
|
|
53
53
|
font-size: var(--a-ui-size);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
/* Display convention (ADR-0037): block-level by default; [inline] opts back to inline-level. */
|
|
57
|
+
:scope[inline] { display: inline-block; }
|
|
58
|
+
|
|
56
59
|
/* Default trigger sizing — composes button-ui's surface; just
|
|
57
|
-
stretches the min-width so "Jan 1, 2026 14:30" fits.
|
|
60
|
+
stretches the min-width so "Jan 1, 2026 14:30" fits. Normalize to the
|
|
61
|
+
picker-family field shape (mirrors date-range-picker): value text
|
|
62
|
+
left-aligned with the caret pushed to the trailing edge, not centered
|
|
63
|
+
like a default button. */
|
|
58
64
|
:scope [slot="trigger"] {
|
|
59
65
|
min-width: var(--datetime-picker-trigger-min-width, var(--datetime-picker-trigger-min-width-default));
|
|
66
|
+
justify-content: space-between;
|
|
67
|
+
line-height: 1;
|
|
68
|
+
}
|
|
69
|
+
/* A committed value bumps to --a-ui-text (bright), matching input-ui /
|
|
70
|
+
select-ui / time-picker value color; the empty placeholder keeps
|
|
71
|
+
button-ui's muted outline fg. */
|
|
72
|
+
:scope [slot="trigger"][data-has-value] {
|
|
73
|
+
color: var(--a-ui-text);
|
|
60
74
|
}
|
|
61
75
|
|
|
62
76
|
/* States */
|
|
@@ -12,8 +12,12 @@
|
|
|
12
12
|
--empty-state-heading-fg-default: var(--a-fg);
|
|
13
13
|
--empty-state-desc-fg-default: var(--a-fg-muted);
|
|
14
14
|
|
|
15
|
-
/* ── Typography ──
|
|
16
|
-
|
|
15
|
+
/* ── Typography ──
|
|
16
|
+
Heading uses the dedicated heading ramp (16px), NOT --a-ui-lg (15px,
|
|
17
|
+
the top of the control-label ramp) — at 15px the heading was only 1.07×
|
|
18
|
+
the 14px description, a hierarchy too weak to read as a title. 17px
|
|
19
|
+
lifts the ratio to ~1.21 (heading-medium weight adds further contrast). */
|
|
20
|
+
--empty-state-heading-size-default: var(--a-heading-md);
|
|
17
21
|
--empty-state-heading-weight-default: var(--a-weight-medium);
|
|
18
22
|
--empty-state-desc-size-default: var(--a-ui-size);
|
|
19
23
|
}
|
|
@@ -91,8 +95,11 @@
|
|
|
91
95
|
}
|
|
92
96
|
:scope[minimal] [slot="heading"] {
|
|
93
97
|
font-size: inherit;
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
/* Keep the heading bolder + non-muted so it stays distinct from the
|
|
99
|
+
muted inline description on the same baseline (otherwise '[icon]
|
|
100
|
+
heading description' reads as one run-on phrase). */
|
|
101
|
+
font-weight: var(--empty-state-heading-weight, var(--empty-state-heading-weight-default));
|
|
102
|
+
color: var(--empty-state-heading-fg, var(--empty-state-heading-fg-default));
|
|
96
103
|
line-height: inherit;
|
|
97
104
|
}
|
|
98
105
|
:scope[minimal] [slot="description"] {
|
|
@@ -36,6 +36,13 @@
|
|
|
36
36
|
align-items: center;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/* A stacked field is a full-width form row — fill the container (form column,
|
|
40
|
+
grid cell, or flex parent) rather than sizing to content. Inline fields stay
|
|
41
|
+
intrinsic so compact filter bars keep their side-by-side layout. (bug-34) */
|
|
42
|
+
:scope:not([inline]) {
|
|
43
|
+
width: 100%;
|
|
44
|
+
}
|
|
45
|
+
|
|
39
46
|
/* Gate `row-gap` on actual message presence — otherwise the grid
|
|
40
47
|
reserves --field-gap (~8px) between the control row and a
|
|
41
48
|
zero-content message row, making field-ui[inline] visibly taller
|
|
@@ -125,11 +132,15 @@
|
|
|
125
132
|
"label control"
|
|
126
133
|
". message";
|
|
127
134
|
}
|
|
135
|
+
/* Trailing sits at the control's trailing edge (after the input), not between
|
|
136
|
+
label and control — inline trailing is a control affordance (⌘K hint,
|
|
137
|
+
result count), so it reads at the row's end, mirroring input-ui's own
|
|
138
|
+
trailing slot. (bug-18) */
|
|
128
139
|
:scope[inline]:has([slot="trailing"]):not(:has([slot="action"])) {
|
|
129
|
-
grid-template-columns: minmax(var(--field-label-inline-min, var(--field-label-inline-min-default)), auto)
|
|
140
|
+
grid-template-columns: minmax(var(--field-label-inline-min, var(--field-label-inline-min-default)), auto) minmax(0, 1fr) auto;
|
|
130
141
|
grid-template-areas:
|
|
131
|
-
"label trailing
|
|
132
|
-
".
|
|
142
|
+
"label control trailing"
|
|
143
|
+
". message message";
|
|
133
144
|
}
|
|
134
145
|
:scope[inline]:not(:has([slot="trailing"])):has([slot="action"]) {
|
|
135
146
|
grid-template-columns: minmax(var(--field-label-inline-min, var(--field-label-inline-min-default)), auto) minmax(0, 1fr) auto;
|
|
@@ -138,10 +149,10 @@
|
|
|
138
149
|
". message message";
|
|
139
150
|
}
|
|
140
151
|
:scope[inline]:has([slot="trailing"]):has([slot="action"]) {
|
|
141
|
-
grid-template-columns: minmax(var(--field-label-inline-min, var(--field-label-inline-min-default)), auto)
|
|
152
|
+
grid-template-columns: minmax(var(--field-label-inline-min, var(--field-label-inline-min-default)), auto) minmax(0, 1fr) auto auto;
|
|
142
153
|
grid-template-areas:
|
|
143
|
-
"label trailing
|
|
144
|
-
".
|
|
154
|
+
"label control trailing action"
|
|
155
|
+
". message message message";
|
|
145
156
|
}
|
|
146
157
|
:scope[inline]:not([label]):not(:has([slot="trailing"])):not(:has([slot="action"])) {
|
|
147
158
|
grid-template-columns: minmax(0, 1fr);
|
|
@@ -31,6 +31,11 @@
|
|
|
31
31
|
"type": "string",
|
|
32
32
|
"default": "md"
|
|
33
33
|
},
|
|
34
|
+
"minColumnWidth": {
|
|
35
|
+
"description": "Minimum track width for columns=\"auto-fit\"/\"auto-fill\" (any CSS length, e.g. \"240px\", \"16rem\"). Sets the minmax() floor so cards don't shrink below it before wrapping; unset uses the 12rem default. No effect on numeric columns.",
|
|
36
|
+
"type": "string",
|
|
37
|
+
"default": ""
|
|
38
|
+
},
|
|
34
39
|
"rowGap": {
|
|
35
40
|
"description": "Row gap override",
|
|
36
41
|
"type": "string",
|