@adia-ai/web-components 0.8.41 → 0.8.43

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 (134) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/MIGRATION.md +240 -3
  3. package/USAGE.md +4 -4
  4. package/color/index.js +1 -1
  5. package/components/action-list/action-item.a2ui.json +7 -7
  6. package/components/action-list/action-item.yaml +21 -9
  7. package/components/action-list/action-list.class.js +13 -7
  8. package/components/action-list/action-list.d.ts +2 -2
  9. package/components/button/button.yaml +1 -1
  10. package/components/calendar-picker/calendar-picker.a2ui.json +1 -1
  11. package/components/calendar-picker/calendar-picker.class.js +2 -3
  12. package/components/calendar-picker/calendar-picker.css +16 -18
  13. package/components/calendar-picker/calendar-picker.yaml +2 -2
  14. package/components/card/card.css +3 -3
  15. package/components/chart/chart.a2ui.json +8 -8
  16. package/components/chart/chart.class.js +21 -19
  17. package/components/chart/chart.d.ts +6 -6
  18. package/components/chart/chart.yaml +16 -9
  19. package/components/chart-legend/chart-legend.a2ui.json +7 -11
  20. package/components/chart-legend/chart-legend.class.js +17 -8
  21. package/components/chart-legend/chart-legend.css +5 -2
  22. package/components/chart-legend/chart-legend.d.ts +2 -2
  23. package/components/chart-legend/chart-legend.yaml +12 -8
  24. package/components/check/check.css +9 -0
  25. package/components/{color-picker/color-picker.a2ui.json → color-area/color-area.a2ui.json} +15 -12
  26. package/components/{color-picker/color-picker.class.js → color-area/color-area.class.js} +10 -8
  27. package/components/color-area/color-area.css +185 -0
  28. package/components/color-area/color-area.d.ts +66 -0
  29. package/components/color-area/color-area.examples.md +19 -0
  30. package/components/color-area/color-area.js +17 -0
  31. package/components/{color-picker/color-picker.yaml → color-area/color-area.yaml} +17 -9
  32. package/components/color-input/color-input.a2ui.json +5 -5
  33. package/components/color-input/color-input.class.js +9 -6
  34. package/components/color-input/color-input.css +1 -1
  35. package/components/color-input/color-input.js +2 -2
  36. package/components/color-input/color-input.yaml +14 -12
  37. package/components/description-list/description-list.a2ui.json +1 -1
  38. package/components/description-list/description-list.css +1 -1
  39. package/components/description-list/description-list.d.ts +1 -1
  40. package/components/description-list/description-list.yaml +1 -1
  41. package/components/drilldown/drilldown.a2ui.json +3 -0
  42. package/components/drilldown/drilldown.css +8 -1
  43. package/components/drilldown/drilldown.yaml +2 -0
  44. package/components/field/field.a2ui.json +1 -1
  45. package/components/field/field.class.js +5 -2
  46. package/components/field/field.yaml +1 -1
  47. package/components/index.js +1 -4
  48. package/components/input/input.a2ui.json +4 -4
  49. package/components/input/input.class.js +8 -0
  50. package/components/input/input.css +6 -0
  51. package/components/input/input.yaml +11 -8
  52. package/components/integration-card/integration-card.examples.md +2 -1
  53. package/components/menu/menu-item.a2ui.json +7 -7
  54. package/components/menu/menu-item.yaml +20 -7
  55. package/components/menu/menu.class.js +13 -7
  56. package/components/menu/menu.d.ts +2 -2
  57. package/components/pane/pane.a2ui.json +11 -11
  58. package/components/pane/pane.class.js +8 -4
  59. package/components/pane/pane.css +15 -10
  60. package/components/pane/pane.d.ts +10 -9
  61. package/components/pane/pane.yaml +9 -7
  62. package/components/progress/progress.a2ui.json +1 -1
  63. package/components/progress/progress.class.js +2 -2
  64. package/components/progress/progress.d.ts +1 -1
  65. package/components/progress/progress.yaml +2 -2
  66. package/components/radio/radio.css +7 -0
  67. package/components/search/search.css +10 -1
  68. package/components/segment/segment.a2ui.json +1 -2
  69. package/components/segment/segment.css +10 -0
  70. package/components/segment/segment.yaml +1 -2
  71. package/components/segmented/segmented.a2ui.json +1 -3
  72. package/components/segmented/segmented.class.js +2 -2
  73. package/components/segmented/segmented.yaml +2 -4
  74. package/components/select/select.css +6 -0
  75. package/components/step-progress/step-progress.yaml +1 -1
  76. package/components/swatch/swatch.yaml +1 -1
  77. package/components/switch/switch.css +8 -0
  78. package/components/table-toolbar/table-toolbar.a2ui.json +42 -1
  79. package/components/table-toolbar/table-toolbar.class.js +166 -14
  80. package/components/table-toolbar/table-toolbar.css +46 -0
  81. package/components/table-toolbar/table-toolbar.d.ts +13 -1
  82. package/components/table-toolbar/table-toolbar.yaml +104 -14
  83. package/components/textarea/textarea.css +4 -0
  84. package/components/time-picker/time-picker.yaml +3 -2
  85. package/components/tree/tree.yaml +1 -1
  86. package/components/upload/upload.class.js +16 -0
  87. package/components/upload/upload.d.ts +7 -0
  88. package/components/upload/upload.yaml +7 -3
  89. package/core/icons.js +3 -1
  90. package/custom-elements.json +147 -468
  91. package/dist/host.min.css +1 -1
  92. package/dist/host.sheet.js +1 -1
  93. package/dist/theme-provider.min.js +1 -1
  94. package/dist/web-components.min.css +1 -1
  95. package/dist/web-components.min.js +88 -85
  96. package/dist/web-components.sheet.js +1 -1
  97. package/index.d.ts +9 -13
  98. package/package.json +1 -1
  99. package/patterns/admin-shell/admin-shell.examples.html +2 -2
  100. package/patterns/chart-in-card/chart-in-card.examples.html +10 -10
  101. package/patterns/conversion-funnel/conversion-funnel.html +2 -2
  102. package/patterns/editor-shell/editor-shell.examples.html +3 -3
  103. package/patterns/form-system/form-system.examples.html +1 -1
  104. package/styles/colors/semantics/features.css +8 -1
  105. package/styles/components.css +1 -4
  106. package/traits/arrow-grid-nav/arrow-grid-nav.js +1 -1
  107. package/traits/resize-observer/resize-observer.js +1 -1
  108. package/components/color-picker/color-picker.css +0 -182
  109. package/components/color-picker/color-picker.d.ts +0 -99
  110. package/components/color-picker/color-picker.examples.md +0 -19
  111. package/components/color-picker/color-picker.js +0 -17
  112. package/components/datetime-picker/datetime-picker.a2ui.json +0 -256
  113. package/components/datetime-picker/datetime-picker.class.js +0 -58
  114. package/components/datetime-picker/datetime-picker.css +0 -11
  115. package/components/datetime-picker/datetime-picker.d.ts +0 -87
  116. package/components/datetime-picker/datetime-picker.examples.md +0 -25
  117. package/components/datetime-picker/datetime-picker.js +0 -17
  118. package/components/datetime-picker/datetime-picker.yaml +0 -254
  119. package/components/progress-row/progress-row.a2ui.json +0 -107
  120. package/components/progress-row/progress-row.class.js +0 -118
  121. package/components/progress-row/progress-row.css +0 -60
  122. package/components/progress-row/progress-row.d.ts +0 -24
  123. package/components/progress-row/progress-row.examples.md +0 -7
  124. package/components/progress-row/progress-row.js +0 -17
  125. package/components/progress-row/progress-row.yaml +0 -85
  126. package/components/toggle-group/toggle-group.a2ui.json +0 -148
  127. package/components/toggle-group/toggle-group.class.js +0 -195
  128. package/components/toggle-group/toggle-group.css +0 -127
  129. package/components/toggle-group/toggle-group.d.ts +0 -50
  130. package/components/toggle-group/toggle-group.examples.md +0 -33
  131. package/components/toggle-group/toggle-group.js +0 -18
  132. package/components/toggle-group/toggle-group.yaml +0 -135
  133. package/components/toggle-group/toggle-option.a2ui.json +0 -86
  134. package/components/toggle-group/toggle-option.yaml +0 -75
