@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.
Files changed (186) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/MIGRATION.md +130 -80
  3. package/USAGE.md +1 -1
  4. package/color/index.js +1 -1
  5. package/components/action-list/action-item.a2ui.json +3 -8
  6. package/components/action-list/action-item.yaml +10 -16
  7. package/components/action-list/action-list.class.js +5 -61
  8. package/components/action-list/action-list.d.ts +1 -3
  9. package/components/avatar/avatar.class.js +12 -1
  10. package/components/button/button.d.ts +4 -0
  11. package/components/button/button.yaml +1 -1
  12. package/components/calendar-picker/calendar-picker.a2ui.json +1 -1
  13. package/components/calendar-picker/calendar-picker.class.js +2 -3
  14. package/components/calendar-picker/calendar-picker.css +16 -18
  15. package/components/calendar-picker/calendar-picker.yaml +2 -2
  16. package/components/card/card.css +3 -3
  17. package/components/chart/chart.a2ui.json +29 -18
  18. package/components/chart/chart.class.js +1308 -266
  19. package/components/chart/chart.css +151 -1
  20. package/components/chart/chart.d.ts +9 -9
  21. package/components/chart/chart.yaml +63 -31
  22. package/components/chart-legend/chart-legend.a2ui.json +20 -14
  23. package/components/chart-legend/chart-legend.class.js +79 -58
  24. package/components/chart-legend/chart-legend.css +65 -1
  25. package/components/chart-legend/chart-legend.d.ts +5 -5
  26. package/components/chart-legend/chart-legend.examples.md +4 -4
  27. package/components/chart-legend/chart-legend.yaml +50 -20
  28. package/components/check/check.css +9 -0
  29. package/components/color-area/color-area.a2ui.json +1 -1
  30. package/components/color-area/color-area.class.js +2 -2
  31. package/components/color-area/color-area.css +4 -7
  32. package/components/color-area/color-area.d.ts +1 -1
  33. package/components/color-area/color-area.yaml +3 -3
  34. package/components/color-input/color-input.a2ui.json +1 -1
  35. package/components/color-input/color-input.class.js +1 -1
  36. package/components/color-input/color-input.yaml +2 -2
  37. package/components/combobox/combobox.a2ui.json +3 -0
  38. package/components/combobox/combobox.class.js +9 -8
  39. package/components/combobox/combobox.css +25 -4
  40. package/components/combobox/combobox.yaml +6 -0
  41. package/components/command/command.css +17 -1
  42. package/components/context-menu/context-menu.d.ts +2 -0
  43. package/components/drilldown/drilldown.a2ui.json +3 -0
  44. package/components/drilldown/drilldown.css +8 -1
  45. package/components/drilldown/drilldown.yaml +2 -0
  46. package/components/field/field.class.js +5 -5
  47. package/components/heatmap/heatmap.a2ui.json +5 -0
  48. package/components/heatmap/heatmap.d.ts +2 -0
  49. package/components/heatmap/heatmap.yaml +8 -0
  50. package/components/index.js +0 -4
  51. package/components/input/input.a2ui.json +4 -4
  52. package/components/input/input.class.js +20 -7
  53. package/components/input/input.css +6 -0
  54. package/components/input/input.yaml +15 -11
  55. package/components/integration-card/integration-card.d.ts +2 -0
  56. package/components/menu/menu-item.a2ui.json +3 -8
  57. package/components/menu/menu-item.yaml +13 -21
  58. package/components/menu/menu.class.js +5 -27
  59. package/components/menu/menu.d.ts +1 -3
  60. package/components/noodles/noodles.a2ui.json +0 -15
  61. package/components/noodles/noodles.yaml +0 -12
  62. package/components/number-format/number-format.class.js +10 -0
  63. package/components/pagination/pagination.class.js +88 -4
  64. package/components/pane/pane.a2ui.json +2 -12
  65. package/components/pane/pane.class.js +5 -30
  66. package/components/pane/pane.d.ts +3 -5
  67. package/components/pane/pane.yaml +7 -19
  68. package/components/popover/popover.d.ts +2 -0
  69. package/components/progress/progress.a2ui.json +1 -1
  70. package/components/progress/progress.class.js +13 -8
  71. package/components/progress/progress.d.ts +1 -1
  72. package/components/progress/progress.yaml +2 -2
  73. package/components/radio/radio.css +7 -0
  74. package/components/range/range.class.js +9 -1
  75. package/components/search/search.css +10 -1
  76. package/components/segment/segment.a2ui.json +1 -2
  77. package/components/segment/segment.css +10 -0
  78. package/components/segment/segment.yaml +1 -2
  79. package/components/segmented/segmented.a2ui.json +1 -3
  80. package/components/segmented/segmented.class.js +2 -2
  81. package/components/segmented/segmented.yaml +2 -4
  82. package/components/select/select.a2ui.json +5 -1
  83. package/components/select/select.class.js +14 -14
  84. package/components/select/select.css +20 -1
  85. package/components/select/select.yaml +7 -1
  86. package/components/step-progress/step-progress.yaml +1 -1
  87. package/components/stream/stream.d.ts +2 -0
  88. package/components/switch/switch.css +8 -0
  89. package/components/table/table.a2ui.json +6 -1
  90. package/components/table/table.class.js +18 -1
  91. package/components/table/table.css +31 -6
  92. package/components/table/table.d.ts +3 -1
  93. package/components/table/table.examples.md +2 -2
  94. package/components/table/table.yaml +9 -1
  95. package/components/table-toolbar/table-toolbar.a2ui.json +67 -2
  96. package/components/table-toolbar/table-toolbar.class.js +492 -17
  97. package/components/table-toolbar/table-toolbar.css +311 -0
  98. package/components/table-toolbar/table-toolbar.d.ts +17 -1
  99. package/components/table-toolbar/table-toolbar.yaml +220 -15
  100. package/components/tag/tag.class.js +13 -1
  101. package/components/text/text.a2ui.json +3 -3
  102. package/components/text/text.d.ts +5 -3
  103. package/components/text/text.yaml +3 -3
  104. package/components/textarea/textarea.class.js +9 -1
  105. package/components/textarea/textarea.css +4 -0
  106. package/components/time-picker/time-picker.yaml +3 -2
  107. package/components/tour/tour.d.ts +10 -0
  108. package/components/tree/tree.yaml +1 -1
  109. package/components/upload/upload.class.js +16 -0
  110. package/components/upload/upload.d.ts +7 -0
  111. package/components/upload/upload.yaml +7 -3
  112. package/core/a11y.d.ts +22 -0
  113. package/core/a11y.js +64 -0
  114. package/core/anchor.js +9 -5
  115. package/core/element.js +1 -1
  116. package/core/icons.js +2 -5
  117. package/custom-elements.json +142 -594
  118. package/dist/host.min.css +1 -1
  119. package/dist/host.sheet.js +1 -1
  120. package/dist/theme-provider.min.js +1 -1
  121. package/dist/web-components.min.css +1 -1
  122. package/dist/web-components.min.js +122 -119
  123. package/dist/web-components.sheet.js +1 -1
  124. package/index.d.ts +0 -15
  125. package/package.json +1 -1
  126. package/patterns/access-requests/access-requests.examples.html +1 -1
  127. package/patterns/admin-keys-and-export/admin-keys-and-export.examples.html +7 -7
  128. package/patterns/agent-cost/agent-cost.examples.html +6 -6
  129. package/patterns/agent-memory/agent-memory.examples.html +3 -3
  130. package/patterns/agent-prompt-library/agent-prompt-library.examples.html +8 -8
  131. package/patterns/agent-tool-call/agent-tool-call.examples.html +1 -1
  132. package/patterns/approvals/approvals.examples.html +6 -6
  133. package/patterns/audit-log/audit-log.examples.html +1 -1
  134. package/patterns/bulk-action-toolbar/bulk-action-toolbar.examples.html +4 -4
  135. package/patterns/chart-in-card/chart-in-card.examples.html +124 -10
  136. package/patterns/chart-in-card/chart-in-card.examples.js +37 -0
  137. package/patterns/comments-and-collaboration/comments-and-collaboration.examples.html +5 -5
  138. package/patterns/conversion-funnel/conversion-funnel.html +2 -2
  139. package/patterns/data-tables-inline-edit-and-tree/data-tables-inline-edit-and-tree.examples.html +2 -2
  140. package/patterns/diff-review/diff-review.examples.html +6 -6
  141. package/patterns/editor-shell/editor-shell.examples.html +3 -3
  142. package/patterns/export-flow/export-flow.examples.html +2 -2
  143. package/patterns/filter-bar/filter-bar.examples.html +2 -2
  144. package/patterns/forms-conditional-and-autocomplete/forms-conditional-and-autocomplete.examples.html +2 -2
  145. package/patterns/inline-dialog/inline-dialog.examples.html +2 -2
  146. package/patterns/marketing-engagement/marketing-engagement.examples.html +4 -4
  147. package/patterns/notifications-bell-and-digest/notifications-bell-and-digest.examples.html +1 -1
  148. package/patterns/permissions-matrix/permissions-matrix.examples.html +1 -1
  149. package/patterns/permissions-sharing/permissions-sharing.examples.html +2 -2
  150. package/patterns/profile-public-and-verification/profile-public-and-verification.examples.html +4 -4
  151. package/patterns/search-discovery/search-discovery.examples.html +2 -2
  152. package/styles/colors/semantics/features.css +8 -1
  153. package/styles/components.css +0 -4
  154. package/styles/type/roles.css +29 -9
  155. package/traits/arrow-grid-nav/arrow-grid-nav.js +1 -1
  156. package/traits/resize-observer/resize-observer.js +1 -1
  157. package/components/color-picker/color-picker.a2ui.json +0 -148
  158. package/components/color-picker/color-picker.class.js +0 -46
  159. package/components/color-picker/color-picker.css +0 -14
  160. package/components/color-picker/color-picker.d.ts +0 -99
  161. package/components/color-picker/color-picker.examples.md +0 -19
  162. package/components/color-picker/color-picker.js +0 -17
  163. package/components/color-picker/color-picker.yaml +0 -175
  164. package/components/datetime-picker/datetime-picker.a2ui.json +0 -256
  165. package/components/datetime-picker/datetime-picker.class.js +0 -58
  166. package/components/datetime-picker/datetime-picker.css +0 -11
  167. package/components/datetime-picker/datetime-picker.d.ts +0 -87
  168. package/components/datetime-picker/datetime-picker.examples.md +0 -25
  169. package/components/datetime-picker/datetime-picker.js +0 -17
  170. package/components/datetime-picker/datetime-picker.yaml +0 -254
  171. package/components/progress-row/progress-row.a2ui.json +0 -107
  172. package/components/progress-row/progress-row.class.js +0 -118
  173. package/components/progress-row/progress-row.css +0 -60
  174. package/components/progress-row/progress-row.d.ts +0 -24
  175. package/components/progress-row/progress-row.examples.md +0 -7
  176. package/components/progress-row/progress-row.js +0 -17
  177. package/components/progress-row/progress-row.yaml +0 -85
  178. package/components/toggle-group/toggle-group.a2ui.json +0 -148
  179. package/components/toggle-group/toggle-group.class.js +0 -195
  180. package/components/toggle-group/toggle-group.css +0 -127
  181. package/components/toggle-group/toggle-group.d.ts +0 -50
  182. package/components/toggle-group/toggle-group.examples.md +0 -33
  183. package/components/toggle-group/toggle-group.js +0 -18
  184. package/components/toggle-group/toggle-group.yaml +0 -135
  185. package/components/toggle-group/toggle-option.a2ui.json +0 -86
  186. package/components/toggle-group/toggle-option.yaml +0 -75
