@adia-ai/web-components 0.8.38 → 0.8.40
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 +30 -0
- package/MIGRATION.md +243 -2
- package/components/agent-artifact/agent-artifact.css +1 -1
- package/components/agent-reasoning/agent-reasoning.css +2 -2
- package/components/agent-trace/agent-trace.css +3 -3
- package/components/alert/alert.css +1 -1
- package/components/avatar/avatar.css +1 -1
- package/components/badge/badge.css +1 -1
- package/components/button/button.css +6 -5
- package/components/calendar-picker/calendar-picker.css +5 -2
- package/components/card/card.css +3 -3
- package/components/chart/chart.a2ui.json +5 -5
- package/components/chart/chart.class.js +4 -4
- package/components/chart/chart.css +6 -6
- package/components/chart/chart.d.ts +2 -2
- package/components/chart/chart.yaml +3 -2
- package/components/chat-thread/chat-thread.css +1 -1
- package/components/code/code.css +6 -6
- package/components/combobox/combobox.css +8 -2
- package/components/command/command.a2ui.json +3 -0
- package/components/command/command.class.js +28 -6
- package/components/command/command.css +17 -6
- package/components/command/command.yaml +5 -0
- package/components/date-range-picker/date-range-picker.css +7 -1
- package/components/datetime-picker/datetime-picker.css +5 -1
- package/components/description-list/description-list.css +2 -2
- package/components/display-field/display-field.css +3 -3
- package/components/divider/divider.css +1 -1
- package/components/drawer/drawer.css +2 -2
- package/components/drilldown/drilldown.a2ui.json +3 -1
- package/components/drilldown/drilldown.class.js +12 -4
- package/components/drilldown/drilldown.css +9 -10
- package/components/drilldown/drilldown.yaml +2 -0
- package/components/empty-state/empty-state.css +2 -2
- package/components/field/field.css +1 -1
- package/components/heatmap/heatmap.css +2 -2
- package/components/inline-message/inline-message.css +1 -1
- package/components/input/input.css +5 -4
- package/components/integration-card/integration-card.css +4 -4
- package/components/kbd/kbd.css +1 -1
- package/components/list/list.css +2 -2
- package/components/modal/modal.class.js +68 -4
- package/components/nav/nav.a2ui.json +5 -0
- package/components/nav/nav.class.js +24 -4
- package/components/nav/nav.css +2 -2
- package/components/nav/nav.d.ts +2 -0
- package/components/nav/nav.yaml +18 -0
- package/components/nav-group/nav-group.css +3 -3
- package/components/nav-item/nav-item.css +2 -2
- package/components/option-card/option-card.css +1 -1
- package/components/otp-input/otp-input.css +1 -1
- package/components/page/page.css +2 -2
- package/components/pagination/pagination.css +1 -1
- package/components/pane/pane.css +1 -1
- package/components/progress-row/progress-row.css +2 -2
- package/components/qr-code/qr-code.a2ui.json +10 -10
- package/components/qr-code/qr-code.class.js +3 -3
- package/components/qr-code/qr-code.d.ts +10 -7
- package/components/qr-code/qr-code.yaml +13 -9
- package/components/range/range.css +1 -1
- package/components/rating/rating.css +1 -1
- package/components/richtext/richtext.css +3 -3
- package/components/segment/segment.css +5 -4
- package/components/select/select.class.js +30 -12
- package/components/select/select.css +14 -5
- package/components/spinner/spinner.css +1 -1
- package/components/stat/stat.css +3 -3
- package/components/step-progress/step-progress.css +1 -1
- package/components/stepper/stepper.css +2 -2
- package/components/swatch/swatch.css +8 -6
- package/components/table/table.a2ui.json +0 -10
- package/components/table/table.class.js +4 -4
- package/components/table/table.css +6 -9
- package/components/table/table.d.ts +0 -2
- package/components/table/table.yaml +0 -9
- package/components/table-toolbar/table-toolbar.css +1 -1
- package/components/tabs/tabs.css +1 -1
- package/components/tag/tag.css +2 -2
- package/components/tags-input/tags-input.css +1 -1
- package/components/textarea/textarea.css +1 -1
- package/components/time-picker/time-picker.css +1 -1
- package/components/timeline/timeline.css +4 -4
- package/components/toc/toc.css +1 -1
- package/components/toggle-group/toggle-group.class.js +13 -11
- package/components/toggle-group/toggle-group.css +14 -8
- package/components/toggle-group/toggle-group.d.ts +5 -0
- package/components/toggle-group/toggle-group.yaml +7 -0
- package/components/toggle-group/toggle-option.a2ui.json +5 -0
- package/components/toggle-group/toggle-option.yaml +14 -2
- package/components/tooltip/tooltip.css +1 -1
- package/components/tour/tour.css +2 -2
- package/components/tree/tree.css +1 -1
- package/custom-elements.json +101 -89
- package/dist/host.min.css +1 -1
- package/dist/host.sheet.js +1 -1
- package/dist/theme-provider.min.js +3 -3
- package/dist/web-components.min.css +1 -1
- package/dist/web-components.min.js +97 -94
- package/dist/web-components.sheet.js +1 -1
- package/package.json +1 -1
- package/styles/type/scale.css +6 -7
|
@@ -439,8 +439,14 @@ export class UISelect extends UIFormElement {
|
|
|
439
439
|
: this.icon
|
|
440
440
|
? `<icon-ui slot="leading" data-select-leading name="${escapeHTML(this.icon)}"></icon-ui>`
|
|
441
441
|
: '';
|
|
442
|
+
// No native <input> wrap (per ADR-0055 / ADR-0025): the searchable
|
|
443
|
+
// trigger is a `contenteditable="plaintext-only"` surface carrying
|
|
444
|
+
// `role="combobox"`, mirroring combobox-ui's editable-surface pattern.
|
|
445
|
+
// Placeholder text renders via the [data-empty]::before pseudo (see
|
|
446
|
+
// select.css), same mechanism as input-ui / combobox-ui.
|
|
447
|
+
const initialDisplayText = this.#displayText() === this.placeholder ? '' : this.#displayText();
|
|
442
448
|
const displayMarkup = this.searchable
|
|
443
|
-
? `<
|
|
449
|
+
? `<span slot="display" contenteditable="plaintext-only" role="combobox" aria-autocomplete="list" tabindex="0" data-placeholder="${escapeHTML(this.placeholder || '')}"${initialDisplayText ? '' : ' data-empty'}>${escapeHTML(initialDisplayText)}</span>`
|
|
444
450
|
: `<span slot="display">${escapeHTML(this.#displayText())}</span>`;
|
|
445
451
|
// §184 (v0.5.5, FEEDBACK-08 §7): optional hint slot beneath the
|
|
446
452
|
// trigger. Mirrors slider-ui's hint pattern + matches the
|
|
@@ -478,7 +484,7 @@ export class UISelect extends UIFormElement {
|
|
|
478
484
|
this.#searchInput.removeEventListener('focus', this.#onSearchFocus);
|
|
479
485
|
this.#searchInput.removeEventListener('click', this.#onSearchClick);
|
|
480
486
|
}
|
|
481
|
-
this.#searchInput = this.querySelector('
|
|
487
|
+
this.#searchInput = this.querySelector('[slot="display"][contenteditable]');
|
|
482
488
|
if (this.#searchInput) {
|
|
483
489
|
this.#searchInput.addEventListener('input', this.#onSearchInput);
|
|
484
490
|
this.#searchInput.addEventListener('focus', this.#onSearchFocus);
|
|
@@ -492,9 +498,13 @@ export class UISelect extends UIFormElement {
|
|
|
492
498
|
const display = this.querySelector('[slot="display"]');
|
|
493
499
|
if (display && !this.multiple) {
|
|
494
500
|
// Single-select: keep the canonical text-rendering path.
|
|
495
|
-
if (display.
|
|
496
|
-
// Only update
|
|
497
|
-
if (!this.#query)
|
|
501
|
+
if (display.hasAttribute('contenteditable')) {
|
|
502
|
+
// Only update text when not actively editing (no active query)
|
|
503
|
+
if (!this.#query) {
|
|
504
|
+
const text = this.#displayText() === this.placeholder ? '' : this.#displayText();
|
|
505
|
+
display.textContent = text;
|
|
506
|
+
display.toggleAttribute('data-empty', !text);
|
|
507
|
+
}
|
|
498
508
|
} else {
|
|
499
509
|
display.textContent = this.#displayText();
|
|
500
510
|
}
|
|
@@ -502,10 +512,13 @@ export class UISelect extends UIFormElement {
|
|
|
502
512
|
// Multi-select: display element holds the placeholder ONLY when
|
|
503
513
|
// no chips are present (otherwise the chip row IS the display).
|
|
504
514
|
const hasChips = this.#values().length > 0;
|
|
505
|
-
if (display.
|
|
515
|
+
if (display.hasAttribute('contenteditable')) {
|
|
506
516
|
// search input — keep placeholder; never inject the value text.
|
|
507
|
-
display.placeholder
|
|
508
|
-
if (!this.#query)
|
|
517
|
+
display.setAttribute('data-placeholder', hasChips ? '' : (this.placeholder || ''));
|
|
518
|
+
if (!this.#query) {
|
|
519
|
+
display.textContent = '';
|
|
520
|
+
display.toggleAttribute('data-empty', true);
|
|
521
|
+
}
|
|
509
522
|
} else {
|
|
510
523
|
display.textContent = hasChips ? '' : (this.placeholder || '');
|
|
511
524
|
}
|
|
@@ -991,7 +1004,7 @@ export class UISelect extends UIFormElement {
|
|
|
991
1004
|
// before it would start removing query characters.
|
|
992
1005
|
if (e.key === 'Backspace' && this.multiple && !this.disabled && !this.readonly) {
|
|
993
1006
|
const target = e.target;
|
|
994
|
-
const fromInput = target && target.
|
|
1007
|
+
const fromInput = target && target.hasAttribute?.('contenteditable') && target.getAttribute('slot') === 'display';
|
|
995
1008
|
const queryEmpty = !this.#query || this.#query.length === 0;
|
|
996
1009
|
if (!fromInput || queryEmpty) {
|
|
997
1010
|
if (this.#values().length > 0) {
|
|
@@ -1005,8 +1018,11 @@ export class UISelect extends UIFormElement {
|
|
|
1005
1018
|
if (this.searchable && this.#query) {
|
|
1006
1019
|
// First Escape: clear query
|
|
1007
1020
|
this.#query = '';
|
|
1008
|
-
const input = this.querySelector('
|
|
1009
|
-
if (input)
|
|
1021
|
+
const input = this.querySelector('[slot="display"][contenteditable]');
|
|
1022
|
+
if (input) {
|
|
1023
|
+
input.textContent = '';
|
|
1024
|
+
input.toggleAttribute('data-empty', true);
|
|
1025
|
+
}
|
|
1010
1026
|
this.#applyFilter();
|
|
1011
1027
|
return;
|
|
1012
1028
|
}
|
|
@@ -1061,7 +1077,9 @@ export class UISelect extends UIFormElement {
|
|
|
1061
1077
|
};
|
|
1062
1078
|
|
|
1063
1079
|
#onSearchInput = (e) => {
|
|
1064
|
-
|
|
1080
|
+
const text = e.target.textContent || '';
|
|
1081
|
+
this.#query = text;
|
|
1082
|
+
e.target.toggleAttribute('data-empty', !text);
|
|
1065
1083
|
if (!this.open) this.open = true;
|
|
1066
1084
|
this.#applyFilter();
|
|
1067
1085
|
};
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
border: 1px solid var(--select-border);
|
|
92
92
|
border-radius: var(--select-radius);
|
|
93
93
|
background: var(--select-bg);
|
|
94
|
-
line-height:
|
|
94
|
+
line-height: var(--a-font-leading-none);
|
|
95
95
|
cursor: pointer;
|
|
96
96
|
/* Match every property the hover / focus / invalid states change. */
|
|
97
97
|
transition:
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
display: inline-flex;
|
|
131
131
|
align-items: center;
|
|
132
132
|
flex-shrink: 0;
|
|
133
|
-
line-height:
|
|
133
|
+
line-height: var(--a-font-leading-none);
|
|
134
134
|
--a-icon-size: var(--select-font-size);
|
|
135
135
|
color: var(--select-fg-muted);
|
|
136
136
|
}
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
white-space: nowrap;
|
|
150
150
|
color: var(--select-fg);
|
|
151
151
|
}
|
|
152
|
-
|
|
152
|
+
[slot="display"][contenteditable] {
|
|
153
153
|
border: none;
|
|
154
154
|
outline: none;
|
|
155
155
|
background: transparent;
|
|
@@ -159,9 +159,18 @@
|
|
|
159
159
|
color: var(--select-fg);
|
|
160
160
|
min-width: 0;
|
|
161
161
|
width: 100%;
|
|
162
|
+
/* Positioning context for the [data-empty]::before placeholder pseudo
|
|
163
|
+
below — out-of-flow, same rationale as input-ui/combobox-ui: an
|
|
164
|
+
in-flow pseudo would render the caret after the placeholder text
|
|
165
|
+
instead of at content-start. */
|
|
166
|
+
position: relative;
|
|
162
167
|
}
|
|
163
|
-
|
|
168
|
+
[slot="display"][contenteditable][data-empty]::before {
|
|
169
|
+
content: attr(data-placeholder);
|
|
164
170
|
color: var(--select-placeholder-fg);
|
|
171
|
+
pointer-events: none;
|
|
172
|
+
position: absolute;
|
|
173
|
+
inset: 0;
|
|
165
174
|
}
|
|
166
175
|
:scope:not([value]) [slot="display"],
|
|
167
176
|
:scope[value=""] [slot="display"] {
|
|
@@ -405,7 +414,7 @@ select-ui [role="group"] [slot="group-label"] {
|
|
|
405
414
|
font-weight: var(--a-ui-weight);
|
|
406
415
|
color: var(--select-fg-muted);
|
|
407
416
|
text-transform: uppercase;
|
|
408
|
-
letter-spacing:
|
|
417
|
+
letter-spacing: var(--a-font-tracking-wide);
|
|
409
418
|
white-space: nowrap;
|
|
410
419
|
}
|
|
411
420
|
|
package/components/stat/stat.css
CHANGED
|
@@ -171,7 +171,7 @@
|
|
|
171
171
|
grid-area: label;
|
|
172
172
|
font-size: var(--stat-label-size);
|
|
173
173
|
color: var(--stat-label-fg);
|
|
174
|
-
line-height:
|
|
174
|
+
line-height: var(--a-font-leading-normal);
|
|
175
175
|
min-width: 0;
|
|
176
176
|
overflow: hidden;
|
|
177
177
|
text-overflow: ellipsis;
|
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
align-items: center;
|
|
186
186
|
gap: 0.25em;
|
|
187
187
|
font-size: var(--stat-change-size);
|
|
188
|
-
line-height:
|
|
188
|
+
line-height: var(--a-font-leading-none);
|
|
189
189
|
justify-self: start;
|
|
190
190
|
}
|
|
191
191
|
|
|
@@ -195,7 +195,7 @@
|
|
|
195
195
|
font-size: var(--stat-value-size);
|
|
196
196
|
font-weight: var(--stat-value-weight);
|
|
197
197
|
color: var(--stat-value-fg);
|
|
198
|
-
line-height:
|
|
198
|
+
line-height: var(--a-font-leading-snug);
|
|
199
199
|
min-width: 0;
|
|
200
200
|
overflow: hidden;
|
|
201
201
|
text-overflow: ellipsis;
|
|
@@ -236,7 +236,7 @@
|
|
|
236
236
|
display: block;
|
|
237
237
|
font-weight: var(--stepper-item-label-weight);
|
|
238
238
|
font-size: var(--stepper-item-label-size);
|
|
239
|
-
line-height:
|
|
239
|
+
line-height: var(--a-font-leading-normal);
|
|
240
240
|
color: var(--stepper-item-label-fg);
|
|
241
241
|
min-width: 0;
|
|
242
242
|
overflow-wrap: break-word;
|
|
@@ -247,7 +247,7 @@
|
|
|
247
247
|
margin-top: var(--stepper-item-offset-xs);
|
|
248
248
|
color: var(--stepper-item-desc-fg);
|
|
249
249
|
font-size: var(--stepper-item-desc-size);
|
|
250
|
-
line-height:
|
|
250
|
+
line-height: var(--a-font-leading-relaxed);
|
|
251
251
|
}
|
|
252
252
|
|
|
253
253
|
:scope [slot]:empty {
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
min-width: 0;
|
|
64
64
|
color: var(--swatch-label-fg);
|
|
65
65
|
font-size: var(--swatch-label-size);
|
|
66
|
-
line-height:
|
|
66
|
+
line-height: var(--a-font-leading-snug);
|
|
67
67
|
vertical-align: baseline;
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -238,7 +238,7 @@
|
|
|
238
238
|
background: var(--swatch-badge-bg);
|
|
239
239
|
color: var(--swatch-badge-fg);
|
|
240
240
|
font-size: var(--swatch-badge-size);
|
|
241
|
-
line-height:
|
|
241
|
+
line-height: var(--a-font-leading-none);
|
|
242
242
|
border-radius: var(--swatch-badge-radius);
|
|
243
243
|
box-shadow: 0 0 0 1px color-mix(in oklab, var(--md-sys-color-neutral-outline-variant) 60%, transparent);
|
|
244
244
|
}
|
|
@@ -274,20 +274,22 @@
|
|
|
274
274
|
z-index: 1;
|
|
275
275
|
}
|
|
276
276
|
:scope[shape="block"][auto-contrast] > [data-label][data-on-dark] {
|
|
277
|
-
color: var(--a-chrome-light
|
|
277
|
+
color: var(--a-chrome-light);
|
|
278
278
|
}
|
|
279
279
|
:scope[shape="block"][auto-contrast] > [data-label][data-on-light] {
|
|
280
|
-
color: var(--a-chrome-dark
|
|
280
|
+
color: var(--a-chrome-dark);
|
|
281
281
|
}
|
|
282
282
|
/* Detail line follows the same auto-contrast choice. */
|
|
283
283
|
:scope[shape="block"][auto-contrast] > [data-detail] {
|
|
284
284
|
z-index: 1;
|
|
285
285
|
}
|
|
286
286
|
:scope[shape="block"][auto-contrast] > [data-label][data-on-dark] ~ [data-detail] {
|
|
287
|
-
color:
|
|
287
|
+
color: var(--a-chrome-light);
|
|
288
|
+
opacity: 0.8;
|
|
288
289
|
}
|
|
289
290
|
:scope[shape="block"][auto-contrast] > [data-label][data-on-light] ~ [data-detail] {
|
|
290
|
-
color:
|
|
291
|
+
color: var(--a-chrome-dark);
|
|
292
|
+
opacity: 0.7;
|
|
291
293
|
}
|
|
292
294
|
|
|
293
295
|
/* ═══════ Copy button — a stamped <button-ui variant="ghost" size="sm">
|
|
@@ -24,16 +24,6 @@
|
|
|
24
24
|
"description": "JS property (set programmatically — `el.data = [...]`) — row records, an array of plain objects keyed to columns[].key. May also be supplied declaratively as a JSON-array `data=\"[…]\"` attribute, hydrated once at connect (gh#288) — the same pattern chart-ui's `data` attribute uses. Custom accessor on the element class, not a reflected attribute.",
|
|
25
25
|
"$ref": "common_types.json#/$defs/DynamicObjectList"
|
|
26
26
|
},
|
|
27
|
-
"density": {
|
|
28
|
-
"description": "Controls cell padding and row height. 'compact' for dense data, 'standard' for default spacing, 'comfortable' for spacious rows.",
|
|
29
|
-
"type": "string",
|
|
30
|
-
"enum": [
|
|
31
|
-
"compact",
|
|
32
|
-
"standard",
|
|
33
|
-
"comfortable"
|
|
34
|
-
],
|
|
35
|
-
"default": "standard"
|
|
36
|
-
},
|
|
37
27
|
"expandable": {
|
|
38
28
|
"description": "Enable row expansion",
|
|
39
29
|
"type": "boolean",
|
|
@@ -21,8 +21,11 @@
|
|
|
21
21
|
* sortable — enable column sorting on header click
|
|
22
22
|
* selectable — enable row selection via checkboxes
|
|
23
23
|
* striped — alternate row background
|
|
24
|
-
* density — 'compact' | 'standard' | 'comfortable'
|
|
25
24
|
* valign — 'center' (default) | 'top' — body-cell vertical alignment (gh#505)
|
|
25
|
+
*
|
|
26
|
+
* table-ui has no local `density` prop (ADR-0054) — it converges onto the
|
|
27
|
+
* ambient global [density="compact"|"spacious"] attribute; --table-py/-px
|
|
28
|
+
* already derive from --a-space-* steps, which --a-density scales.
|
|
26
29
|
* paginate — rows per page (0 = no pagination)
|
|
27
30
|
* loading — show loading overlay
|
|
28
31
|
* search — global search filter string
|
|
@@ -118,7 +121,6 @@ export class UITable extends UIElement {
|
|
|
118
121
|
frameless: { type: Boolean, default: false, reflect: true },
|
|
119
122
|
wrap: { type: Boolean, default: false, reflect: true },
|
|
120
123
|
raw: { type: Boolean, default: false, reflect: true },
|
|
121
|
-
density: { type: String, default: 'standard', reflect: true },
|
|
122
124
|
paginate: { type: Number, default: 0, reflect: true },
|
|
123
125
|
loading: { type: Boolean, default: false, reflect: true },
|
|
124
126
|
search: { type: String, default: '', reflect: true },
|
|
@@ -294,7 +296,6 @@ export class UITable extends UIElement {
|
|
|
294
296
|
columnWidths: Object.fromEntries(this.#columnWidths),
|
|
295
297
|
hiddenColumns: this.#columns.filter(c => c.hidden).map(c => c.key),
|
|
296
298
|
page: this.#page,
|
|
297
|
-
density: this.density,
|
|
298
299
|
};
|
|
299
300
|
}
|
|
300
301
|
|
|
@@ -319,7 +320,6 @@ export class UITable extends UIElement {
|
|
|
319
320
|
}
|
|
320
321
|
}
|
|
321
322
|
if (state.page != null) this.#page = state.page;
|
|
322
|
-
if (state.density) this.density = state.density;
|
|
323
323
|
this.#requestRender();
|
|
324
324
|
}
|
|
325
325
|
|
|
@@ -463,14 +463,11 @@
|
|
|
463
463
|
|
|
464
464
|
/* ═══════ Density ═══════ */
|
|
465
465
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
:scope[density="comfortable"] {
|
|
472
|
-
--table-py: var(--a-space-4);
|
|
473
|
-
}
|
|
466
|
+
/* No local override (ADR-0054 convergence) — --table-py/-px above already
|
|
467
|
+
derive from --a-space-* steps, which the ambient global
|
|
468
|
+
[density="compact"|"spacious"] attribute already scales via
|
|
469
|
+
--a-density. Do not reintroduce a component-local :scope[density=…]
|
|
470
|
+
block; that would re-shadow the global grammar (ADR-0053). */
|
|
474
471
|
|
|
475
472
|
/* ═══════ Pinned cells ═══════ */
|
|
476
473
|
|
|
@@ -744,7 +741,7 @@
|
|
|
744
741
|
grid-template-columns: subgrid;
|
|
745
742
|
grid-column: 1 / -1;
|
|
746
743
|
border-top: 2px solid var(--table-agg-border);
|
|
747
|
-
font-weight:
|
|
744
|
+
font-weight: var(--a-weight-semibold);
|
|
748
745
|
font-size: var(--table-agg-size);
|
|
749
746
|
color: var(--table-fg-secondary);
|
|
750
747
|
}
|
|
@@ -90,8 +90,6 @@ export class UITable extends UIElement {
|
|
|
90
90
|
columns: string;
|
|
91
91
|
/** JS property (set programmatically — `el.data = [...]`) — row records, an array of plain objects keyed to columns[].key. May also be supplied declaratively as a JSON-array `data="[…]"` attribute, hydrated once at connect (gh#288) — the same pattern chart-ui's `data` attribute uses. Custom accessor on the element class, not a reflected attribute. */
|
|
92
92
|
data: string;
|
|
93
|
-
/** Controls cell padding and row height. 'compact' for dense data, 'standard' for default spacing, 'comfortable' for spacious rows. */
|
|
94
|
-
density: 'compact' | 'standard' | 'comfortable';
|
|
95
93
|
/** Enable row expansion */
|
|
96
94
|
expandable: boolean;
|
|
97
95
|
/** Drop the table's outer 1px perimeter and nothing else (gh#511) — row dividers are untouched (the perimeter is split onto its own --table-perimeter token, defaulting to --table-border). For card-composed tables: the card owns the frame, so the table's square perimeter otherwise renders a doubled edge (flush bleed) or a stray inner box (with content above). Standalone tables keep their chrome by default. Theming path without the attribute: set --table-perimeter to transparent per instance. Note: `<card-ui><section bleed>` already drops a direct-child table-ui's chrome automatically (card.css, gh#796) — `frameless`/`raw` on the instance still applies and is honored, but is no longer required just to avoid the doubled-edge look in that composition. */
|
|
@@ -36,15 +36,6 @@ props:
|
|
|
36
36
|
type: object
|
|
37
37
|
default: []
|
|
38
38
|
dynamic: true # JS-set collection prop with a custom setter — deliberately not in static properties
|
|
39
|
-
density:
|
|
40
|
-
description: Controls cell padding and row height. 'compact' for dense data, 'standard' for default
|
|
41
|
-
spacing, 'comfortable' for spacious rows.
|
|
42
|
-
type: string
|
|
43
|
-
default: standard
|
|
44
|
-
enum:
|
|
45
|
-
- compact
|
|
46
|
-
- standard
|
|
47
|
-
- comfortable
|
|
48
39
|
expandable:
|
|
49
40
|
description: Enable row expansion
|
|
50
41
|
type: boolean
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
font-size: var(--table-toolbar-title-size);
|
|
83
83
|
font-weight: var(--table-toolbar-title-weight);
|
|
84
84
|
color: var(--table-toolbar-title-fg);
|
|
85
|
-
line-height:
|
|
85
|
+
line-height: var(--a-font-leading-snug);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
[data-count-badge][hidden] { display: none; }
|
package/components/tabs/tabs.css
CHANGED
|
@@ -138,7 +138,7 @@
|
|
|
138
138
|
/* font-family floor — see segment.css rationale. */
|
|
139
139
|
font-family: var(--tabs-font-family);
|
|
140
140
|
font-size: var(--tabs-font-size);
|
|
141
|
-
line-height:
|
|
141
|
+
line-height: var(--a-font-leading-none);
|
|
142
142
|
cursor: pointer;
|
|
143
143
|
user-select: none;
|
|
144
144
|
white-space: nowrap;
|
package/components/tag/tag.css
CHANGED
|
@@ -154,8 +154,8 @@ tag-ui[removable]:not([disabled]):hover {
|
|
|
154
154
|
/* font-family floor — see segment.css rationale. */
|
|
155
155
|
font-family: var(--tag-font-family);
|
|
156
156
|
font-size: var(--tag-font);
|
|
157
|
-
font-weight:
|
|
158
|
-
line-height:
|
|
157
|
+
font-weight: var(--a-weight-medium);
|
|
158
|
+
line-height: var(--a-font-leading-none);
|
|
159
159
|
color: var(--tag-fg);
|
|
160
160
|
background: var(--tag-bg);
|
|
161
161
|
white-space: nowrap;
|
|
@@ -75,7 +75,7 @@ textarea-ui:not([disabled]) [slot="text"]:hover {
|
|
|
75
75
|
/* font-family floor — see segment.css rationale. */
|
|
76
76
|
font-family: var(--textarea-font-family);
|
|
77
77
|
font-size: var(--textarea-font-size);
|
|
78
|
-
line-height:
|
|
78
|
+
line-height: var(--a-font-leading-relaxed);
|
|
79
79
|
white-space: pre-wrap;
|
|
80
80
|
word-break: break-word;
|
|
81
81
|
overflow-y: auto;
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
font-family: var(--time-picker-font-family, var(--a-font-family-ui));
|
|
43
43
|
font-size: var(--time-picker-font-size);
|
|
44
44
|
font-variant-numeric: tabular-nums;
|
|
45
|
-
line-height:
|
|
45
|
+
line-height: var(--a-font-leading-normal);
|
|
46
46
|
cursor: text;
|
|
47
47
|
transition:
|
|
48
48
|
border-color var(--time-picker-duration) var(--time-picker-easing),
|
|
@@ -309,7 +309,7 @@ agent-reasoning-ui timeline-ui:not([orientation="horizontal"]),
|
|
|
309
309
|
font-weight: var(--timeline-item-label-weight);
|
|
310
310
|
font-size: var(--timeline-item-label-size);
|
|
311
311
|
color: var(--timeline-item-label-fg);
|
|
312
|
-
line-height:
|
|
312
|
+
line-height: var(--a-font-leading-normal);
|
|
313
313
|
overflow-wrap: break-word;
|
|
314
314
|
min-width: 0;
|
|
315
315
|
}
|
|
@@ -323,7 +323,7 @@ agent-reasoning-ui timeline-ui:not([orientation="horizontal"]),
|
|
|
323
323
|
grid-row: 2;
|
|
324
324
|
color: var(--timeline-item-desc-fg);
|
|
325
325
|
font-size: var(--timeline-item-desc-size);
|
|
326
|
-
line-height:
|
|
326
|
+
line-height: var(--a-font-leading-relaxed);
|
|
327
327
|
margin-top: var(--a-space-0-5);
|
|
328
328
|
}
|
|
329
329
|
|
|
@@ -333,7 +333,7 @@ agent-reasoning-ui timeline-ui:not([orientation="horizontal"]),
|
|
|
333
333
|
color: var(--timeline-item-time-fg);
|
|
334
334
|
font-size: var(--timeline-item-time-size);
|
|
335
335
|
font-variant-numeric: tabular-nums;
|
|
336
|
-
line-height:
|
|
336
|
+
line-height: var(--a-font-leading-normal);
|
|
337
337
|
white-space: nowrap;
|
|
338
338
|
justify-self: end;
|
|
339
339
|
}
|
|
@@ -356,7 +356,7 @@ agent-reasoning-ui timeline-ui:not([orientation="horizontal"]),
|
|
|
356
356
|
gap: var(--a-space-0-5);
|
|
357
357
|
color: var(--timeline-item-outcome-fg);
|
|
358
358
|
font-size: var(--timeline-item-desc-size);
|
|
359
|
-
line-height:
|
|
359
|
+
line-height: var(--a-font-leading-relaxed);
|
|
360
360
|
animation: tl-fade var(--timeline-item-duration) var(--timeline-item-easing);
|
|
361
361
|
}
|
|
362
362
|
|
package/components/toc/toc.css
CHANGED
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
padding-inline: var(--toc-padding-inline);
|
|
60
60
|
text-decoration: none;
|
|
61
61
|
color: inherit;
|
|
62
|
-
line-height:
|
|
62
|
+
line-height: var(--a-font-leading-normal);
|
|
63
63
|
border-inline-start: 2px solid var(--toc-rule-inactive);
|
|
64
64
|
transition:
|
|
65
65
|
color var(--a-duration-fast) var(--a-easing),
|
|
@@ -30,10 +30,12 @@ import { UIElement } from '../../core/element.js';
|
|
|
30
30
|
// ── Toggle Option ──
|
|
31
31
|
//
|
|
32
32
|
// Parent-managed. Selection state flows through `toggle-group-ui`'s `value`
|
|
33
|
-
// (and `single` mode flag)
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
//
|
|
33
|
+
// (and `single` mode flag) — the group's `value` stays the single source of
|
|
34
|
+
// truth. ADR-0056 (gh#1303): the child's current-state surface is the
|
|
35
|
+
// declared, reflected `selected` prop below, converging onto <segment-ui>'s
|
|
36
|
+
// mechanism (yaml → catalog → generative grammar) instead of a private
|
|
37
|
+
// stamp. Don't set `selected` directly on an option; drive the group's
|
|
38
|
+
// `value` instead.
|
|
37
39
|
|
|
38
40
|
export class UIToggleOption extends UIElement {
|
|
39
41
|
static properties = {
|
|
@@ -41,6 +43,7 @@ export class UIToggleOption extends UIElement {
|
|
|
41
43
|
text: { type: String, default: '', reflect: true },
|
|
42
44
|
icon: { type: String, default: '', reflect: true },
|
|
43
45
|
disabled: { type: Boolean, default: false, reflect: true },
|
|
46
|
+
selected: { type: Boolean, default: false, reflect: true },
|
|
44
47
|
};
|
|
45
48
|
|
|
46
49
|
static template = () => null;
|
|
@@ -59,6 +62,7 @@ export class UIToggleOption extends UIElement {
|
|
|
59
62
|
}
|
|
60
63
|
if (this.disabled) this.setAttribute('aria-disabled', 'true');
|
|
61
64
|
else this.removeAttribute('aria-disabled');
|
|
65
|
+
this.setAttribute('aria-pressed', this.selected ? 'true' : 'false');
|
|
62
66
|
}
|
|
63
67
|
|
|
64
68
|
#stamp() {
|
|
@@ -100,13 +104,11 @@ export class UIToggleGroup extends UIElement {
|
|
|
100
104
|
const selected = this.#valueSet;
|
|
101
105
|
for (const opt of this.querySelectorAll('toggle-option-ui')) {
|
|
102
106
|
const optVal = opt.value || opt.getAttribute('value') || '';
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
opt.setAttribute('aria-pressed', 'false');
|
|
109
|
-
}
|
|
107
|
+
const isSelected = selected.has(optVal);
|
|
108
|
+
// ADR-0056 (gh#1303): `selected` is the declared, reflected mechanism —
|
|
109
|
+
// converges onto <segment-ui>'s convention (opt's own render() stamps
|
|
110
|
+
// aria-pressed from it).
|
|
111
|
+
opt.selected = isSelected;
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
114
|
|
|
@@ -1,12 +1,21 @@
|
|
|
1
|
-
/* Safari 17.x bug: `:scope:not(...):hover`
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/* Safari 17.x bug: `:scope:not(...):hover` (Flavor A) and `:scope[selected]`
|
|
2
|
+
(Flavor B — attribute-removal restyle) both fail inside `@scope`.
|
|
3
|
+
Selectors moved out. The @scope is `(toggle-option-ui)` — NOT
|
|
4
|
+
`(toggle-group-ui)` — so the moved-out selectors target
|
|
5
|
+
`toggle-option-ui:hover` / `toggle-option-ui[selected]`. See
|
|
6
|
+
docs/BROWSER-COMPAT.md §3a; mirrors segment.css. */
|
|
5
7
|
toggle-option-ui:not([disabled]):hover {
|
|
6
8
|
--toggle-option-bg: var(--toggle-option-bg-hover);
|
|
7
9
|
--toggle-option-fg: var(--toggle-option-fg-hover);
|
|
8
10
|
}
|
|
9
11
|
|
|
12
|
+
/* ADR-0056 (gh#1303): converged onto <segment-ui>'s declared, reflected
|
|
13
|
+
[selected] prop, set by <toggle-group-ui> (toggle-group.class.js). */
|
|
14
|
+
toggle-option-ui[selected] {
|
|
15
|
+
--toggle-option-bg: var(--toggle-option-selected-bg);
|
|
16
|
+
--toggle-option-fg: var(--toggle-option-selected-fg);
|
|
17
|
+
}
|
|
18
|
+
|
|
10
19
|
@scope (toggle-group-ui) {
|
|
11
20
|
:where(:scope) {
|
|
12
21
|
/* ── Tokens ── */
|
|
@@ -94,10 +103,7 @@ toggle-option-ui:not([disabled]):hover {
|
|
|
94
103
|
z-index: 1;
|
|
95
104
|
}
|
|
96
105
|
|
|
97
|
-
|
|
98
|
-
--toggle-option-bg: var(--toggle-option-selected-bg);
|
|
99
|
-
--toggle-option-fg: var(--toggle-option-selected-fg);
|
|
100
|
-
}
|
|
106
|
+
/* [selected] state rule moved outside @scope — see Safari 17.x bug note at top. */
|
|
101
107
|
|
|
102
108
|
:scope[disabled] {
|
|
103
109
|
--toggle-option-fg: var(--toggle-option-fg-disabled);
|
|
@@ -38,6 +38,11 @@ export class UIToggleOption extends UIElement {
|
|
|
38
38
|
disabled: boolean;
|
|
39
39
|
/** Optional Phosphor icon name; renders as a leading icon. */
|
|
40
40
|
icon: string;
|
|
41
|
+
/** Whether this option is currently selected. Managed by the parent
|
|
42
|
+
<toggle-group-ui> container (ADR-0056) — don't set directly; the group's
|
|
43
|
+
`value` is the single source of truth. Converges onto <segment-ui>'s
|
|
44
|
+
declared reflected-prop mechanism. */
|
|
45
|
+
selected: boolean;
|
|
41
46
|
/** Visible label text. */
|
|
42
47
|
text: string;
|
|
43
48
|
/** Stable identifier matched against the parent group's `value`. */
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Generated by scripts/migrate-yamls-to-v1.mjs — migrated to v1 contract.
|
|
2
2
|
# Edit this file; run `npm run build:components` to regenerate a2ui.json.
|
|
3
|
+
#
|
|
4
|
+
# ADR-0056 (gh#1303): <toggle-option-ui>'s current-state surface converges
|
|
5
|
+
# onto <segment-ui>'s declared, reflected `[selected]` prop (see
|
|
6
|
+
# toggle-option.yaml). This container sets that prop, keeping `value` as the
|
|
7
|
+
# single source of truth.
|
|
3
8
|
$schema: ../../../../scripts/schemas/component.yaml.schema.json
|
|
4
9
|
name: UIToggleGroup
|
|
5
10
|
tag: toggle-group-ui
|
|
@@ -80,6 +85,8 @@ a2ui:
|
|
|
80
85
|
reason: 'Selection model distinction.'
|
|
81
86
|
- rule: 'Use for filter chips, multi-flag toggles, day-of-week pickers; for binary on/off use <switch-ui>.'
|
|
82
87
|
reason: 'Capacity guidance.'
|
|
88
|
+
- rule: 'Sets the child <toggle-option-ui>''s declared [selected] prop to reflect the group value (ADR-0056) — do not author [selected] directly in generated markup; author the group''s value instead.'
|
|
89
|
+
reason: 'Parent-managed declared state — group value stays the single source of truth.'
|
|
83
90
|
anti_patterns: []
|
|
84
91
|
examples:
|
|
85
92
|
- name: basic-toggle-group
|
|
@@ -26,6 +26,11 @@
|
|
|
26
26
|
"type": "string",
|
|
27
27
|
"default": ""
|
|
28
28
|
},
|
|
29
|
+
"selected": {
|
|
30
|
+
"description": "Whether this option is currently selected. Managed by the parent\n<toggle-group-ui> container (ADR-0056) — don't set directly; the group's\n`value` is the single source of truth. Converges onto <segment-ui>'s\ndeclared reflected-prop mechanism.",
|
|
31
|
+
"type": "boolean",
|
|
32
|
+
"default": false
|
|
33
|
+
},
|
|
29
34
|
"text": {
|
|
30
35
|
"description": "Visible label text.",
|
|
31
36
|
"type": "string",
|