@@ -16,7 +16,7 @@ props:
16
16
  `start` (default): term and value pack to the term column edge.
17
17
  `between`: term left, value right-aligned with `text-align: end`.
18
18
  `stretch`: value fills the remaining track width (e.g. for a
19
- `<slider-ui>` / `<select-ui>` / `<color-picker-ui>` as `<dd>`
19
+ `<slider-ui>` / `<select-ui>` / `<color-area-ui>` as `<dd>`
20
20
  that should span the full row). Sets `justify-self: stretch` and
21
21
  `width: 100%` on `dd` so block-level form controls inside reach
22
22
  the column edge rather than shrink-wrapping to content.
@@ -236,6 +236,9 @@
236
236
  "--drilldown-row-px": {
237
237
  "description": "Inline padding of each row."
238
238
  },
239
+ "--drilldown-row-py": {
240
+ "description": "Block padding of each row (grows a row past --drilldown-row-height once content, e.g. a two-line label+meta row, exceeds it)."
241
+ },
239
242
  "--drilldown-row-radius": {
240
243
  "description": "Border radius of each row."
241
244
  }
@@ -4,6 +4,7 @@
4
4
  --drilldown-row-height: var(--a-size, 2.25rem);
5
5
  --drilldown-row-radius: var(--a-radius-sm);
6
6
  --drilldown-row-px: var(--a-space-2);
7
+ --drilldown-row-py: var(--a-space-1-5);
7
8
  --drilldown-row-gap: var(--a-space-2);
8
9
  --drilldown-header-px: var(--a-space-3);
9
10
  --drilldown-header-py: var(--a-space-2);
@@ -189,13 +190,19 @@
189
190
  to { transform: none; opacity: 1; }
190
191
  }
191
192
 
192
- /* ── Rows ── */
193
+ /* ── Rows ──
194
+ min-height sets the single-line floor; padding-block (--drilldown-row-py,
195
+ matching menu-item-ui/action-item-ui's own row-density token) only grows
196
+ the row once content (e.g. a two-line label+meta row, gh#1591) exceeds
197
+ that floor — the two never stack into a taller one-liner because a
198
+ single-line row's content-box is shorter than the min-height already. */
193
199
  [role="option"] {
194
200
  display: flex;
195
201
  align-items: center;
196
202
  gap: var(--drilldown-row-gap);
197
203
  min-height: var(--drilldown-row-height);
198
204
  padding-inline: var(--drilldown-row-px);
205
+ padding-block: var(--drilldown-row-py);
199
206
  border-radius: var(--drilldown-row-radius);
200
207
  cursor: pointer;
201
208
  outline: none;
@@ -194,6 +194,8 @@ tokens:
194
194
  description: Border radius of each row.
195
195
  --drilldown-row-px:
196
196
  description: Inline padding of each row.
197
+ --drilldown-row-py:
198
+ description: Block padding of each row (grows a row past --drilldown-row-height once content, e.g. a two-line label+meta row, exceeds it).
197
199
  --drilldown-row-gap:
198
200
  description: Gap between row elements (dot / main / counts / chevron).
199
201
  --drilldown-bg-hover:
@@ -99,7 +99,7 @@
99
99
  ],
