@adia-ai/web-components 0.8.42 → 0.8.44
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 +44 -0
- package/MIGRATION.md +130 -80
- package/USAGE.md +1 -1
- package/color/index.js +1 -1
- package/components/action-list/action-item.a2ui.json +3 -8
- package/components/action-list/action-item.yaml +10 -16
- package/components/action-list/action-list.class.js +5 -61
- package/components/action-list/action-list.d.ts +1 -3
- package/components/avatar/avatar.class.js +12 -1
- package/components/button/button.d.ts +4 -0
- package/components/button/button.yaml +1 -1
- package/components/calendar-picker/calendar-picker.a2ui.json +1 -1
- package/components/calendar-picker/calendar-picker.class.js +2 -3
- package/components/calendar-picker/calendar-picker.css +16 -18
- package/components/calendar-picker/calendar-picker.yaml +2 -2
- package/components/card/card.css +3 -3
- package/components/chart/chart.a2ui.json +29 -18
- package/components/chart/chart.class.js +1308 -266
- package/components/chart/chart.css +151 -1
- package/components/chart/chart.d.ts +9 -9
- package/components/chart/chart.yaml +63 -31
- package/components/chart-legend/chart-legend.a2ui.json +20 -14
- package/components/chart-legend/chart-legend.class.js +79 -58
- package/components/chart-legend/chart-legend.css +65 -1
- package/components/chart-legend/chart-legend.d.ts +5 -5
- package/components/chart-legend/chart-legend.examples.md +4 -4
- package/components/chart-legend/chart-legend.yaml +50 -20
- package/components/check/check.css +9 -0
- package/components/color-area/color-area.a2ui.json +1 -1
- package/components/color-area/color-area.class.js +2 -2
- package/components/color-area/color-area.css +4 -7
- package/components/color-area/color-area.d.ts +1 -1
- package/components/color-area/color-area.yaml +3 -3
- package/components/color-input/color-input.a2ui.json +1 -1
- package/components/color-input/color-input.class.js +1 -1
- package/components/color-input/color-input.yaml +2 -2
- package/components/combobox/combobox.a2ui.json +3 -0
- package/components/combobox/combobox.class.js +9 -8
- package/components/combobox/combobox.css +25 -4
- package/components/combobox/combobox.yaml +6 -0
- package/components/command/command.css +17 -1
- package/components/context-menu/context-menu.d.ts +2 -0
- package/components/drilldown/drilldown.a2ui.json +3 -0
- package/components/drilldown/drilldown.css +8 -1
- package/components/drilldown/drilldown.yaml +2 -0
- package/components/field/field.class.js +5 -5
- package/components/heatmap/heatmap.a2ui.json +5 -0
- package/components/heatmap/heatmap.d.ts +2 -0
- package/components/heatmap/heatmap.yaml +8 -0
- package/components/index.js +0 -4
- package/components/input/input.a2ui.json +4 -4
- package/components/input/input.class.js +20 -7
- package/components/input/input.css +6 -0
- package/components/input/input.yaml +15 -11
- package/components/integration-card/integration-card.d.ts +2 -0
- package/components/menu/menu-item.a2ui.json +3 -8
- package/components/menu/menu-item.yaml +13 -21
- package/components/menu/menu.class.js +5 -27
- package/components/menu/menu.d.ts +1 -3
- package/components/noodles/noodles.a2ui.json +0 -15
- package/components/noodles/noodles.yaml +0 -12
- package/components/number-format/number-format.class.js +10 -0
- package/components/pagination/pagination.class.js +88 -4
- package/components/pane/pane.a2ui.json +2 -12
- package/components/pane/pane.class.js +5 -30
- package/components/pane/pane.d.ts +3 -5
- package/components/pane/pane.yaml +7 -19
- package/components/popover/popover.d.ts +2 -0
- package/components/progress/progress.a2ui.json +1 -1
- package/components/progress/progress.class.js +13 -8
- package/components/progress/progress.d.ts +1 -1
- package/components/progress/progress.yaml +2 -2
- package/components/radio/radio.css +7 -0
- package/components/range/range.class.js +9 -1
- package/components/search/search.css +10 -1
- package/components/segment/segment.a2ui.json +1 -2
- package/components/segment/segment.css +10 -0
- package/components/segment/segment.yaml +1 -2
- package/components/segmented/segmented.a2ui.json +1 -3
- package/components/segmented/segmented.class.js +2 -2
- package/components/segmented/segmented.yaml +2 -4
- package/components/select/select.a2ui.json +5 -1
- package/components/select/select.class.js +14 -14
- package/components/select/select.css +20 -1
- package/components/select/select.yaml +7 -1
- package/components/step-progress/step-progress.yaml +1 -1
- package/components/stream/stream.d.ts +2 -0
- package/components/switch/switch.css +8 -0
- package/components/table/table.a2ui.json +6 -1
- package/components/table/table.class.js +18 -1
- package/components/table/table.css +31 -6
- package/components/table/table.d.ts +3 -1
- package/components/table/table.examples.md +2 -2
- package/components/table/table.yaml +9 -1
- package/components/table-toolbar/table-toolbar.a2ui.json +67 -2
- package/components/table-toolbar/table-toolbar.class.js +492 -17
- package/components/table-toolbar/table-toolbar.css +311 -0
- package/components/table-toolbar/table-toolbar.d.ts +17 -1
- package/components/table-toolbar/table-toolbar.yaml +220 -15
- package/components/tag/tag.class.js +13 -1
- package/components/text/text.a2ui.json +3 -3
- package/components/text/text.d.ts +5 -3
- package/components/text/text.yaml +3 -3
- package/components/textarea/textarea.class.js +9 -1
- package/components/textarea/textarea.css +4 -0
- package/components/time-picker/time-picker.yaml +3 -2
- package/components/tour/tour.d.ts +10 -0
- package/components/tree/tree.yaml +1 -1
- package/components/upload/upload.class.js +16 -0
- package/components/upload/upload.d.ts +7 -0
- package/components/upload/upload.yaml +7 -3
- package/core/a11y.d.ts +22 -0
- package/core/a11y.js +64 -0
- package/core/anchor.js +9 -5
- package/core/element.js +1 -1
- package/core/icons.js +2 -5
- package/custom-elements.json +142 -594
- package/dist/host.min.css +1 -1
- package/dist/host.sheet.js +1 -1
- package/dist/theme-provider.min.js +1 -1
- package/dist/web-components.min.css +1 -1
- package/dist/web-components.min.js +122 -119
- package/dist/web-components.sheet.js +1 -1
- package/index.d.ts +0 -15
- package/package.json +1 -1
- package/patterns/access-requests/access-requests.examples.html +1 -1
- package/patterns/admin-keys-and-export/admin-keys-and-export.examples.html +7 -7
- package/patterns/agent-cost/agent-cost.examples.html +6 -6
- package/patterns/agent-memory/agent-memory.examples.html +3 -3
- package/patterns/agent-prompt-library/agent-prompt-library.examples.html +8 -8
- package/patterns/agent-tool-call/agent-tool-call.examples.html +1 -1
- package/patterns/approvals/approvals.examples.html +6 -6
- package/patterns/audit-log/audit-log.examples.html +1 -1
- package/patterns/bulk-action-toolbar/bulk-action-toolbar.examples.html +4 -4
- package/patterns/chart-in-card/chart-in-card.examples.html +124 -10
- package/patterns/chart-in-card/chart-in-card.examples.js +37 -0
- package/patterns/comments-and-collaboration/comments-and-collaboration.examples.html +5 -5
- package/patterns/conversion-funnel/conversion-funnel.html +2 -2
- package/patterns/data-tables-inline-edit-and-tree/data-tables-inline-edit-and-tree.examples.html +2 -2
- package/patterns/diff-review/diff-review.examples.html +6 -6
- package/patterns/editor-shell/editor-shell.examples.html +3 -3
- package/patterns/export-flow/export-flow.examples.html +2 -2
- package/patterns/filter-bar/filter-bar.examples.html +2 -2
- package/patterns/forms-conditional-and-autocomplete/forms-conditional-and-autocomplete.examples.html +2 -2
- package/patterns/inline-dialog/inline-dialog.examples.html +2 -2
- package/patterns/marketing-engagement/marketing-engagement.examples.html +4 -4
- package/patterns/notifications-bell-and-digest/notifications-bell-and-digest.examples.html +1 -1
- package/patterns/permissions-matrix/permissions-matrix.examples.html +1 -1
- package/patterns/permissions-sharing/permissions-sharing.examples.html +2 -2
- package/patterns/profile-public-and-verification/profile-public-and-verification.examples.html +4 -4
- package/patterns/search-discovery/search-discovery.examples.html +2 -2
- package/styles/colors/semantics/features.css +8 -1
- package/styles/components.css +0 -4
- package/styles/type/roles.css +29 -9
- package/traits/arrow-grid-nav/arrow-grid-nav.js +1 -1
- package/traits/resize-observer/resize-observer.js +1 -1
- package/components/color-picker/color-picker.a2ui.json +0 -148
- package/components/color-picker/color-picker.class.js +0 -46
- package/components/color-picker/color-picker.css +0 -14
- package/components/color-picker/color-picker.d.ts +0 -99
- package/components/color-picker/color-picker.examples.md +0 -19
- package/components/color-picker/color-picker.js +0 -17
- package/components/color-picker/color-picker.yaml +0 -175
- package/components/datetime-picker/datetime-picker.a2ui.json +0 -256
- package/components/datetime-picker/datetime-picker.class.js +0 -58
- package/components/datetime-picker/datetime-picker.css +0 -11
- package/components/datetime-picker/datetime-picker.d.ts +0 -87
- package/components/datetime-picker/datetime-picker.examples.md +0 -25
- package/components/datetime-picker/datetime-picker.js +0 -17
- package/components/datetime-picker/datetime-picker.yaml +0 -254
- package/components/progress-row/progress-row.a2ui.json +0 -107
- package/components/progress-row/progress-row.class.js +0 -118
- package/components/progress-row/progress-row.css +0 -60
- package/components/progress-row/progress-row.d.ts +0 -24
- package/components/progress-row/progress-row.examples.md +0 -7
- package/components/progress-row/progress-row.js +0 -17
- package/components/progress-row/progress-row.yaml +0 -85
- package/components/toggle-group/toggle-group.a2ui.json +0 -148
- package/components/toggle-group/toggle-group.class.js +0 -195
- package/components/toggle-group/toggle-group.css +0 -127
- package/components/toggle-group/toggle-group.d.ts +0 -50
- package/components/toggle-group/toggle-group.examples.md +0 -33
- package/components/toggle-group/toggle-group.js +0 -18
- package/components/toggle-group/toggle-group.yaml +0 -135
- package/components/toggle-group/toggle-option.a2ui.json +0 -86
- package/components/toggle-group/toggle-option.yaml +0 -75
|
@@ -18,10 +18,38 @@
|
|
|
18
18
|
--table-toolbar-title-weight: var(--a-weight-medium);
|
|
19
19
|
--table-toolbar-title-gap: var(--a-space-2);
|
|
20
20
|
|
|
21
|
+
/* ── Range summary ("Showing X–Y of N") ── */
|
|
22
|
+
--table-toolbar-summary-fg: var(--md-sys-color-neutral-on-surface-variant);
|
|
23
|
+
--table-toolbar-summary-size: var(--a-ui-size);
|
|
24
|
+
|
|
21
25
|
/* ── Search ── */
|
|
22
26
|
--table-toolbar-search-min: 14rem;
|
|
23
27
|
--table-toolbar-search-max: 22rem;
|
|
24
28
|
|
|
29
|
+
/* ── Search-tight stage (ADR-0076, REQ-S-002) ──
|
|
30
|
+
Stepped-down search field extents applied under the
|
|
31
|
+
search-tight/icon-only/overflow @container query below (or the
|
|
32
|
+
matching [stage] pin). Public so a consumer can retune the
|
|
33
|
+
compacted width without forking component CSS, same posture as
|
|
34
|
+
every other --table-toolbar-* token. */
|
|
35
|
+
--table-toolbar-search-tight-min: 9rem;
|
|
36
|
+
--table-toolbar-search-tight-max: 14rem;
|
|
37
|
+
|
|
38
|
+
/* ── Compaction breakpoints (ADR-0076, REQ-M-006) ──
|
|
39
|
+
Normative default pixel widths, token-indirected so a consumer can
|
|
40
|
+
retune without forking component CSS. Boundaries are inclusive on
|
|
41
|
+
the narrower side (max-width semantics) — a container at exactly
|
|
42
|
+
the boundary width renders the narrower of the two adjacent
|
|
43
|
+
stages. MUST stay monotonically decreasing
|
|
44
|
+
(bp-search-tight > bp-icon-only > bp-overflow); no stage-specific
|
|
45
|
+
@container rules exist yet (step 1 lands only this substrate —
|
|
46
|
+
steps 2/3/5 land each stage's own CSS). Same three thresholds
|
|
47
|
+
data-stage-resolved's ResizeObserver (step 7) will classify
|
|
48
|
+
against — one source of truth, never a second hardcoded copy. */
|
|
49
|
+
--table-toolbar-bp-search-tight: 56rem;
|
|
50
|
+
--table-toolbar-bp-icon-only: 40rem;
|
|
51
|
+
--table-toolbar-bp-overflow: 26rem;
|
|
52
|
+
|
|
25
53
|
/* Popover tokens removed — popover escapes to top layer and
|
|
26
54
|
cannot inherit @scope tokens. Raw --a-* tokens are used
|
|
27
55
|
directly in the unscoped popover rules below (see comment
|
|
@@ -34,6 +62,151 @@
|
|
|
34
62
|
box-sizing: border-box;
|
|
35
63
|
display: block;
|
|
36
64
|
color: var(--md-sys-color-neutral-on-surface);
|
|
65
|
+
/* Width-only compaction measurement substrate (ADR-0076, REQ-M-001).
|
|
66
|
+
inline-size containment only — never `size` — per chart.css's own
|
|
67
|
+
documented size-containment trap (container-type: size forces
|
|
68
|
+
block-size containment, collapsing any height-less element; chart
|
|
69
|
+
needs it only because it queries aspect-ratio, table-toolbar's axis
|
|
70
|
+
is width alone). Steps 3/5 land icon-only/overflow's own CSS
|
|
71
|
+
against this same container. */
|
|
72
|
+
container-type: inline-size;
|
|
73
|
+
container-name: table-toolbar;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* ═══════ Search-tight stage ═══════ (ADR-0076, REQ-S-002/REQ-O-001, step 2)
|
|
77
|
+
Auto-snap: the container query fires the step-down once the toolbar's
|
|
78
|
+
own inline-size crosses --table-toolbar-bp-search-tight (56rem
|
|
79
|
+
default). `max-width` is inclusive-on-the-narrower-side by construction
|
|
80
|
+
(REQ-M-006) — a container at exactly the boundary width already renders
|
|
81
|
+
search-tight. `:not([stage])`/`[stage=""]` together cover "no pin" —
|
|
82
|
+
an explicit [stage="full"] pin must NOT auto-snap even inside a narrow
|
|
83
|
+
container (REQ-O-001, the pin wins), so the auto-snap selector
|
|
84
|
+
excludes every OTHER pinned value too.
|
|
85
|
+
|
|
86
|
+
BUG (caught in review, CodeRabbit on PR #1672, verified live in a real
|
|
87
|
+
browser before fixing): the token reassignment below targets
|
|
88
|
+
`[data-toolbar]`, a DESCENDANT of `:scope` — never `:scope` itself. A
|
|
89
|
+
container query only matches elements whose NEAREST ANCESTOR
|
|
90
|
+
establishes the named container; the container element is never its
|
|
91
|
+
own ancestor, so `@container table-toolbar (...) { :scope { ... } }`
|
|
92
|
+
can never match the host that declared `container-type` in the first
|
|
93
|
+
place — it's permanently-dead CSS, regardless of the container's
|
|
94
|
+
actual width. The custom properties still cascade correctly from
|
|
95
|
+
`[data-toolbar]` down to `[data-search]` (a further descendant), so
|
|
96
|
+
targeting the wrapper one level down is both the fix and the reason
|
|
97
|
+
it works: normal inheritance, no container-query involvement needed
|
|
98
|
+
for the property to reach its consumer.
|
|
99
|
+
|
|
100
|
+
CSS custom properties cannot be referenced inside an `@container` size
|
|
101
|
+
query's condition (only `style()` container queries read custom
|
|
102
|
+
properties, and those query computed values, not literal breakpoints)
|
|
103
|
+
— so the boundary below is the literal `56rem`, bound in this comment
|
|
104
|
+
to --table-toolbar-bp-search-tight's own default one line above; the
|
|
105
|
+
table-toolbar.test.js source-assertion suite pins the two values equal
|
|
106
|
+
so this literal can never silently drift from the token. */
|
|
107
|
+
@container table-toolbar (max-width: 56rem) {
|
|
108
|
+
:scope:is(:not([stage]), [stage=""]) > [data-toolbar] {
|
|
109
|
+
--table-toolbar-search-min: var(--table-toolbar-search-tight-min);
|
|
110
|
+
--table-toolbar-search-max: var(--table-toolbar-search-tight-max);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* Explicit pin (REQ-O-001) — forces the search-tight extents regardless
|
|
115
|
+
of the container's actual measured width. Also applies at
|
|
116
|
+
[stage="icon-only"]/[stage="overflow"] (steps 3/5's own, MORE compact
|
|
117
|
+
pins): each later stage is strictly more compact than the last
|
|
118
|
+
(REQ-S), so the search field never widens back out just because a
|
|
119
|
+
tighter stage hasn't landed its own CSS yet. */
|
|
120
|
+
:scope:is([stage="search-tight"], [stage="icon-only"], [stage="overflow"]) {
|
|
121
|
+
--table-toolbar-search-min: var(--table-toolbar-search-tight-min);
|
|
122
|
+
--table-toolbar-search-max: var(--table-toolbar-search-tight-max);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* ═══════ Icon-only stage ═══════ (ADR-0076, REQ-S-003/REQ-M-003/REQ-M-004,
|
|
126
|
+
step 3) — [data-controls] buttons drop their rendered label; the range
|
|
127
|
+
summary's own compaction/hide (REQ-S-003, step 4) rides the SAME
|
|
128
|
+
breakpoint just below, since both are decided by the same container
|
|
129
|
+
crossing --table-toolbar-bp-icon-only.
|
|
130
|
+
|
|
131
|
+
::after content:none overrides button.css's own `:scope[text]::after {
|
|
132
|
+
content: attr(text) }` generated-content rule (REQ-M-003) — aria-label
|
|
133
|
+
is untouched (button-ui stamps it from [text] unconditionally in its
|
|
134
|
+
own render(), REQ-X-001), so the accessible name survives regardless of
|
|
135
|
+
the CSS-hidden visual label. The selector below is deliberately more
|
|
136
|
+
specific than button.css's own (adds the `:scope` ancestor + `[text]`)
|
|
137
|
+
so it wins the cascade outright rather than relying on scope-proximity
|
|
138
|
+
tie-breaking, which would resolve in button.css's OWN favor at equal
|
|
139
|
+
specificity (its rule is proximity-0 to its own host). Geometry mirrors
|
|
140
|
+
button-ui's own [data-icon-only] treatment exactly (REQ-M-004) —
|
|
141
|
+
--button-px/width are button-ui's own exposed tokens, set here from the
|
|
142
|
+
table-toolbar side the same way [data-sort-row][data-active] overrides
|
|
143
|
+
menu-item-ui's tokens above. Literal `40rem` bound to
|
|
144
|
+
--table-toolbar-bp-icon-only's default (same duplication rationale +
|
|
145
|
+
source-assertion test as the search-tight boundary above). */
|
|
146
|
+
@container table-toolbar (max-width: 40rem) {
|
|
147
|
+
:scope:is(:not([stage]), [stage=""]) [data-toolbar-btn][text]::after {
|
|
148
|
+
content: none;
|
|
149
|
+
}
|
|
150
|
+
:scope:is(:not([stage]), [stage=""]) [data-toolbar-btn] {
|
|
151
|
+
--button-px: 0;
|
|
152
|
+
|
|
153
|
+
width: var(--button-height);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
:scope:is([stage="icon-only"], [stage="overflow"]) [data-toolbar-btn][text]::after {
|
|
158
|
+
content: none;
|
|
159
|
+
}
|
|
160
|
+
:scope:is([stage="icon-only"], [stage="overflow"]) [data-toolbar-btn] {
|
|
161
|
+
--button-px: 0;
|
|
162
|
+
|
|
163
|
+
width: var(--button-height);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/* ═══════ Range-summary conditional compact/hide ═══════ (ADR-0076
|
|
167
|
+
REQ-S-003, step 4) — at the SAME icon-only breakpoint as above:
|
|
168
|
+
- [data-page-size] present AND visible (no [hidden]) → its own
|
|
169
|
+
pagination context already carries the range info, so [data-summary]
|
|
170
|
+
hides entirely (its info is genuinely redundant here).
|
|
171
|
+
- [data-page-size] absent/hidden → [data-summary] is the toolbar's
|
|
172
|
+
ONLY visible range context, so it never fully disappears; instead
|
|
173
|
+
it swaps its full text for the short form (see [data-summary-compact]
|
|
174
|
+
below, "1–25/320" vs "Showing 1–25 of 320").
|
|
175
|
+
Which branch applies is a pure :has()/:not() container-width read — no
|
|
176
|
+
JS drives this (REQ-M-002); #updateSummary() populates BOTH
|
|
177
|
+
[data-summary-text] and [data-summary-compact] together whenever a
|
|
178
|
+
valid range exists, and CSS alone decides which one paints. */
|
|
179
|
+
@container table-toolbar (max-width: 40rem) {
|
|
180
|
+
:scope:is(:not([stage]), [stage=""]):has([data-page-size]:not([hidden])) [data-summary] {
|
|
181
|
+
display: none;
|
|
182
|
+
}
|
|
183
|
+
:scope:is(:not([stage]), [stage=""]):not(:has([data-page-size]:not([hidden]))) [data-summary-text] {
|
|
184
|
+
display: none;
|
|
185
|
+
}
|
|
186
|
+
/* :not([hidden]) — reviewer finding on PR #1674: without it, this
|
|
187
|
+
author-origin `display: inline` OUTRANKS the UA-origin
|
|
188
|
+
`[hidden] { display: none }` rule regardless of specificity (origin
|
|
189
|
+
comes before specificity in the cascade), so a JS-hidden
|
|
190
|
+
[data-summary-compact] (#updateSummary()'s empty-slot/loading
|
|
191
|
+
branches, which set compact.hidden = true) would still paint —
|
|
192
|
+
stale compact text alongside the empty-state content after a
|
|
193
|
+
positive range transitions to range-total="0" in icon-only mode.
|
|
194
|
+
Same class of gotcha this file already reinforces explicitly for
|
|
195
|
+
every other JS-toggled node ([data-toolbar-btn][hidden],
|
|
196
|
+
[data-search][hidden], [data-toolbar-overflow][hidden], etc). */
|
|
197
|
+
:scope:is(:not([stage]), [stage=""]):not(:has([data-page-size]:not([hidden]))) [data-summary-compact]:not([hidden]) {
|
|
198
|
+
display: inline;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
:scope:is([stage="icon-only"], [stage="overflow"]):has([data-page-size]:not([hidden])) [data-summary] {
|
|
203
|
+
display: none;
|
|
204
|
+
}
|
|
205
|
+
:scope:is([stage="icon-only"], [stage="overflow"]):not(:has([data-page-size]:not([hidden]))) [data-summary-text] {
|
|
206
|
+
display: none;
|
|
207
|
+
}
|
|
208
|
+
:scope:is([stage="icon-only"], [stage="overflow"]):not(:has([data-page-size]:not([hidden]))) [data-summary-compact]:not([hidden]) {
|
|
209
|
+
display: inline;
|
|
37
210
|
}
|
|
38
211
|
|
|
39
212
|
[data-toolbar] {
|
|
@@ -68,6 +241,17 @@
|
|
|
68
241
|
--table-toolbar-px: var(--a-space-4);
|
|
69
242
|
}
|
|
70
243
|
|
|
244
|
+
/* ═══════ Scope slot ═══════ (gh#1615 — leading region before the title cluster) */
|
|
245
|
+
|
|
246
|
+
[data-scope] {
|
|
247
|
+
display: inline-flex;
|
|
248
|
+
align-items: center;
|
|
249
|
+
gap: var(--table-toolbar-cluster-gap);
|
|
250
|
+
flex: 0 0 auto;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
[data-scope]:empty { display: none; }
|
|
254
|
+
|
|
71
255
|
/* ═══════ Title cluster ═══════ */
|
|
72
256
|
|
|
73
257
|
[data-title] {
|
|
@@ -87,6 +271,40 @@
|
|
|
87
271
|
|
|
88
272
|
[data-toolbar-count-badge][hidden] { display: none; }
|
|
89
273
|
|
|
274
|
+
/* ═══════ Range summary ═══════ (gh#1615 — "Showing X–Y of N", independent of [data-title]) */
|
|
275
|
+
|
|
276
|
+
[data-summary] {
|
|
277
|
+
flex: 0 0 auto;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
[data-summary][hidden] { display: none; }
|
|
281
|
+
|
|
282
|
+
[data-summary-text] {
|
|
283
|
+
font-size: var(--table-toolbar-summary-size);
|
|
284
|
+
color: var(--table-toolbar-summary-fg);
|
|
285
|
+
line-height: var(--a-font-leading-snug);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* Short-form compact text ("1–25/320", ADR-0076 REQ-S-003) — hidden by
|
|
289
|
+
default (`display: none`, not just [hidden]) since it only ever paints
|
|
290
|
+
inside the icon-only-without-page-size branch above; that branch is the
|
|
291
|
+
ONLY place this flips to `display: inline`. Same typography as
|
|
292
|
+
[data-summary-text] — it's the same information, just terser. */
|
|
293
|
+
[data-summary-compact] {
|
|
294
|
+
display: none;
|
|
295
|
+
font-size: var(--table-toolbar-summary-size);
|
|
296
|
+
color: var(--table-toolbar-summary-fg);
|
|
297
|
+
line-height: var(--a-font-leading-snug);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/* ═══════ Empty-state slot ═══════ (ADR-0076 REQ-E — renders in
|
|
301
|
+
[data-summary]'s own position, alongside [data-summary-text]; only one
|
|
302
|
+
of the two is ever visible at a time, per #updateSummary(). Plain
|
|
303
|
+
author-supplied markup (REQ-E-003) — no forced typography here, unlike
|
|
304
|
+
[data-summary-text] above, which styles OUR OWN generated text. */
|
|
305
|
+
|
|
306
|
+
[data-summary-empty][hidden] { display: none; }
|
|
307
|
+
|
|
90
308
|
/* ═══════ Controls cluster ═══════ */
|
|
91
309
|
|
|
92
310
|
[data-controls] {
|
|
@@ -96,8 +314,63 @@
|
|
|
96
314
|
flex: 0 0 auto;
|
|
97
315
|
}
|
|
98
316
|
|
|
317
|
+
/* ADR-0076 REQ-C-003 — with [chrome-only] set, all three buttons carry
|
|
318
|
+
[hidden] (see #updateControlVisibility()); this collapses the cluster
|
|
319
|
+
to zero footprint via the same :empty{display:none} shape [data-scope]/
|
|
320
|
+
[data-actions]/[data-actions-leading] already use above, defensively
|
|
321
|
+
covering the case where no button children are stamped at all. */
|
|
322
|
+
[data-controls]:empty { display: none; }
|
|
323
|
+
|
|
99
324
|
[data-toolbar-btn][hidden] { display: none; }
|
|
100
325
|
|
|
326
|
+
/* ═══════ Overflow stage ═══════ (ADR-0076 REQ-S-004/REQ-X-003/004,
|
|
327
|
+
PLAN step 5) — collapses Filter/Sort/Columns into one "More" trigger
|
|
328
|
+
at the tightest breakpoint. The three granular buttons STAY in the
|
|
329
|
+
DOM (never created/destroyed across a stage transition — the simplest
|
|
330
|
+
way to keep REQ-X-004's tab-order guarantee correct); CSS alone
|
|
331
|
+
decides which cluster paints (REQ-M-002). [data-toolbar-overflow] is
|
|
332
|
+
the <menu-ui> wrapper stamped by #mkOverflowTrigger() — hiding/showing
|
|
333
|
+
it hides/shows its [slot="trigger"] button together with its (closed)
|
|
334
|
+
menu-item-ui children in one rule, matching how every other stage
|
|
335
|
+
toggle in this file targets one wrapper element rather than each
|
|
336
|
+
child individually. Literal `26rem` bound to
|
|
337
|
+
--table-toolbar-bp-overflow's own default (same duplication +
|
|
338
|
+
source-assertion discipline as the search-tight/icon-only boundaries
|
|
339
|
+
above). */
|
|
340
|
+
[data-toolbar-overflow] { display: none; }
|
|
341
|
+
|
|
342
|
+
@container table-toolbar (max-width: 26rem) {
|
|
343
|
+
:scope:is(:not([stage]), [stage=""]) [data-toolbar-btn] {
|
|
344
|
+
display: none;
|
|
345
|
+
}
|
|
346
|
+
:scope:is(:not([stage]), [stage=""]) [data-toolbar-overflow] {
|
|
347
|
+
display: inline-flex;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
:scope[stage="overflow"] [data-toolbar-btn] {
|
|
352
|
+
display: none;
|
|
353
|
+
}
|
|
354
|
+
:scope[stage="overflow"] [data-toolbar-overflow] {
|
|
355
|
+
display: inline-flex;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/* [hidden] (per-kind chrome-only/no-* suppression, #updateControlVisibility())
|
|
359
|
+
must win over the stage-driven `display: inline-flex` rules above —
|
|
360
|
+
both for the reason `[data-toolbar-btn][hidden]`/`[data-search][hidden]`
|
|
361
|
+
etc reinforce it above (the browser's own UA-origin `[hidden]{display:
|
|
362
|
+
none}` rule is LOWER origin priority than any author rule, so an
|
|
363
|
+
unreinforced [hidden] would lose to author CSS) AND because this
|
|
364
|
+
selector must match or exceed the (0,3,0) specificity of the
|
|
365
|
+
`:scope … [data-toolbar-overflow]` show-rules above to win the tie —
|
|
366
|
+
`:scope [data-toolbar-overflow][hidden]` (0,3,0), placed after both in
|
|
367
|
+
source order, satisfies that. This covers the whole-trigger-suppressed
|
|
368
|
+
case (chrome-only, or all three no-* set) — the per-menu-item-ui
|
|
369
|
+
hidden state inside the (closed) menu needs no CSS help since
|
|
370
|
+
[hidden]'s UA default applies cleanly to a plain child with no
|
|
371
|
+
conflicting author rule. */
|
|
372
|
+
:scope [data-toolbar-overflow][hidden] { display: none; }
|
|
373
|
+
|
|
101
374
|
/* ═══════ Search ═══════ */
|
|
102
375
|
|
|
103
376
|
[data-search] {
|
|
@@ -111,6 +384,44 @@
|
|
|
111
384
|
|
|
112
385
|
[data-search][hidden] { display: none; }
|
|
113
386
|
|
|
387
|
+
/* ═══════ Actions-leading slot ═══════ (gh#1649 — app-owned triggers, e.g.
|
|
388
|
+
custom Filter/Columns buttons, that land BEFORE the page-size select)
|
|
389
|
+
Carries the SAME margin-inline-start:auto as [data-search]/[data-page-size]
|
|
390
|
+
so the trailing group still pushes to the far edge even when EVERY
|
|
391
|
+
native affordance ahead of it is dropped ([no-search] + [no-filter]/
|
|
392
|
+
[no-sort]/[no-columns], the adiav2 shape) and this slot becomes the
|
|
393
|
+
first visible member of the trailing cluster. Multiple auto-margin
|
|
394
|
+
siblings in one flex row is safe — only the first one with unclaimed
|
|
395
|
+
free space to its left actually receives it (same note as [data-page-size]
|
|
396
|
+
below). */
|
|
397
|
+
|
|
398
|
+
[data-actions-leading] {
|
|
399
|
+
display: inline-flex;
|
|
400
|
+
align-items: center;
|
|
401
|
+
gap: var(--table-toolbar-cluster-gap);
|
|
402
|
+
flex: 0 0 auto;
|
|
403
|
+
margin-inline-start: auto;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
[data-actions-leading]:empty { display: none; }
|
|
407
|
+
|
|
408
|
+
/* ═══════ Page-size select ═══════ (gh#1615)
|
|
409
|
+
Carries the SAME margin-inline-start:auto as [data-search] so the
|
|
410
|
+
trailing group (controls/search/page-size/actions) still pushes to the
|
|
411
|
+
far edge when [no-search] drops search — without changing search's own
|
|
412
|
+
existing default for consumers that never set [page-size-options]
|
|
413
|
+
(the element doesn't render at all until then; see [hidden] below and
|
|
414
|
+
#updatePageSizeSelect). Multiple auto-margin siblings in one flex row
|
|
415
|
+
is safe — only the first one with unclaimed free space to its left
|
|
416
|
+
actually receives it. */
|
|
417
|
+
|
|
418
|
+
[data-page-size] {
|
|
419
|
+
flex: 0 0 auto;
|
|
420
|
+
margin-inline-start: auto;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
[data-page-size][hidden] { display: none; }
|
|
424
|
+
|
|
114
425
|
/* ═══════ Actions slot ═══════ */
|
|
115
426
|
|
|
116
427
|
[data-actions] {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `<table-toolbar-ui>` — Header / companion bar for a sibling table-ui. Renders title + count badge, filter / sort / columns popovers,
|
|
2
|
+
* `<table-toolbar-ui>` — Header / companion bar for a sibling table-ui. Renders an optional leading [slot="scope"] region, title + count badge, an optional "Showing X–Y of N" range summary, filter / sort / columns popovers, a search input, an optional [slot="actions-leading"] region, an optional page-size select, and a trailing [slot="actions"] region — all wired to the target table via an [for] id-ref. Modeled on chart-legend-ui's [for] binding pattern. Drop next to (or above) any table-ui to add the standard data-grid toolbar without re-implementing search, filter, sort, column visibility, or pagination summary/page-size. Filter rows auto-pick a primitive per column: ≤ 50 distinct values → multi-select (searchable when ≥ 12 options), id-like keys → free-text contains. The column descriptor's `filter` field overrides the auto-detect: `'select'` forces multi-select even on high-cardinality columns; `'text'` forces a contains input even on small enums.
|
|
3
3
|
*
|
|
4
4
|
* @see https://ui-kit.exe.xyz/site/components/table-toolbar
|
|
5
5
|
*
|
|
@@ -14,10 +14,13 @@ import { UIElement } from '../../core/element.js';
|
|
|
14
14
|
|
|
15
15
|
export type TableToolbarColumnsChangeEvent = CustomEvent<unknown>;
|
|
16
16
|
export type TableToolbarFilterChangeEvent = CustomEvent<unknown>;
|
|
17
|
+
export type TableToolbarPageSizeChangeEvent = CustomEvent<unknown>;
|
|
17
18
|
export type TableToolbarSearchEvent = CustomEvent<unknown>;
|
|
18
19
|
export type TableToolbarSortChangeEvent = CustomEvent<unknown>;
|
|
19
20
|
|
|
20
21
|
export class UITableToolbar extends UIElement {
|
|
22
|
+
/** Suppress all four native controls/search at once (filter, sort, columns, search) as additive sugar over noFilter/noSort/noColumns/ noSearch (ADR-0076, ADIA2-9123). Precedence is pure, absolute OR — while set, all four stay off regardless of any individual no-* attribute's own value, with no partial re-enable path; to re-enable one control, remove chrome-only entirely and set the other three no-* attributes explicitly instead. The four granular attributes are not deprecated or removed — they remain the independently-addressable shipped API; chrome-only never replaces them, it's a convenience preset on top. */
|
|
23
|
+
chromeOnly: boolean;
|
|
21
24
|
/** Optional count badge value shown next to the title. When unset, falls back to the row count of the bound table. */
|
|
22
25
|
count: string;
|
|
23
26
|
/** id-ref of the table-ui to control. Falls back to the first sibling table-ui within the same parent when omitted. */
|
|
@@ -30,8 +33,20 @@ export class UITableToolbar extends UIElement {
|
|
|
30
33
|
noSearch: boolean;
|
|
31
34
|
/** Hide the Sort popover button. Sort is shown by default; set to opt out. */
|
|
32
35
|
noSort: boolean;
|
|
36
|
+
/** Current rows-per-page value, shown as the selected option in the page-size select. Falls back to the first entry of pageSizeOptions when unset (0) or not present among the options. Applied directly to the bound table's own [paginate] prop (rows-per-page), the same way filter/sort/columns changes are applied to the target — mirror this prop only to reflect state to URL / persistence / analytics. */
|
|
37
|
+
pageSize: number;
|
|
38
|
+
/** Rows-per-page choices rendered as `<option>`s in the page-size select (e.g. `[10, 25, 50, 100]`). JS property (`.pageSizeOptions = [...]`), or a declarative JSON-array `page-size-options="[10,25,50]"` attribute hydrated once at connect — the same dynamic-array pattern table-ui's own `columns`/`data` props use. Empty (the default) hides the page-size select entirely — additive opt-in, no footprint on existing consumers. */
|
|
39
|
+
pageSizeOptions: string;
|
|
33
40
|
/** Placeholder text for the search input. */
|
|
34
41
|
placeholder: string;
|
|
42
|
+
/** 1-indexed last row number of the current page, for the range summary (e.g. `25` in "Showing 1–25 of 320"). See rangeStart. */
|
|
43
|
+
rangeEnd: number;
|
|
44
|
+
/** 1-indexed first row number of the current page, for the "Showing X–Y of N" range summary (e.g. `1` in "Showing 1–25 of 320"). Renders alongside — never in place of — [text]/[count]; the range summary is its own cluster, independent of the title cluster. All three of rangeStart/rangeEnd/rangeTotal must be set (> 0) for the summary to render; omit all three (the default) to opt out entirely. */
|
|
45
|
+
rangeStart: number;
|
|
46
|
+
/** Total row count across all pages, for the range summary (e.g. `320` in "Showing 1–25 of 320"). Distinct from pagination-ui's `total` (total PAGES) — this is total ROWS; deliberately not spelled `total` to avoid that cross-sibling name collision (ADR-0063 B5). See rangeStart. */
|
|
47
|
+
rangeTotal: number;
|
|
48
|
+
/** Explicit compaction-stage override (ADR-0076). Unset (the default, empty string) means auto-snap: the toolbar's own inline-size container query picks the nearest stage from its live width against the three --table-toolbar-bp-* breakpoints, snapping discretely, never interpolating. Setting stage explicitly pins that stage's rendering regardless of the container's actual width — overriding the container query, mirroring chart-ui's ratio override shape. Primary use: visual-eval fixtures that need a deterministic stage without resizing a real container, and a consumer embedding the toolbar inside a known-narrow panel who wants to skip auto-detection entirely. All four stages' CSS is now live (ADR-0076): search-tight steps the search field down (step 2); icon-only drops control labels and compacts/hides the range summary (steps 3+4); overflow collapses Filter/Sort/Columns into one "More" trigger routed through the same menu-ui/menu-item-ui pattern used elsewhere in the corpus (step 5). The resolved stage — the pin if set, otherwise the live width classification — also reflects onto the host as `data-stage-resolved` (step 7, informational only, mirrors chart-ui's `data-ratio-resolved` convention — never drives table-toolbar's own rendering, which stays 100% CSS-driven). */
|
|
49
|
+
stage: '' | 'full' | 'search-tight' | 'icon-only' | 'overflow';
|
|
35
50
|
/** Title text shown on the left. */
|
|
36
51
|
text: string;
|
|
37
52
|
/** Toolbar visual variant. `default` renders bare on parent surface; `card` adds the same chrome as a card-ui header. */
|
|
@@ -39,6 +54,7 @@ export class UITableToolbar extends UIElement {
|
|
|
39
54
|
|
|
40
55
|
addEventListener(type: 'columns-change', listener: (ev: TableToolbarColumnsChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
41
56
|
addEventListener(type: 'filter-change', listener: (ev: TableToolbarFilterChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
57
|
+
addEventListener(type: 'page-size-change', listener: (ev: TableToolbarPageSizeChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
42
58
|
addEventListener(type: 'search', listener: (ev: TableToolbarSearchEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
43
59
|
addEventListener(type: 'sort-change', listener: (ev: TableToolbarSortChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
44
60
|
addEventListener<K extends keyof HTMLElementEventMap>(
|