@@ -125,6 +125,11 @@ export class UITable extends UIElement {
125
125
  paginate: { type: Number, default: 0, reflect: true },
126
126
  loading: { type: Boolean, default: false, reflect: true },
127
127
  search: { type: String, default: '', reflect: true },
128
+ // adiav2 zero-overrides purge (gh#1680) deleted an app-side [data-clickable]
129
+ // cursor rule with no kit-side replacement — row-click is always-emitted
130
+ // (fires whether or not a listener cares), so cursor can't be inferred
131
+ // from listener presence; this is an explicit opt-in affordance instead.
132
+ clickableRows: { type: Boolean, default: false, reflect: true, attribute: 'clickable-rows' },
128
133
  };
129
134
 
130
135
  static template = () => null;
@@ -735,6 +740,18 @@ export class UITable extends UIElement {
735
740
  const allSelected = this.#data.length > 0 && this.#selected.size === this.#data.length;
736
741
  const cells = [];
737
742
 
743
+ // Expand column header — an empty placeholder for the reserved
744
+ // expand-toggle track. Must precede the checkbox header, matching the
745
+ // grid template and body-row cell order (gh#1654: with no placeholder,
746
+ // every header label sat one column left of its data).
747
+ if (this.expandable) {
748
+ const cell = document.createElement('div');
749
+ cell.setAttribute('role', 'columnheader');
750
+ cell.setAttribute('data-expand-col', '');
751
+ cell.setAttribute('aria-label', 'Expand');
752
+ cells.push(cell);
753
+ }
754
+
738
755
  // Checkbox column header
739
756
  if (this.selectable) {
740
757
  const cell = document.createElement('div');
@@ -1505,7 +1522,7 @@ export class UITable extends UIElement {
1505
1522
 
1506
1523
  #onKeydown = (e) => {
1507
1524
  const visCols = this.#visibleColumns;
1508
- const totalCols = visCols.length + (this.selectable ? 1 : 0);
1525
+ const totalCols = visCols.length + (this.expandable ? 1 : 0) + (this.selectable ? 1 : 0);
1509
1526
  const body = this.querySelector(':scope > [data-body]');
1510
1527
  const totalRows = body ? body.children.length : 0;
1511
1528
 
@@ -303,9 +303,18 @@
303
303
 
304
304
  /* text-overflow on a flex container doesn't reach text nodes (anonymous
305
305
  flex items). Built-in cell types now wrap text in <span>; link type
306
- creates <a>; avatar/progress composite types use row-ui > span. */
306
+ creates <a>; avatar/progress composite types use row-ui > span.
307
+
308
+ `[data-truncate]` (gh#1681) extends the identical contract to
309
+ consumer-rendered `column.render` cells, whose output shape isn't
310
+ guaranteed to be a bare <span>/<a> — a render() function sets it on
311
+ whichever element (any tag, including a custom element) should
312
+ single-line-ellipsis, the same way a column author sets [data-wrap] to
313
+ opt a built-in cell INTO wrapping. Undocumented before this: `render`
314
+ cells clipped with no ellipsis and no opt-in path. */
307
315
  [data-body] [role="gridcell"] > span,
308
- [data-body] [role="gridcell"] > a {
316
+ [data-body] [role="gridcell"] > a,
317
+ [data-body] [role="gridcell"] > [data-truncate] {
309
318
  min-width: 0;
310
319
  flex: 1;
311
320
  overflow: hidden;
@@ -351,8 +360,10 @@
351
360
 
352
361
  :scope[wrap] [data-body] [role="gridcell"] > span,
353
362
  :scope[wrap] [data-body] [role="gridcell"] > a,
363
+ :scope[wrap] [data-body] [role="gridcell"] > [data-truncate],
354
364
  [data-body] [role="gridcell"][data-wrap] > span,
355
- [data-body] [role="gridcell"][data-wrap] > a {
365
+ [data-body] [role="gridcell"][data-wrap] > a,
366
+ [data-body] [role="gridcell"][data-wrap] > [data-truncate] {
356
367
  white-space: normal;
357
368
  overflow: visible;
358
369
  text-overflow: clip;
@@ -417,6 +428,15 @@
417
428
  color: var(--table-fg-hover);
418
429
  }
419
430
 
431
+ /* Clickable-row affordance (gh#1680) — adiav2's zero-overrides purge
432
+ deleted an app-side [data-clickable] cursor rule with no kit-side
433
+ replacement. `row-click` fires unconditionally regardless of whether a
434
+ listener cares, so cursor can't be inferred from listener presence;
435
+ `clickable-rows` is an explicit opt-in instead. */
436
+ :scope[clickable-rows] [data-body] > [role="row"] {
437
+ cursor: pointer;
438
+ }
439
+
420
440
  /* Selected row — must out-specify the base row rule `[data-body] >
421
441
  [role="row"]` (0,2,0) and the hover rule (0,2,1), or the highlight never
422
442
  paints. Scoping to `[data-body] > [role="row"][aria-selected="true"]` lifts
@@ -534,9 +554,14 @@
534
554
 
535
555
  /* ═══════ Overlays (empty / loading / error) ═══════ */
536
556
 
537
- [data-overlay],
538
- [data-empty],
539
- [data-loading] {
557
+ /* Scoped to the host's direct children — gh#1700, hygiene pass matching
558
+ the command-ui (gh#1697/#1698) and combobox-ui (gh#1700) fix shape.
559
+ Single-consumer today (only table.class.js's own `:scope >
560
+ [data-empty]` / `:scope > [data-loading]` overlay markers), but a bare
561
+ selector here is one nested consumer away from the same leak. */
562
+ :scope > [data-overlay],
563
+ :scope > [data-empty],
564
+ :scope > [data-loading] {
540
565
  grid-column: 1 / -1;
541
566
  display: flex;
542
567
  flex-direction: column;
@@ -86,7 +86,9 @@ export interface TableSortEventDetail {
86
86
  export type TableSortEvent = CustomEvent<TableSortEventDetail>;
87
87
 
88
88
  export class UITable extends UIElement {
89
- /** Column definitions. Array of {key, label, type?, width?, minWidth?, maxWidth?, flex?, sortable?, resizable?, filterable?, pinned?, hidden?, wrap?, valign?, accessor?, format?, render?, sortFn?, filterType?, meta?}. `valign` ('top'|'center') overrides the host [valign] for that column's body cells only header cells always stay centered. Alternative to declarative <col-def> children (<col-def valign="top">); col-def also accepts `meta` as a JSON attribute (gh#925) — e.g. <col-def type="badge" meta='{"variants":{"Online":"success"}}'> — so cell-type meta (badge variant maps, currency codes) is expressible in static HTML. */
89
+ /** Renders body rows with `cursor: pointer`. `row-click` fires unconditionally whether or not a listener is attached, so the cursor can't be inferred from listener presenceset this explicitly when row-click behavior is wired up (master-detail, open-flyout, navigation) so rows read as actionable. */
90
+ clickableRows: boolean;
91
+ /** Column definitions. Array of {key, label, type?, width?, minWidth?, maxWidth?, flex?, sortable?, resizable?, filterable?, pinned?, hidden?, wrap?, valign?, accessor?, format?, render?, sortFn?, filterType?, meta?}. `valign` ('top'|'center') overrides the host [valign] for that column's body cells only — header cells always stay centered. Alternative to declarative <col-def> children (<col-def valign="top">); col-def also accepts `meta` as a JSON attribute (gh#925) — e.g. <col-def type="badge" meta='{"variants":{"Online":"success"}}'> — so cell-type meta (badge variant maps, currency codes) is expressible in static HTML. Truncation contract for `render` cells (gh#1681) — a `render(value, row, cell, dataIndex)` function's returned markup isn't guaranteed to be a bare <span>/<a> the way built-in cell types are, so single-line ellipsis truncation isn't automatic; set `data-truncate` on whichever rendered element (any tag, including a custom element) should single-line-ellipsis to opt it into the same contract built-in cells get for free. `[wrap]` (host) / `[data-wrap]` (per-column) override it back to multi-line, matching built-in cells. */
90
92
  columns: string;
91
93
  /** 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
94
  data: string;
@@ -12,8 +12,8 @@
12
12
  <table-ui id="api-selectable" selectable></table-ui>
13
13
  ```
14
14
 
15
- ## expandable
15
+ ## render cell truncation (data-truncate)
16
16
 
17
17
  ```html
18
- <table-ui id="api-expandable" expandable></table-ui>
18
+ <table-ui id="api-render-truncate"></table-ui>
19
19
  ```
@@ -20,7 +20,7 @@ composes:
20
20
  - badge-ui
21
21
  props:
22
22
  columns:
23
- description: Column definitions. Array of {key, label, type?, width?, minWidth?, maxWidth?, flex?, sortable?, resizable?, filterable?, pinned?, hidden?, wrap?, valign?, accessor?, format?, render?, sortFn?, filterType?, meta?}. `valign` ('top'|'center') overrides the host [valign] for that column's body cells only — header cells always stay centered. Alternative to declarative <col-def> children (<col-def valign="top">); col-def also accepts `meta` as a JSON attribute (gh#925) — e.g. <col-def type="badge" meta='{"variants":{"Online":"success"}}'> — so cell-type meta (badge variant maps, currency codes) is expressible in static HTML.
23
+ description: Column definitions. Array of {key, label, type?, width?, minWidth?, maxWidth?, flex?, sortable?, resizable?, filterable?, pinned?, hidden?, wrap?, valign?, accessor?, format?, render?, sortFn?, filterType?, meta?}. `valign` ('top'|'center') overrides the host [valign] for that column's body cells only — header cells always stay centered. Alternative to declarative <col-def> children (<col-def valign="top">); col-def also accepts `meta` as a JSON attribute (gh#925) — e.g. <col-def type="badge" meta='{"variants":{"Online":"success"}}'> — so cell-type meta (badge variant maps, currency codes) is expressible in static HTML. Truncation contract for `render` cells (gh#1681) — a `render(value, row, cell, dataIndex)` function's returned markup isn't guaranteed to be a bare <span>/<a> the way built-in cell types are, so single-line ellipsis truncation isn't automatic; set `data-truncate` on whichever rendered element (any tag, including a custom element) should single-line-ellipsis to opt it into the same contract built-in cells get for free. `[wrap]` (host) / `[data-wrap]` (per-column) override it back to multi-line, matching built-in cells.
24
24
  type: array
25
25
  default: []
26
26
  dynamic: true # JS-set collection prop with a custom setter — deliberately not in static properties
@@ -85,6 +85,14 @@ props:
85
85
  range select.
86
86
  type: boolean
87
87
  default: false
88
+ clickable-rows:
89
+ description: >-
90
+ Renders body rows with `cursor: pointer`. `row-click` fires unconditionally
91
+ whether or not a listener is attached, so the cursor can't be inferred from
92
+ listener presence — set this explicitly when row-click behavior is wired up
93
+ (master-detail, open-flyout, navigation) so rows read as actionable.
94
+ type: boolean
95
+ default: false
88
96
  sortable:
89
97
  description: Enable click-to-sort on column headers. Supports multi-sort via Shift+click.
90
98
  type: boolean
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://adiaui.dev/a2ui/v0_9/components/TableToolbar.json",
4
4
  "title": "TableToolbar",
5
- "description": "Header / companion bar for a sibling table-ui. Renders title + count badge, filter / sort / columns popovers, and a search input — 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, or column visibility. 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.",
5
+ "description": "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.",
6
6
  "type": "object",
7
7
  "allOf": [
8
8
  {
@@ -13,6 +13,11 @@
13
13
  }
14
14
  ],
15
15
  "properties": {
16
+ "chromeOnly": {
17
+ "description": "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.",
18
+ "type": "boolean",
19
+ "default": false
20
+ },
16
21
  "component": {
17
22
  "const": "TableToolbar"
18
23
  },
@@ -46,11 +51,47 @@
46
51
  "type": "boolean",
47
52
  "default": false
48
53
  },
54
+ "pageSize": {
55
+ "description": "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.",
56
+ "type": "number",
57
+ "default": 0
58
+ },
59
+ "pageSizeOptions": {
60
+ "description": "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.",
61
+ "$ref": "common_types.json#/$defs/DynamicStringList"
62
+ },
49
63
  "placeholder": {
50
64
  "description": "Placeholder text for the search input.",
51
65
  "type": "string",
52
66
  "default": "Search..."
53
67
  },
68
+ "rangeEnd": {
69
+ "description": "1-indexed last row number of the current page, for the range summary (e.g. `25` in \"Showing 1–25 of 320\"). See rangeStart.",
70
+ "type": "number",
71
+ "default": 0
72
+ },
73
+ "rangeStart": {
74
+ "description": "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.",
75
+ "type": "number",
76
+ "default": 0
77
+ },
78
+ "rangeTotal": {
79
+ "description": "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.",
80
+ "type": "number",
81
+ "default": 0
82
+ },
83
+ "stage": {
84
+ "description": "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).",
85
+ "type": "string",
86
+ "enum": [
87
+ "",
88
+ "full",
89
+ "search-tight",
90
+ "icon-only",
91
+ "overflow"
92
+ ],
93
+ "default": ""
94
+ },
54
95
  "text": {
55
96
  "description": "Title text shown on the left.",
56
97
  "type": "string",
@@ -81,6 +122,7 @@
81
122
  "field-ui",
82
123
  "select-ui",
83
124
  "input-ui",
125
+ "menu-ui",
84
126
  "menu-item-ui",
85
127
  "icon-ui",
86
128
  "check-ui"
@@ -92,6 +134,9 @@
92
134
  "filter-change": {
93
135
  "description": "Filter set changed. Detail: { filters }."
94
136
  },
137
+ "page-size-change": {
138
+ "description": "Page-size select changed. Detail: { pageSize }."
139
+ },
95
140
  "search": {
96
141
  "description": "Debounced search query change. Detail: { value }."
97
142
  },
@@ -104,6 +149,11 @@
104
149
  "description": "Members table with filter/sort/columns/search wired to a sibling table-ui.",
105
150
  "a2ui": "[\n {\"id\": \"root\", \"component\": \"Column\", \"gap\": \"3\", \"children\": [\"bar\", \"card\"]},\n {\"id\": \"bar\", \"component\": \"TableToolbar\", \"for\": \"members\", \"text\": \"All Employees\", \"count\": \"32\"},\n {\"id\": \"card\", \"component\": \"Card\", \"children\": [\"sec\"]},\n {\"id\": \"sec\", \"component\": \"Section\", \"bleed\": true, \"children\": [\"tbl\"]},\n {\"id\": \"tbl\", \"component\": \"Table\", \"id\": \"members\", \"sortable\": true, \"raw\": true}\n]",
106
151
  "name": "members-toolbar"
152
+ },
153
+ {
154
+ "description": "The ratified adiav2 list-page toolbar row (ADIA2-9123, gh#1649): scope menu, range summary, app-owned Filter/Columns triggers (their own filter drawer, not the native popovers — [no-filter]/[no-columns]/ [no-sort]/[no-search] drop the native affordances), page-size select, and a primary CTA — [slot=\"actions-leading\"] carries the Filter/Columns triggers so they land BEFORE the page-size select, while [slot=\"actions\"] carries the CTA so it lands after.",
155
+ "a2ui": "[\n {\"id\": \"root\", \"component\": \"Column\", \"gap\": \"3\", \"children\": [\"bar\", \"card\"]},\n {\"id\": \"bar\", \"component\": \"TableToolbar\", \"for\": \"accounts\", \"no-filter\": true, \"no-sort\": true, \"no-columns\": true, \"no-search\": true, \"range-start\": 1, \"range-end\": 25, \"range-total\": 320, \"page-size\": 25, \"page-size-options\": [10, 25, 50, 100], \"children\": [\"btn-filter\", \"btn-columns\", \"btn-new\"]},\n {\"id\": \"btn-filter\", \"component\": \"Button\", \"text\": \"Filter\", \"variant\": \"ghost\", \"slot\": \"actions-leading\"},\n {\"id\": \"btn-columns\", \"component\": \"Button\", \"text\": \"Columns\", \"variant\": \"ghost\", \"slot\": \"actions-leading\"},\n {\"id\": \"btn-new\", \"component\": \"Button\", \"text\": \"New account\", \"variant\": \"primary\", \"slot\": \"actions\"},\n {\"id\": \"card\", \"component\": \"Card\", \"children\": [\"sec\"]},\n {\"id\": \"sec\", \"component\": \"Section\", \"bleed\": true, \"children\": [\"tbl\"]},\n {\"id\": \"tbl\", \"component\": \"Table\", \"id\": \"accounts\", \"sortable\": true, \"raw\": true}\n]",
156
+ "name": "adiav2-list-page-toolbar-row"
107
157
  }
108
158
  ],
109
159
  "keywords": [
@@ -131,7 +181,16 @@
131
181
  ],
132
182
  "slots": {
133
183
  "actions": {
134
- "description": "Trailing action area — primary buttons (e.g. \"New row\") rendered after the search input."
184
+ "description": "Trailing action area — primary buttons (e.g. \"New row\") rendered after the search input, [slot=\"actions-leading\"], and the page-size select."
185
+ },
186
+ "actions-leading": {
187
+ "description": "Region rendered AFTER the search input and BEFORE the native page-size select (gh#1649) — for app-owned trigger buttons (e.g. custom Filter / Columns triggers that open the consumer's own drawer instead of the native filter/columns popovers) that must land ahead of the page-size select rather than after it, unlike [slot=\"actions\"]. Same real-insertion-point pattern as [slot=\"scope\"] / [slot=\"actions\"] — positioning is CSS by DOM order, not a template stamp. Empty (the default) has zero footprint on existing consumers."
188
+ },
189
+ "empty": {
190
+ "description": "Renders in place of the range-summary text — the same [data-summary] region — when [range-total] is EXPLICITLY present and equal to \"0\" (checked via hasAttribute, never the computed value alone, so an unset range-total during loading never flashes this content; ADR-0076, REQ-E-001). Mutually exclusive with a positive [range-total]: the normal \"Showing X-Y of N\" text always wins whenever range-total is a positive number. Empty (the default) preserves today's exact behavior — [data-summary] hides on a confirmed range-total=\"0\" exactly as before this slot existed. Plain author-supplied markup (text, an empty-state-ui composite, an icon+text pair) — table-toolbar does not template or constrain its shape. Naming matches chart-ui's own existing `empty` slot convention."
191
+ },
192
+ "scope": {
193
+ "description": "Leading region rendered BEFORE the [text]/[count] title cluster — e.g. a scope/view-switcher menu (an org's teams, a saved view). Positioning is CSS by DOM order, mirroring how [slot=\"actions\"] is a real, author-fillable insertion point rather than template-stamped content."
135
194
  }
136
195
  },
137
196
  "states": [
@@ -183,6 +242,12 @@
183
242
  "--table-toolbar-radius": {
184
243
  "description": "Toolbar corner radius (variant=card)"
185
244
  },
245
+ "--table-toolbar-summary-fg": {
246
+ "description": "Range-summary (\"Showing X–Y of N\") text color"
247
+ },
248
+ "--table-toolbar-summary-size": {
249
+ "description": "Range-summary font size"
250
+ },
186
251
  "--table-toolbar-title-fg": {
187
252
  "description": "Title text color"
188
253
  },