100
100
  "slots": {
101
101
  "default": {
102
- "description": "The form control — a WIDE control like input-ui, select-ui, textarea-ui, slider-ui, range-ui, calendar-picker-ui, color-picker-ui, upload-ui, otp-input-ui. Auto-id'd for the label's [for] binding.\nDO NOT wrap small self-labeling widgets here. check-ui, switch-ui, radio-ui, toggle-ui all carry their own [label] attribute that renders inline next to the control — wrapping them in field-ui produces broken layouts (settings-row `justify-self: end` rule pushes the control to the trailing edge, away from the label that field-ui stamps; the widget's own label then renders again on the right, creating a doubled / right-justified affordance). See anti_patterns below for the canonical alternatives."
102
+ "description": "The form control — a WIDE control like input-ui, select-ui, textarea-ui, slider-ui, range-ui, calendar-picker-ui, color-area-ui, upload-ui, otp-input-ui. Auto-id'd for the label's [for] binding.\nDO NOT wrap small self-labeling widgets here. check-ui, switch-ui, radio-ui, toggle-ui all carry their own [label] attribute that renders inline next to the control — wrapping them in field-ui produces broken layouts (settings-row `justify-self: end` rule pushes the control to the trailing edge, away from the label that field-ui stamps; the widget's own label then renders again on the right, creating a doubled / right-justified affordance). See anti_patterns below for the canonical alternatives."
103
103
  },
104
104
  "action": {
105
105
  "description": "Button adjacent to the control for inline actions (clear, reset, help popover)."
@@ -279,8 +279,11 @@ export class UIField extends UIElement {
279
279
  'input-ui', 'textarea-ui', 'select-ui', 'combobox-ui', 'search-ui',
280
280
  'check-ui', 'radio-ui', 'switch-ui', 'slider-ui', 'range-ui',
281
281
  'otp-input-ui', 'tags-input-ui', 'chat-input-ui', 'autocomplete-input-ui',
282
- 'datetime-picker-ui', 'date-range-picker-ui', 'calendar-picker-ui',
283
- 'color-picker-ui', 'upload-ui', 'rating-ui', 'segmented-ui',
282
+ 'date-range-picker-ui', 'calendar-picker-ui',
283
+ // datetime-picker-ui / color-picker-ui cut in 0.8.43 (gh#1617,
284
+ // ADR-0063/gh#1372) — calendar-picker-ui / color-area-ui are the
285
+ // sole tags now.
286
+ 'color-area-ui', 'upload-ui', 'rating-ui', 'segmented-ui',
284
287
  'input', 'textarea', 'select',
285
288
  ]);
286
289
 
@@ -68,7 +68,7 @@ slots:
68
68
  description: >-
69
69
  The form control — a WIDE control like input-ui, select-ui,
70
70
  textarea-ui, slider-ui, range-ui, calendar-picker-ui,
71
- color-picker-ui, upload-ui, otp-input-ui. Auto-id'd for the
71
+ color-area-ui, upload-ui, otp-input-ui. Auto-id'd for the
72
72
  label's [for] binding.
73
73
 
74
74
  DO NOT wrap small self-labeling widgets here. check-ui,
@@ -50,7 +50,7 @@ export { UITooltip } from './tooltip/tooltip.js';
50
50
  export { UIBadge } from './badge/badge.js';
51
51
  export { UIBreadcrumb } from './breadcrumb/breadcrumb.js';
52
52
  export { UICommand } from './command/command.js';
53
- export { UIColorPicker } from './color-picker/color-picker.js';
53
+ export { UIColorArea } from './color-area/color-area.js';
54
54
  export { UIColorInput } from './color-input/color-input.js';
55
55
  export { UINoodles } from './noodles/noodles.js';
56
56
  export { UITable } from './table/table.js';
@@ -114,18 +114,15 @@ export { UISearch } from './search/search.js';
114
114
  export { UICombobox } from './combobox/combobox.js';
115
115
  export { UITagsInput } from './tags-input/tags-input.js';
116
116
  export { UIStat } from './stat/stat.js';
117
- export { UIProgressRow } from './progress-row/progress-row.js';
118
117
  export { UIActionList, UIActionItem } from './action-list/action-list.js';
119
118
  export { UIEmptyState } from './empty-state/empty-state.js';
120
119
  export { UICalendarGrid } from './calendar-grid/calendar-grid.js';
121
120
  export { UICalendarPicker } from './calendar-picker/calendar-picker.js';
122
121
  export { UIDateRangePicker } from './date-range-picker/date-range-picker.js';
123
122
  export { UITimePicker } from './time-picker/time-picker.js';
124
- export { UIDatetimePicker } from './datetime-picker/datetime-picker.js';
125
123
  export { UIEmbed } from './embed/embed.js';
126
124
  export { UIBlock } from './block/block.js';
127
125
  export { UIText } from './text/text.js';
128
- export { UIToggleGroup, UIToggleOption } from './toggle-group/toggle-group.js';
129
126
  export { UIToggleScheme } from './toggle-scheme/toggle-scheme.js';
130
127
  export { UIDemoToggle } from './demo-toggle/demo-toggle.js';
131
128
  export { UIRichText } from './richtext/richtext.js';
@@ -14,7 +14,7 @@
14
14
  ],
15
15
  "properties": {
16
16
  "type": {
17
- "description": "Input type. `password` wraps a native `<input>` for disc masking; `number` renders a contenteditable + stepper buttons (no native input). `text`/`email`/`tel`/`url` use plain contenteditable. input-ui does NOT implement date/time/color/search affordances — those HTML5 type values render as a plain contenteditable with no calendar, clock, swatch, or search affordance (first-pass-VALID against this enum historically, but functionally broken generation output). Use the owning primitive instead — CalendarPicker for date (+ month/week, no dedicated granularity primitive exists), DatetimePicker for datetime-local, TimePicker for time, ColorInput/ColorPicker for color, Search for search. See anti_patterns.",
17
+ "description": "Input type. `password` wraps a native `<input>` for disc masking; `number` renders a contenteditable + stepper buttons (no native input). `text`/`email`/`tel`/`url` use plain contenteditable. input-ui does NOT implement date/time/color/search affordances — those HTML5 type values render as a plain contenteditable with no calendar, clock, swatch, or search affordance (first-pass-VALID against this enum historically, but functionally broken generation output). Use the owning primitive instead — CalendarPicker for date (+ month/week, no dedicated granularity primitive exists), CalendarPicker precision=\"minute\" for datetime-local, TimePicker for time, ColorInput/ColorArea for color, Search for search. See anti_patterns.",
18
18
  "type": "string",
19
19
  "enum": [
20
20
  "text",
@@ -165,8 +165,8 @@
165
165
  "wrong": "{\"component\": \"Input\", \"type\": \"date\"}\n"
166
166
  },
167
167
  {
168
- "fix": "{\"component\": \"DatetimePicker\"}\n",
169
- "why": "Same gap as \"date\" — no native datetime picker rendered. Use\nDatetimePicker for combined date + time input.\n",
168
+ "fix": "{\"component\": \"CalendarPicker\", \"precision\": \"minute\"}\n",
169
+ "why": "Same gap as \"date\" — no native datetime picker rendered. Use\nCalendarPicker with precision=\"minute\" for combined date + time\ninput (DatetimePicker was a deprecated thin alias, cut in 0.8.43,\ngh#1617 — CalendarPicker is the sole tag now).\n",
170
170
  "wrong": "{\"component\": \"Input\", \"type\": \"datetime-local\"}\n"
171
171
  },
172
172
  {
@@ -186,7 +186,7 @@
186
186
  },
187
187
  {
188
188
  "fix": "{\"component\": \"ColorInput\"}\n",
189
- "why": "No native color swatch/picker rendered — just a plain text\nsurface. Use ColorInput for a compact form-bearing swatch +\npopover, or ColorPicker directly for the full OKLCH picker\nsurface.\n",
189
+ "why": "No native color swatch/picker rendered — just a plain text\nsurface. Use ColorInput for a compact form-bearing swatch +\npopover, or ColorArea directly for the full OKLCH picker surface\n(ColorPicker was a deprecated thin alias, cut in 0.8.43, gh#1617 —\nColorArea is the sole tag now).\n",
190
190
  "wrong": "{\"component\": \"Input\", \"type\": \"color\"}\n"
191
191
  },
192
192
  {
@@ -272,11 +272,19 @@ export class UIInput extends UIFormElement {
272
272
  `;
273
273
  }
274
274
 
275
+ // Suppress browser-native suggestion/autofill affordances on the
276
+ // contenteditable surface (gh#1593) — a bespoke editable, not a real
277
+ // form <input>, so a browser's saved-values dropdown or spellcheck
278
+ // suggestion strip is always noise here, never a wanted feature.
279
+ // aria-autocomplete="none" documents the same intent for AT users.
275
280
  const editable = `
276
281
  <span slot="text" contenteditable="plaintext-only" tabindex="0"
277
282
  ${this.value ? '' : 'data-empty=""'}
278
283
  ${labelby}
279
284
  data-placeholder="${this.placeholder}"
285
+ autocomplete="off" aria-autocomplete="none"
286
+ autocorrect="off" autocapitalize="off" spellcheck="false"
287
+ data-lpignore="true" data-1p-ignore="true"
280
288
  ${this.#isNumberMode ? 'inputmode="decimal"' : ''}></span>`;
281
289
 
282
290
  const controls = this.#isNumberMode ? `
@@ -51,6 +51,11 @@ input-ui:not([disabled]) [slot="field"]:hover [slot="suffix"] {
51
51
  /* ── State: disabled ── */
52
52
  --input-bg-disabled: var(--a-ui-bg-disabled);
53
53
  --input-fg-disabled: var(--a-ui-text-disabled);
54
+ /* gh#1595 — border kept full contrast on disabled; otp-input.css /
55
+ upload.css already alias this exact role for their own disabled
56
+ border, so this follows that sibling pattern rather than inventing
57
+ a new one. */
58
+ --input-border-disabled: var(--a-ui-border-disabled);
54
59
  text-align: start; /* §text-align-reset — blocks inheritance from centered ancestors */
55
60
  }
56
61
 
@@ -381,6 +386,7 @@ input-ui:not([disabled]) [slot="field"]:hover [slot="suffix"] {
381
386
  :scope[disabled] [slot="field"] {
382
387
  background: var(--input-bg-disabled);
383
388
  color: var(--input-fg-disabled);
389
+ border-color: var(--input-border-disabled);
384
390
  cursor: not-allowed;
385
391
  }
386
392
 
@@ -33,8 +33,8 @@ props:
33
33
  against this enum historically, but functionally broken generation
34
34
  output). Use the owning primitive instead — CalendarPicker for date
35
35
  (+ month/week, no dedicated granularity primitive exists),
36
- DatetimePicker for datetime-local, TimePicker for time,
37
- ColorInput/ColorPicker for color, Search for search. See
36
+ CalendarPicker precision="minute" for datetime-local, TimePicker
37
+ for time, ColorInput/ColorArea for color, Search for search. See
38
38
  anti_patterns.
39
39
  type: string
40
40
  default: text
@@ -291,8 +291,8 @@ a2ui:
291
291
  — text/email/password/number/tel/url (gh#1363 B10). Never
292
292
  set [type] to an HTML5 value input-ui doesn't render — route
293
293
  date/time/color/search intents to the owning primitive instead:
294
- CalendarPicker, DatetimePicker, TimePicker, ColorInput (or
295
- ColorPicker directly), Search. See anti_patterns.
294
+ CalendarPicker (precision="minute" for datetime-local), TimePicker,
295
+ ColorInput (or ColorArea directly), Search. See anti_patterns.
296
296
  anti_patterns:
297
297
  - wrong: |
298
298
  {"component": "Input", "type": "date"}
@@ -307,9 +307,11 @@ anti_patterns:
307
307
  {"component": "Input", "type": "datetime-local"}
308
308
  why: |
309
309
  Same gap as "date" — no native datetime picker rendered. Use
310
- DatetimePicker for combined date + time input.
310
+ CalendarPicker with precision="minute" for combined date + time
311
+ input (DatetimePicker was a deprecated thin alias, cut in 0.8.43,
312
+ gh#1617 — CalendarPicker is the sole tag now).
311
313
  fix: |
312
- {"component": "DatetimePicker"}
314
+ {"component": "CalendarPicker", "precision": "minute"}
313
315
  - wrong: |
314
316
  {"component": "Input", "type": "time"}
315
317
  why: |
@@ -338,8 +340,9 @@ anti_patterns:
338
340
  why: |
339
341
  No native color swatch/picker rendered — just a plain text
340
342
  surface. Use ColorInput for a compact form-bearing swatch +
341
- popover, or ColorPicker directly for the full OKLCH picker
342
- surface.
343
+ popover, or ColorArea directly for the full OKLCH picker surface
344
+ (ColorPicker was a deprecated thin alias, cut in 0.8.43, gh#1617 —
345
+ ColorArea is the sole tag now).
343
346
  fix: |
344
347
  {"component": "ColorInput"}
345
348
  - wrong: |
@@ -16,7 +16,8 @@
16
16
 
17
17
  ```html
18
18
  <integration-card-ui provider="github" name="GitHub" description="Sync issues and pull requests." status="connected">
19
- <menu-ui slot="actions" label="More" trigger-icon="dots-three" trigger-variant="ghost">
19
+ <menu-ui slot="actions">
20
+ <button-ui slot="trigger" icon="dots-three" variant="ghost" aria-label="More"></button-ui>
20
21
  <menu-item-ui action="reauth">Re-authenticate</menu-item-ui>
21
22
  <menu-item-ui action="disconnect" variant="danger">Disconnect</menu-item-ui>
22
23
  </menu-ui>
@@ -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/MenuItem.json",
4
4
  "title": "MenuItem",
5
- "description": "Child of `<menu-ui>`. One actionable row inside a menu, with optional leading icon + label + subtitle + value.",
5
+ "description": "Child of `<menu-ui>`. One actionable row inside a menu, with optional leading icon + label + description + value. (The deprecated `subtitle` prop alias for `description` was cut in 0.8.43 — ADR-0063, gh#1563/gh#1617.)",
6
6
  "type": "object",
7
7
  "allOf": [
8
8
  {
@@ -13,6 +13,11 @@
13
13
  }
14
14
  ],
15
15
  "properties": {
16
+ "description": {
17
+ "description": "Optional secondary description line rendered under the label. Canonical spelling (ADR-0063, gh#1563) replacing `subtitle` — converges menu-item onto the ~20-component corpus majority that already names this concept `description`. The deprecated `subtitle` prop alias was cut in 0.8.43 (gh#1617).",
18
+ "type": "string",
19
+ "default": ""
20
+ },
16
21
  "component": {
17
22
  "const": "MenuItem"
18
23
  },
@@ -26,11 +31,6 @@
26
31
  "type": "string",
27
32
  "default": ""
28
33
  },
29
- "subtitle": {
30
- "description": "Optional secondary description line rendered under the label.",
31
- "type": "string",
32
- "default": ""
33
- },
34
34
  "text": {
35
35
  "description": "Item label text.",
36
36
  "type": "string",
@@ -81,7 +81,7 @@
81
81
  "description": "Custom leading element override; falls through to `[icon]` prop if not slotted."
82
82
  },
83
83
  "subtitle": {
84
- "description": "Custom secondary-line content override; falls through to `[subtitle]` prop if not slotted."
84
+ "description": "Custom secondary-line content override; falls through to the `[description]` prop if not slotted (ADR-0063, gh#1563 — the deprecated `[subtitle]` prop alias was cut in 0.8.43, gh#1617). The slot's own name is unchanged by that rename — this is a distinct, deliberately-unrenamed surface."
85
85
  },
86
86
  "text": {
87
87
  "description": "Custom label content; falls through to `[text]` prop if not slotted."
@@ -13,7 +13,7 @@ component: MenuItem
13
13
  category: navigation
14
14
  version: 1
15
15
  description: |-
16
- Child of `<menu-ui>`. One actionable row inside a menu, with optional leading icon + label + subtitle + value.
16
+ Child of `<menu-ui>`. One actionable row inside a menu, with optional leading icon + label + description + value. (The deprecated `subtitle` prop alias for `description` was cut in 0.8.43 — ADR-0063, gh#1563/gh#1617.)
17
17
 
18
18
  props:
19
19
  icon:
@@ -24,8 +24,13 @@ props:
24
24
  description: Item label text.
25
25
  type: string
26
26
  default: ""
27
- subtitle:
28
- description: Optional secondary description line rendered under the label.
27
+ description:
28
+ description: >-
29
+ Optional secondary description line rendered under the label.
30
+ Canonical spelling (ADR-0063, gh#1563) replacing `subtitle` —
31
+ converges menu-item onto the ~20-component corpus majority that
32
+ already names this concept `description`. The deprecated `subtitle`
33
+ prop alias was cut in 0.8.43 (gh#1617).
29
34
  type: string
30
35
  default: ""
31
36
  value:
@@ -49,7 +54,12 @@ slots:
49
54
  text:
50
55
  description: Custom label content; falls through to `[text]` prop if not slotted.
51
56
  subtitle:
52
- description: Custom secondary-line content override; falls through to `[subtitle]` prop if not slotted.
57
+ description: >-
58
+ Custom secondary-line content override; falls through to the
59
+ `[description]` prop if not slotted (ADR-0063, gh#1563 — the
60
+ deprecated `[subtitle]` prop alias was cut in 0.8.43, gh#1617). The
61
+ slot's own name is unchanged by that rename — this is a distinct,
62
+ deliberately-unrenamed surface.
53
63
  trailing:
54
64
  description: Trailing element pinned to the far edge (shortcut hint, check mark).
55
65
 
@@ -81,9 +91,12 @@ a2ui:
81
91
  hint).
82
92
  - >-
83
93
  <action-item-ui> (child of <action-list-ui>) shares this row contract
84
- (icon/text/subtitle/value/variant/disabled props, icon/text/subtitle/
85
- trailing slot overrides) for inline, non-popover command rows — use
86
- it instead when the surface isn't a <menu-ui> popover (#1363 C5).
94
+ (icon/text/description/value/variant/disabled props, icon/text/
95
+ subtitle/trailing slot overrides) for inline, non-popover command
96
+ rows — use it instead when the surface isn't a <menu-ui> popover
97
+ (#1363 C5). Both components' deprecated `subtitle` PROP aliases for
98
+ `description` were cut in 0.8.43 (ADR-0063, gh#1563/gh#1571,
99
+ gh#1617); the `subtitle` SLOT on both is unchanged.
87
100
 
88
101
  keywords:
89
102
  - menu-item
@@ -258,7 +258,12 @@ export class UIMenuItem extends UIElement {
258
258
  static properties = {
259
259
  icon: { type: String, default: '', reflect: true },
260
260
  text: { type: String, default: '', reflect: true },
261
- subtitle: { type: String, default: '', reflect: true },
261
+ // ADR-0063 (gh#1563) `description` is canonical (menu-item was the
262
+ // sole ~20-component-corpus outlier using `subtitle`); the deprecated
263
+ // `subtitle` PROP dual-read shim was cut in 0.8.43 (gh#1617). The
264
+ // `subtitle` SLOT (a separate surface — see menu-item.yaml) is
265
+ // deliberately unchanged.
266
+ description: { type: String, default: '', reflect: true },
262
267
  value: { type: String, default: '', reflect: true },
263
268
  variant: { type: String, default: 'default', reflect: true },
264
269
  disabled: { type: Boolean, default: false, reflect: true },
@@ -324,10 +329,10 @@ export class UIMenuItem extends UIElement {
324
329
  this.appendChild(span);
325
330
  }
326
331
 
327
- if (this.subtitle && !this.#ownChild('[slot="subtitle"]')) {
332
+ if (this.description && !this.#ownChild('[slot="subtitle"]')) {
328
333
  const sub = this.#stampMark(document.createElement('span'));
329
334
  sub.setAttribute('slot', 'subtitle');
330
- sub.textContent = this.subtitle;
335
+ sub.textContent = this.description;
331
336
  this.appendChild(sub);
332
337
  }
333
338
  }
@@ -357,15 +362,16 @@ export class UIMenuItem extends UIElement {
357
362
  const textEl = this.#ownChild('[slot="text"]');
358
363
  if (this.#wasStamped(textEl)) textEl.textContent = this.text;
359
364
 
360
- // Sync subtitle only touch elements we stamped.
365
+ // Sync subtitle (backed by the `description` prop — ADR-0063, gh#1563)
366
+ // — only touch elements we stamped.
361
367
  const subEl = this.#ownChild('[slot="subtitle"]');
362
- if (this.subtitle) {
368
+ if (this.description) {
363
369
  if (subEl) {
364
- if (this.#wasStamped(subEl)) subEl.textContent = this.subtitle;
370
+ if (this.#wasStamped(subEl)) subEl.textContent = this.description;
365
371
  } else {
366
372
  const el = this.#stampMark(document.createElement('span'));
367
373
  el.setAttribute('slot', 'subtitle');
368
- el.textContent = this.subtitle;
374
+ el.textContent = this.description;
369
375
  this.appendChild(el);
370
376
  }
371
377
  } else if (this.#wasStamped(subEl)) {
@@ -41,12 +41,12 @@ export class UIMenuDivider extends UIElement {
41
41
  }
42
42
 
43
43
  export class UIMenuItem extends UIElement {
44
+ /** Optional secondary description line rendered under the label. Canonical spelling (ADR-0063, gh#1563) replacing `subtitle` — converges menu-item onto the ~20-component corpus majority that already names this concept `description`. The deprecated `subtitle` prop alias was cut in 0.8.43 (gh#1617). */
45
+ description: string;
44
46
  /** Disabled state — blocks pointer + keyboard activation. */
45
47
  disabled: boolean;
46
48
  /** Optional leading Phosphor icon name. */
47
49
  icon: string;
48
- /** Optional secondary description line rendered under the label. */
49
- subtitle: string;
50
50
  /** Item label text. */
51
51
  text: string;
52
52
  /** Stable identifier emitted via the parent menu's `select` event. */
@@ -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/Pane.json",
4
4
  "title": "Pane",
5
- "description": "Collapsible, resizable content panel — drag-resize handle on the\ninner edge when [side=\"leading\"] / [side=\"trailing\"], [resizable]\nopt-in. Used standalone for resizable two-pane layouts, or wrapped\nby <editor-sidebar> / <admin-sidebar> which DELEGATE drag to the\ninner pane-ui rather than reimplementing it. See pane.yaml's\na2ui.rules for the full composition contract.\n",
5
+ "description": "Collapsible, resizable content panel — drag-resize handle on the\ninner edge when [edge=\"leading\"] / [edge=\"trailing\"], [resizable]\nopt-in. Used standalone for resizable two-pane layouts, or wrapped\nby <editor-sidebar> / <admin-sidebar> which DELEGATE drag to the\ninner pane-ui rather than reimplementing it. See pane.yaml's\na2ui.rules for the full composition contract.\n",
6
6
  "type": "object",
7
7
  "allOf": [
8
8
  {
@@ -21,6 +21,16 @@
21
21
  "component": {
22
22
  "const": "Pane"
23
23
  },
24
+ "edge": {
25
+ "description": "Opts a pane into horizontal-sibling chrome: suppresses the default\nfour-sided border and moves the resize grabber to the inner edge\n(right edge for `leading`, left edge for `trailing`). Also flips the\nresize-drag direction so `trailing` panes grow when dragged leftward.\nUnset keeps the pane-intrinsic chrome (full border, right-edge\ngrabber when resizable). Canonical spelling (ADR-0063, gh#1563) — the\ndeprecated `side` dual-read alias was cut in 0.8.43 (gh#1617).\n",
26
+ "type": "string",
27
+ "enum": [
28
+ "",
29
+ "leading",
30
+ "trailing"
31
+ ],
32
+ "default": ""
33
+ },
24
34
  "maxWidth": {
25
35
  "description": "Component property: maxWidth.",
26
36
  "type": "number",
@@ -35,16 +45,6 @@
35
45
  "description": "Component property: resizable.",
36
46
  "type": "boolean",
37
47
  "default": false
38
- },
39
- "side": {
40
- "description": "Opts a pane into horizontal-sibling chrome: suppresses the default\nfour-sided border and moves the resize grabber to the inner edge\n(right edge for `leading`, left edge for `trailing`). Also flips the\nresize-drag direction so `trailing` panes grow when dragged leftward.\nUnset keeps the pane-intrinsic chrome (full border, right-edge\ngrabber when resizable).\n",
41
- "type": "string",
42
- "enum": [
43
- "",
44
- "leading",
45
- "trailing"
46
- ],
47
- "default": ""
48
48
  }
49
49
  },
50
50
  "required": [
@@ -32,12 +32,14 @@
32
32
  * resizable — boolean, enables drag-to-resize (width)
33
33
  * min-width — minimum width when resizing (default: 200)
34
34
  * max-width — maximum width when resizing (default: 600)
35
- * side — 'leading' | 'trailing' | '' (default). When set, the
35
+ * edge — 'leading' | 'trailing' | '' (default). When set, the
36
36
  * pane is treated as a horizontal sibling: the default
37
37
  * four-sided border is suppressed, only the inner-edge
38
38
  * border is drawn, the resize grabber moves to that
39
39
  * inner edge, and the resize-drag direction flips so
40
- * trailing panes grow when dragged leftward.
40
+ * trailing panes grow when dragged leftward. The
41
+ * deprecated `side` dual-read alias was cut in 0.8.43
42
+ * (gh#1617, ADR-0063).
41
43
  *
42
44
  * JS API:
43
45
  * pane.collapsed = true/false
@@ -58,7 +60,9 @@ export class UIPane extends UIElement {
58
60
  resizable: { type: Boolean, default: false, reflect: true },
59
61
  minWidth: { type: Number, default: 200, attribute: 'min-width', reflect: true },
60
62
  maxWidth: { type: Number, default: 9999, attribute: 'max-width', reflect: true },
61
- side: { type: String, default: '', reflect: true },
63
+ // ADR-0063 (gh#1563) `edge` is the canonical spelling; the deprecated
64
+ // `side` dual-read alias was cut in 0.8.43 (gh#1617).
65
+ edge: { type: String, default: '', reflect: true },
62
66
  };
63
67
 
64
68
  static template = () => null;
@@ -164,7 +168,7 @@ export class UIPane extends UIElement {
164
168
  // is anchored on the RIGHT side of its flex row — dragging leftward
165
169
  // should GROW the pane (grabber moves further left = more width),
166
170
  // not shrink it. Negate dx in that case.
167
- const sign = this.side === 'trailing' ? -1 : 1;
171
+ const sign = this.edge === 'trailing' ? -1 : 1;
168
172
  const dx = (e.clientX - this.#startX) * sign;
169
173
  const w = Math.max(this.minWidth, Math.min(this.maxWidth, this.#startW + dx));
170
174
  this.style.width = `${w}px`;
@@ -63,20 +63,23 @@
63
63
  transition: none;
64
64
  }
65
65
 
66
- /* Side-aware border treatment.
66
+ /* Edge-aware border treatment. ADR-0063 (gh#1563): `[edge]` is the
67
+ canonical attribute — pane.class.js's connected() mirrors an
68
+ old-only `[side]` value onto `[edge]` before the first render, so
69
+ selecting on `[edge=...]` alone covers both spellings.
67
70
  `leading` — pane sits at the leading edge of a horizontal row, so
68
71
  the only visual separator it needs is on its trailing
69
72
  edge (right in LTR).
70
73
  `trailing` — mirror: only a leading-edge border (left in LTR).
71
- Default (no side attr) keeps the full 4-sided border. */
72
- :scope[side="leading"],
73
- :scope[side="trailing"] {
74
+ Default (no edge attr) keeps the full 4-sided border. */
75
+ :scope[edge="leading"],
76
+ :scope[edge="trailing"] {
74
77
  border: none;
75
78
  }
76
- :scope[side="leading"] {
79
+ :scope[edge="leading"] {
77
80
  border-inline-end: 1px solid var(--pane-border);
78
81
  }
79
- :scope[side="trailing"] {
82
+ :scope[edge="trailing"] {
80
83
  border-inline-start: 1px solid var(--pane-border);
81
84
  }
82
85
 
@@ -184,11 +187,13 @@
184
187
  }
185
188
 
186
189
  /* ── Resize handle ──
187
- Default (no side) positions the grabber on the right edge. When
188
- `side="trailing"` is set, flip the grabber to the left edge so it
190
+ Default (no edge) positions the grabber on the right edge. When
191
+ `edge="trailing"` is set, flip the grabber to the left edge so it
189
192
  sits on the pane's "inner" side (where it meets the sibling
190
193
  content/pane in a horizontal row). `inset-inline-*` lets the rules
191
- stay LTR/RTL-safe. */
194
+ stay LTR/RTL-safe. `side="trailing"` is a deprecated dual-read alias
195
+ (ADR-0063, gh#1563) — pane.class.js's connected() mirrors it onto
196
+ `[edge]` before the first render, so this selector alone covers both. */
192
197
  [slot="resize"] {
193
198
  position: absolute;
194
199
  top: 0;
@@ -202,7 +207,7 @@
202
207
  z-index: 1;
203
208
  }
204
209
 
205
- :scope[side="trailing"] > [slot="resize"] {
210
+ :scope[edge="trailing"] > [slot="resize"] {
206
211
  inset-inline-end: auto;
207
212
  inset-inline-start: 0;
208
213
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * `<pane-ui>` — Collapsible, resizable content panel — drag-resize handle on the
3
- inner edge when [side="leading"] / [side="trailing"], [resizable]
3
+ inner edge when [edge="leading"] / [edge="trailing"], [resizable]
4
4
  opt-in. Used standalone for resizable two-pane layouts, or wrapped
5
5
  by <editor-sidebar> / <admin-sidebar> which DELEGATE drag to the
6
6
  inner pane-ui rather than reimplementing it. See pane.yaml's
@@ -23,20 +23,21 @@ export type PaneToggleEvent = CustomEvent<unknown>;
23
23
  export class UIPane extends UIElement {
24
24
  /** Component property: collapsed. */
25
25
  collapsed: boolean;
26
- /** Component property: maxWidth. */
27
- maxWidth: number;
28
- /** Component property: minWidth. */
29
- minWidth: number;
30
- /** Component property: resizable. */
31
- resizable: boolean;
32
26
  /** Opts a pane into horizontal-sibling chrome: suppresses the default
33
27
  four-sided border and moves the resize grabber to the inner edge
34
28
  (right edge for `leading`, left edge for `trailing`). Also flips the
35
29
  resize-drag direction so `trailing` panes grow when dragged leftward.
36
30
  Unset keeps the pane-intrinsic chrome (full border, right-edge
37
- grabber when resizable).
31
+ grabber when resizable). Canonical spelling (ADR-0063, gh#1563) — the
32
+ deprecated `side` dual-read alias was cut in 0.8.43 (gh#1617).
38
33
  */
39
- side: '' | 'leading' | 'trailing';
34
+ edge: '' | 'leading' | 'trailing';
35
+ /** Component property: maxWidth. */
36
+ maxWidth: number;
37
+ /** Component property: minWidth. */
38
+ minWidth: number;
39
+ /** Component property: resizable. */
40
+ resizable: boolean;
40
41
 
41
42
  addEventListener(type: 'toggle', listener: (ev: PaneToggleEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
42
43
  addEventListener<K extends keyof HTMLElementEventMap>(