@adia-ai/web-components 0.6.21 → 0.6.23

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 (248) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/components/accordion/accordion-item.a2ui.json +20 -3
  3. package/components/accordion/accordion-item.yaml +24 -0
  4. package/components/accordion/accordion.a2ui.json +1 -1
  5. package/components/accordion/accordion.d.ts +8 -1
  6. package/components/accordion/accordion.yaml +15 -2
  7. package/components/action-list/action-item.a2ui.json +19 -3
  8. package/components/action-list/action-item.yaml +24 -0
  9. package/components/action-list/action-list.a2ui.json +12 -2
  10. package/components/action-list/action-list.yaml +13 -3
  11. package/components/agent-artifact/agent-artifact.a2ui.json +9 -2
  12. package/components/agent-artifact/agent-artifact.d.ts +1 -1
  13. package/components/agent-artifact/agent-artifact.yaml +17 -3
  14. package/components/agent-feedback-bar/agent-feedback-bar.a2ui.json +9 -2
  15. package/components/agent-feedback-bar/agent-feedback-bar.d.ts +8 -1
  16. package/components/agent-feedback-bar/agent-feedback-bar.yaml +19 -3
  17. package/components/agent-questions/agent-questions.a2ui.json +8 -2
  18. package/components/agent-questions/agent-questions.d.ts +8 -1
  19. package/components/agent-questions/agent-questions.yaml +19 -3
  20. package/components/agent-reasoning/agent-reasoning.yaml +9 -1
  21. package/components/agent-suggestions/agent-suggestions.a2ui.json +9 -2
  22. package/components/agent-suggestions/agent-suggestions.d.ts +7 -1
  23. package/components/agent-suggestions/agent-suggestions.yaml +18 -3
  24. package/components/agent-trace/agent-trace.a2ui.json +9 -2
  25. package/components/agent-trace/agent-trace.d.ts +1 -1
  26. package/components/agent-trace/agent-trace.yaml +16 -3
  27. package/components/alert/alert.a2ui.json +1 -1
  28. package/components/alert/alert.css +8 -0
  29. package/components/alert/alert.d.ts +9 -1
  30. package/components/alert/alert.yaml +16 -2
  31. package/components/aside/aside.a2ui.json +7 -1
  32. package/components/aside/aside.yaml +33 -2
  33. package/components/avatar/avatar-group.a2ui.json +20 -3
  34. package/components/avatar/avatar-group.yaml +24 -0
  35. package/components/avatar/avatar.a2ui.json +1 -1
  36. package/components/avatar/avatar.d.ts +7 -1
  37. package/components/avatar/avatar.yaml +14 -2
  38. package/components/badge/badge.a2ui.json +1 -1
  39. package/components/badge/badge.d.ts +7 -1
  40. package/components/badge/badge.yaml +14 -2
  41. package/components/block/block.a2ui.json +9 -4
  42. package/components/block/block.d.ts +9 -3
  43. package/components/block/block.yaml +25 -5
  44. package/components/block/class.js +23 -0
  45. package/components/breadcrumb/breadcrumb.a2ui.json +5 -1
  46. package/components/breadcrumb/breadcrumb.yaml +33 -2
  47. package/components/button/button.a2ui.json +22 -2
  48. package/components/button/button.yaml +21 -3
  49. package/components/calendar-picker/calendar-picker.a2ui.json +1 -1
  50. package/components/calendar-picker/calendar-picker.yaml +13 -2
  51. package/components/canvas/canvas.a2ui.json +6 -2
  52. package/components/canvas/canvas.yaml +20 -3
  53. package/components/card/card.css +23 -2
  54. package/components/card/card.yaml +12 -0
  55. package/components/chart/chart.css +4 -2
  56. package/components/chart/chart.yaml +9 -1
  57. package/components/chart-legend/chart-legend.yaml +7 -1
  58. package/components/chat-thread/chat-thread.a2ui.json +6 -2
  59. package/components/chat-thread/chat-thread.d.ts +8 -1
  60. package/components/chat-thread/chat-thread.yaml +21 -3
  61. package/components/check/check.a2ui.json +13 -3
  62. package/components/check/check.yaml +18 -3
  63. package/components/code/code.a2ui.json +1 -1
  64. package/components/code/code.yaml +13 -2
  65. package/components/col/class.js +39 -0
  66. package/components/col/col.a2ui.json +12 -5
  67. package/components/col/col.d.ts +12 -4
  68. package/components/col/col.yaml +27 -7
  69. package/components/color-input/color-input.yaml +27 -1
  70. package/components/color-picker/color-picker.a2ui.json +8 -2
  71. package/components/color-picker/color-picker.yaml +15 -3
  72. package/components/command/command.a2ui.json +7 -2
  73. package/components/command/command.d.ts +9 -1
  74. package/components/command/command.yaml +39 -3
  75. package/components/demo-toggle/demo-toggle.yaml +7 -1
  76. package/components/description-list/description-list.a2ui.json +5 -1
  77. package/components/description-list/description-list.yaml +11 -2
  78. package/components/divider/divider.a2ui.json +1 -1
  79. package/components/divider/divider.d.ts +8 -1
  80. package/components/divider/divider.yaml +15 -2
  81. package/components/drawer/drawer.yaml +32 -1
  82. package/components/embed/embed.a2ui.json +1 -1
  83. package/components/embed/embed.d.ts +8 -1
  84. package/components/embed/embed.yaml +17 -2
  85. package/components/empty-state/empty-state.a2ui.json +19 -2
  86. package/components/empty-state/empty-state.css +14 -0
  87. package/components/empty-state/empty-state.d.ts +3 -1
  88. package/components/empty-state/empty-state.yaml +50 -3
  89. package/components/feed/feed-item.a2ui.json +21 -3
  90. package/components/feed/feed-item.yaml +25 -0
  91. package/components/feed/feed.a2ui.json +23 -3
  92. package/components/feed/feed.yaml +26 -0
  93. package/components/fields/fields.yaml +7 -1
  94. package/components/footer/footer.a2ui.json +7 -1
  95. package/components/footer/footer.yaml +27 -2
  96. package/components/grid/class.js +57 -0
  97. package/components/grid/grid.a2ui.json +3 -3
  98. package/components/grid/grid.d.ts +3 -3
  99. package/components/grid/grid.yaml +22 -8
  100. package/components/header/header.a2ui.json +8 -1
  101. package/components/header/header.yaml +30 -2
  102. package/components/heatmap/heatmap.yaml +7 -1
  103. package/components/icon/icon.a2ui.json +9 -2
  104. package/components/icon/icon.d.ts +1 -1
  105. package/components/icon/icon.yaml +32 -3
  106. package/components/image/image.yaml +7 -1
  107. package/components/input/input.yaml +29 -1
  108. package/components/inspector/inspector.a2ui.json +7 -2
  109. package/components/inspector/inspector.d.ts +9 -1
  110. package/components/inspector/inspector.yaml +23 -3
  111. package/components/kbd/kbd.a2ui.json +1 -1
  112. package/components/kbd/kbd.d.ts +1 -1
  113. package/components/kbd/kbd.yaml +11 -2
  114. package/components/list/list-item.a2ui.json +21 -3
  115. package/components/list/list-item.yaml +25 -0
  116. package/components/list/list.a2ui.json +7 -2
  117. package/components/list/list.d.ts +9 -1
  118. package/components/list/list.yaml +21 -3
  119. package/components/menu/menu-divider.a2ui.json +17 -3
  120. package/components/menu/menu-divider.yaml +35 -0
  121. package/components/menu/menu-item.a2ui.json +19 -3
  122. package/components/menu/menu-item.yaml +42 -0
  123. package/components/menu/menu.a2ui.json +7 -1
  124. package/components/menu/menu.yaml +33 -2
  125. package/components/modal/modal.a2ui.json +7 -2
  126. package/components/modal/modal.d.ts +10 -1
  127. package/components/modal/modal.yaml +48 -3
  128. package/components/nav/nav.a2ui.json +16 -2
  129. package/components/nav/nav.yaml +40 -3
  130. package/components/nav-group/nav-group.a2ui.json +12 -2
  131. package/components/nav-group/nav-group.yaml +37 -3
  132. package/components/nav-item/nav-item.a2ui.json +13 -2
  133. package/components/nav-item/nav-item.yaml +40 -3
  134. package/components/noodles/noodles.a2ui.json +12 -2
  135. package/components/noodles/noodles.yaml +14 -3
  136. package/components/option-card/option-card.yaml +27 -1
  137. package/components/otp-input/otp-input.yaml +24 -1
  138. package/components/page/page.a2ui.json +7 -1
  139. package/components/page/page.yaml +9 -2
  140. package/components/pagination/pagination.a2ui.json +1 -1
  141. package/components/pagination/pagination.d.ts +1 -1
  142. package/components/pagination/pagination.yaml +13 -2
  143. package/components/pane/pane.a2ui.json +1 -1
  144. package/components/pane/pane.d.ts +7 -1
  145. package/components/pane/pane.yaml +33 -2
  146. package/components/pipeline-status/pipeline-status.a2ui.json +6 -2
  147. package/components/pipeline-status/pipeline-status.d.ts +1 -1
  148. package/components/pipeline-status/pipeline-status.yaml +18 -3
  149. package/components/popover/popover.yaml +30 -1
  150. package/components/progress/progress.a2ui.json +1 -1
  151. package/components/progress/progress.d.ts +1 -1
  152. package/components/progress/progress.yaml +13 -2
  153. package/components/progress-row/progress-row.a2ui.json +12 -2
  154. package/components/progress-row/progress-row.yaml +13 -3
  155. package/components/radio/radio.a2ui.json +1 -1
  156. package/components/radio/radio.yaml +9 -1
  157. package/components/range/range.yaml +7 -1
  158. package/components/rating/rating.a2ui.json +4 -1
  159. package/components/rating/rating.yaml +10 -2
  160. package/components/richtext/richtext.a2ui.json +6 -2
  161. package/components/richtext/richtext.d.ts +9 -1
  162. package/components/richtext/richtext.yaml +20 -3
  163. package/components/row/class.js +50 -0
  164. package/components/row/row.a2ui.json +17 -6
  165. package/components/row/row.d.ts +14 -5
  166. package/components/row/row.yaml +36 -8
  167. package/components/search/search.a2ui.json +5 -1
  168. package/components/search/search.yaml +11 -2
  169. package/components/section/section.a2ui.json +7 -1
  170. package/components/section/section.yaml +36 -2
  171. package/components/segment/segment.a2ui.json +8 -2
  172. package/components/segment/segment.d.ts +7 -1
  173. package/components/segment/segment.yaml +16 -3
  174. package/components/segmented/segmented.a2ui.json +6 -1
  175. package/components/segmented/segmented.css +5 -0
  176. package/components/segmented/segmented.yaml +12 -2
  177. package/components/select/select.a2ui.json +1 -1
  178. package/components/select/select.yaml +34 -2
  179. package/components/skeleton/skeleton.a2ui.json +7 -2
  180. package/components/skeleton/skeleton.d.ts +1 -1
  181. package/components/skeleton/skeleton.yaml +17 -3
  182. package/components/slider/slider.yaml +7 -1
  183. package/components/stack/stack.a2ui.json +14 -3
  184. package/components/stack/stack.d.ts +9 -1
  185. package/components/stack/stack.yaml +22 -4
  186. package/components/stat/stat.a2ui.json +6 -2
  187. package/components/stat/stat.css +5 -2
  188. package/components/stat/stat.d.ts +1 -1
  189. package/components/stat/stat.yaml +16 -3
  190. package/components/step-progress/step-progress.yaml +7 -1
  191. package/components/stepper/stepper-item.a2ui.json +20 -3
  192. package/components/stepper/stepper-item.yaml +24 -0
  193. package/components/stepper/stepper.a2ui.json +1 -1
  194. package/components/stepper/stepper.d.ts +1 -1
  195. package/components/stepper/stepper.yaml +13 -2
  196. package/components/stream/stream.a2ui.json +12 -2
  197. package/components/stream/stream.yaml +15 -3
  198. package/components/swatch/swatch.yaml +7 -1
  199. package/components/swiper/swiper.yaml +7 -1
  200. package/components/switch/switch.a2ui.json +6 -2
  201. package/components/switch/switch.yaml +16 -2
  202. package/components/table/cell-types.js +23 -10
  203. package/components/table/class.js +6 -2
  204. package/components/table/table.css +49 -1
  205. package/components/table/table.yaml +27 -1
  206. package/components/table-toolbar/table-toolbar.yaml +27 -1
  207. package/components/tabs/tab.a2ui.json +17 -3
  208. package/components/tabs/tab.yaml +39 -0
  209. package/components/tabs/tabs.a2ui.json +1 -1
  210. package/components/tabs/tabs.d.ts +1 -1
  211. package/components/tabs/tabs.yaml +36 -2
  212. package/components/tag/tag.a2ui.json +6 -2
  213. package/components/tag/tag.d.ts +9 -1
  214. package/components/tag/tag.yaml +38 -3
  215. package/components/text/class.js +13 -0
  216. package/components/text/text.a2ui.json +9 -2
  217. package/components/text/text.d.ts +1 -1
  218. package/components/text/text.yaml +12 -5
  219. package/components/textarea/textarea.a2ui.json +15 -3
  220. package/components/textarea/textarea.yaml +41 -4
  221. package/components/timeline/timeline-item.a2ui.json +20 -3
  222. package/components/timeline/timeline-item.yaml +24 -0
  223. package/components/timeline/timeline.a2ui.json +8 -1
  224. package/components/timeline/timeline.yaml +9 -2
  225. package/components/toast/toast.a2ui.json +6 -2
  226. package/components/toast/toast.yaml +19 -3
  227. package/components/toggle-group/toggle-group.a2ui.json +13 -3
  228. package/components/toggle-group/toggle-group.d.ts +1 -1
  229. package/components/toggle-group/toggle-group.yaml +19 -4
  230. package/components/toggle-group/toggle-option.a2ui.json +18 -3
  231. package/components/toggle-group/toggle-option.yaml +23 -0
  232. package/components/toggle-scheme/toggle-scheme.yaml +4 -0
  233. package/components/toolbar/toolbar-group.a2ui.json +18 -3
  234. package/components/toolbar/toolbar-group.yaml +23 -0
  235. package/components/toolbar/toolbar.yaml +7 -1
  236. package/components/tooltip/tooltip.yaml +24 -1
  237. package/components/tree/tree-item.a2ui.json +19 -3
  238. package/components/tree/tree-item.yaml +42 -0
  239. package/components/tree/tree.a2ui.json +6 -1
  240. package/components/tree/tree.yaml +31 -2
  241. package/components/upload/upload.yaml +7 -1
  242. package/core/index.js +1 -0
  243. package/core/responsive.d.ts +29 -0
  244. package/core/responsive.js +120 -0
  245. package/core/responsive.test.js +121 -0
  246. package/package.json +1 -1
  247. package/styles/tokens.css +6 -6
  248. package/styles/typography.css +1 -0
@@ -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/Radio.json",
4
4
  "title": "Radio",
5
- "description": "Radio button with pure CSS dot. Groups by name attribute. Form-associated.",
5
+ "description": "Radio button with pure CSS dot. Groups by name attribute (one selected value per group); form-associated and emits standard change events. Use for single-select option groups in forms; for richer styling or button-style options use <segment-ui> inside <segmented-ui> instead.",
6
6
  "type": "object",
7
7
  "allOf": [
8
8
  {
@@ -6,7 +6,11 @@ tag: radio-ui
6
6
  component: Radio
7
7
  category: input
8
8
  version: 1
9
- description: Radio button with pure CSS dot. Groups by name attribute. Form-associated.
9
+ description: >-
10
+ Radio button with pure CSS dot. Groups by name attribute (one selected
11
+ value per group); form-associated and emits standard change events. Use
12
+ for single-select option groups in forms; for richer styling or
13
+ button-style options use <segment-ui> inside <segmented-ui> instead.
10
14
  props:
11
15
  name:
12
16
  description: Form control name for form data submission
@@ -109,6 +113,10 @@ tokens:
109
113
  a2ui:
110
114
  rules:
111
115
  - "Self-labeling widget — use the [label] attribute directly; do NOT wrap in <field-ui>. The widget renders its own label inline via CSS attr() pattern. For radio groups, the canonical pattern is a column of bare <radio-ui label='…'> elements sharing a [name=] — no field-ui wrapper around each radio."
116
+ - rule: 'Use the [name] attribute to group radios — exactly one is selected per name group; form-associated.'
117
+ reason: 'Standard radio-group semantics; name= is the group key.'
118
+ - rule: 'For button-style single-select clusters (visually richer) use <segmented-ui> + <segment-ui> instead.'
119
+ reason: 'Visual + interaction sibling distinction.'
112
120
  anti_patterns:
113
121
  - description: Wrapping a radio-ui in field-ui. The widget already self-labels.
114
122
  wrong: |
@@ -80,7 +80,13 @@ tokens:
80
80
  --range-value-color:
81
81
  description: Value text color
82
82
  a2ui:
83
- rules: []
83
+ rules:
84
+ - rule: 'Two-handle slider for selecting a range (min + max). Form-associated; emits two-value change events.'
85
+ reason: 'Range-input contract.'
86
+ - rule: 'Different from <slider-ui> (single value) — use range when both endpoints matter.'
87
+ reason: 'Single vs range distinction.'
88
+ - rule: 'Step attribute controls handle increments; min/max set the bound rails.'
89
+ reason: 'Standard range knobs.'
84
90
  anti_patterns: []
85
91
  examples:
86
92
  - name: price-range-filter
@@ -92,7 +92,10 @@
92
92
  "like"
93
93
  ],
94
94
  "name": "UIRating",
95
- "related": [],
95
+ "related": [
96
+ "Field",
97
+ "AgentFeedbackBar"
98
+ ],
96
99
  "slots": {},
97
100
  "states": [
98
101
  {
@@ -61,7 +61,13 @@ states:
61
61
  traits: []
62
62
  tokens: {}
63
63
  a2ui:
64
- rules: []
64
+ rules:
65
+ - rule: 'Star/icon-based ordinal rating input. Form-associated; emits numeric value 0..max via change events.'
66
+ reason: 'Rating-input contract.'
67
+ - rule: 'For thumbs-up/down agent feedback use <agent-feedback-bar-ui> instead — different semantics + visual.'
68
+ reason: 'Surface boundary.'
69
+ - rule: 'max attribute sets the scale (default 5); allow-half attribute enables half-step granularity.'
70
+ reason: 'Configuration knobs.'
65
71
  anti_patterns: []
66
72
  examples: []
67
73
  keywords:
@@ -79,4 +85,6 @@ synonyms:
79
85
  - star rating
80
86
  - review score
81
87
  - feedback rating
82
- related: []
88
+ related:
89
+ - Field
90
+ - AgentFeedbackBar
@@ -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/RichText.json",
4
4
  "title": "RichText",
5
- "description": "Renders markdown to styled HTML.",
5
+ "description": "Markdown-to-HTML rendering primitive — converts the [markdown] prop\n(or fetched [src] content) into styled HTML using the canonical\nprose tokens. Used for rendering LLM responses inside chat surfaces,\narticle bodies, and documentation pages. Distinct from <code-ui>\n(syntax-highlighted code), <textarea-ui> (interactive editor), and\n<text-ui> (single-line typography). Not a Markdown editor — for\nediting use a CodeMirror-backed <code-ui language=\"markdown\"\neditable>.\n",
6
6
  "type": "object",
7
7
  "allOf": [
8
8
  {
@@ -62,7 +62,11 @@
62
62
  "richtext"
63
63
  ],
64
64
  "name": "UIRichText",
65
- "related": [],
65
+ "related": [
66
+ "Code",
67
+ "Text",
68
+ "Textarea"
69
+ ],
66
70
  "slots": {
67
71
  "default": {
68
72
  "description": "Default slot — primary child content."
@@ -1,5 +1,13 @@
1
1
  /**
2
- * `<richtext-ui>` — Renders markdown to styled HTML.
2
+ * `<richtext-ui>` — Markdown-to-HTML rendering primitive converts the [markdown] prop
3
+ (or fetched [src] content) into styled HTML using the canonical
4
+ prose tokens. Used for rendering LLM responses inside chat surfaces,
5
+ article bodies, and documentation pages. Distinct from <code-ui>
6
+ (syntax-highlighted code), <textarea-ui> (interactive editor), and
7
+ <text-ui> (single-line typography). Not a Markdown editor — for
8
+ editing use a CodeMirror-backed <code-ui language="markdown"
9
+ editable>.
10
+
3
11
  *
4
12
  * @see https://ui-kit.exe.xyz/site/components/richtext
5
13
  *
@@ -4,7 +4,15 @@ tag: richtext-ui
4
4
  component: RichText
5
5
  category: forms
6
6
  version: 1
7
- description: Renders markdown to styled HTML.
7
+ description: |
8
+ Markdown-to-HTML rendering primitive — converts the [markdown] prop
9
+ (or fetched [src] content) into styled HTML using the canonical
10
+ prose tokens. Used for rendering LLM responses inside chat surfaces,
11
+ article bodies, and documentation pages. Distinct from <code-ui>
12
+ (syntax-highlighted code), <textarea-ui> (interactive editor), and
13
+ <text-ui> (single-line typography). Not a Markdown editor — for
14
+ editing use a CodeMirror-backed <code-ui language="markdown"
15
+ editable>.
8
16
  props:
9
17
  markdown:
10
18
  description: 'Component property: markdown.'
@@ -24,7 +32,13 @@ states:
24
32
  traits: []
25
33
  tokens: {}
26
34
  a2ui:
27
- rules: []
35
+ rules:
36
+ - rule: 'Rich-text display + editor primitive. Renders paragraphs, lists, headings, and inline formatting; contenteditable when editable= is set.'
37
+ reason: 'Per ADR-0025, no native <textarea> for rich text.'
38
+ - rule: 'Different from <text-ui> (single semantic block) — richtext handles multi-paragraph + inline marks.'
39
+ reason: 'Capacity boundary.'
40
+ - rule: 'For plain code use <code-ui> or richtext with code variant; for chat input use <chat-composer-ui>.'
41
+ reason: 'Specialized siblings.'
28
42
  anti_patterns: []
29
43
  examples:
30
44
  - name: basic-richtext
@@ -51,4 +65,7 @@ synonyms:
51
65
  - markdown
52
66
  - md-render
53
67
  - rich-text
54
- related: []
68
+ related:
69
+ - Code
70
+ - Text
71
+ - Textarea
@@ -20,6 +20,7 @@
20
20
 
21
21
  import { UIElement } from '../../core/element.js';
22
22
  import { draggable } from '../../traits/draggable/draggable.js';
23
+ import { parseResponsive, breakpoint, BP_NAMES } from '../../core/responsive.js';
23
24
 
24
25
  export class UIRow extends UIElement {
25
26
  static properties = {
@@ -28,6 +29,9 @@ export class UIRow extends UIElement {
28
29
  gap: { type: String, default: 'md', reflect: true },
29
30
  grow: { type: Boolean, default: false, reflect: true },
30
31
  wrap: { type: Boolean, default: false, reflect: true },
32
+ // wrap-at="sm" = enable flex-wrap from sm upward; complements the
33
+ // boolean [wrap] (always-wrap) without modifying it.
34
+ wrapAt: { type: String, default: '', reflect: true, attribute: 'wrap-at' },
31
35
  draggable: { type: Boolean, default: false, reflect: true },
32
36
  };
33
37
  static template = () => null;
@@ -47,4 +51,50 @@ export class UIRow extends UIElement {
47
51
  this.#dragAttached = true;
48
52
  }
49
53
  }
54
+
55
+ render() {
56
+ const gap = this.gap;
57
+ const align = this.align;
58
+ const justify = this.justify;
59
+ const wrapAt = this.wrapAt;
60
+ const anyR = gap?.includes('@') || align?.includes('@') || justify?.includes('@') || !!wrapAt;
61
+ const bp = anyR ? breakpoint.value : '';
62
+
63
+ if (gap?.includes('@')) {
64
+ this.style.setProperty('--row-gap', _gapToCss(parseResponsive(gap, bp)));
65
+ } else {
66
+ this.style.removeProperty('--row-gap');
67
+ }
68
+
69
+ if (align?.includes('@')) {
70
+ this.style.setProperty('--row-align', _flexAlign(parseResponsive(align, bp)));
71
+ } else {
72
+ this.style.removeProperty('--row-align');
73
+ }
74
+
75
+ if (justify?.includes('@')) {
76
+ this.style.setProperty('--row-justify', _flexJustify(parseResponsive(justify, bp)));
77
+ } else {
78
+ this.style.removeProperty('--row-justify');
79
+ }
80
+
81
+ // wrap-at="sm" enables flex-wrap from the named breakpoint upward.
82
+ // Uses inline style rather than toggling the [wrap] attribute to avoid
83
+ // reactive re-entrancy. Falls back to '' (CSS [wrap] handles the
84
+ // always-wrap case; this only fires when wrap-at is set).
85
+ if (wrapAt) {
86
+ const activeIdx = BP_NAMES.indexOf(bp);
87
+ const targetIdx = BP_NAMES.indexOf(wrapAt);
88
+ this.style.flexWrap = (targetIdx !== -1 && activeIdx >= targetIdx) ? 'wrap' : '';
89
+ } else {
90
+ this.style.flexWrap = '';
91
+ }
92
+ }
50
93
  }
94
+
95
+ const _ALIGN = { start: 'flex-start', end: 'flex-end', center: 'center', stretch: 'stretch', baseline: 'baseline' };
96
+ const _JUSTIFY = { start: 'flex-start', end: 'flex-end', center: 'center', between: 'space-between', 'space-between': 'space-between', 'space-around': 'space-around' };
97
+
98
+ function _gapToCss(v) { return (!v || v === '0') ? '0' : /^\d+$/.test(v) ? `var(--a-space-${v})` : `var(--a-gap-${v})`; }
99
+ function _flexAlign(v) { return _ALIGN[v] ?? v; }
100
+ function _flexJustify(v) { return _JUSTIFY[v] ?? v; }
@@ -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/Row.json",
4
4
  "title": "Row",
5
- "description": "Flex row layout primitive.",
5
+ "description": "Flex row layout primitive — horizontal stack of children with\n[gap] / [align] / [justify] / [grow] / [wrap]. The horizontal\ncounterpart to <col-ui>. Use <row-ui> for horizontal toolbars,\ninline-control clusters, button groups, table cells. For action\nclusters inside chrome containers (<header-ui> / <footer-ui>) use\nthe parent's [slot=\"action\"] convention instead — the chrome scope\nalready lays out actions correctly without wrapping in row-ui.\n",
6
6
  "type": "object",
7
7
  "allOf": [
8
8
  {
@@ -14,7 +14,7 @@
14
14
  ],
15
15
  "properties": {
16
16
  "align": {
17
- "description": "Align items",
17
+ "description": "Cross-axis alignment (start/center/end/stretch/baseline). Accepts `@bp` notation: align=\"start center@sm\".",
18
18
  "type": "string",
19
19
  "default": "center"
20
20
  },
@@ -27,7 +27,7 @@
27
27
  "default": false
28
28
  },
29
29
  "gap": {
30
- "description": "Gap between children. Accepts either the named scale (xs/sm/md/lg/xl) or a numeric rung on the spacing scale (\"1\"…\"16\").",
30
+ "description": "Gap between children. Named scale (xs/sm/md/lg/xl) or numeric spacing rung (\"1\"…\"16\"). Accepts `@bp` notation: gap=\"2 4@md\".",
31
31
  "type": "string",
32
32
  "default": "md"
33
33
  },
@@ -37,14 +37,19 @@
37
37
  "default": false
38
38
  },
39
39
  "justify": {
40
- "description": "Justify content",
40
+ "description": "Main-axis justify (start/center/end/between/space-between/space-around). Accepts `@bp` notation: justify=\"start between@md\".",
41
41
  "type": "string",
42
42
  "default": "start"
43
43
  },
44
44
  "wrap": {
45
- "description": "Enable flex wrap",
45
+ "description": "Enable flex-wrap unconditionally. For viewport-responsive wrapping use [wrap-at] instead.",
46
46
  "type": "boolean",
47
47
  "default": false
48
+ },
49
+ "wrapAt": {
50
+ "description": "Enable flex-wrap from the named breakpoint upward (xs/sm/md/lg/xl). `wrap-at=\"sm\"` = no-wrap on xs, wrap from sm up. Complements the boolean [wrap] (always-wrap) without conflicting with it.",
51
+ "type": "string",
52
+ "default": ""
48
53
  }
49
54
  },
50
55
  "required": [
@@ -90,7 +95,13 @@
90
95
  "name": "idle"
91
96
  }
92
97
  ],
93
- "synonyms": {},
98
+ "synonyms": {
99
+ "row": [
100
+ "hstack",
101
+ "horizontal-stack",
102
+ "hbox"
103
+ ]
104
+ },
94
105
  "tag": "row-ui",
95
106
  "tokens": {},
96
107
  "traits": [],
@@ -1,5 +1,12 @@
1
1
  /**
2
- * `<row-ui>` — Flex row layout primitive.
2
+ * `<row-ui>` — Flex row layout primitive — horizontal stack of children with
3
+ [gap] / [align] / [justify] / [grow] / [wrap]. The horizontal
4
+ counterpart to <col-ui>. Use <row-ui> for horizontal toolbars,
5
+ inline-control clusters, button groups, table cells. For action
6
+ clusters inside chrome containers (<header-ui> / <footer-ui>) use
7
+ the parent's [slot="action"] convention instead — the chrome scope
8
+ already lays out actions correctly without wrapping in row-ui.
9
+
3
10
  *
4
11
  * @see https://ui-kit.exe.xyz/site/components/row
5
12
  *
@@ -13,16 +20,18 @@
13
20
  import { UIElement } from '../../core/element.js';
14
21
 
15
22
  export class UIRow extends UIElement {
16
- /** Align items */
23
+ /** Cross-axis alignment (start/center/end/stretch/baseline). Accepts `@bp` notation: align="start center@sm". */
17
24
  align: string;
18
25
  /** Enables drag handle + cursor:grab. Wires the draggable trait; dispatches drag-end. */
19
26
  draggable: boolean;
20
- /** Gap between children. Accepts either the named scale (xs/sm/md/lg/xl) or a numeric rung on the spacing scale ("1"…"16"). */
27
+ /** Gap between children. Named scale (xs/sm/md/lg/xl) or numeric spacing rung ("1"…"16"). Accepts `@bp` notation: gap="2 4@md". */
21
28
  gap: string;
22
29
  /** Fills remaining space in a flex parent. CSS-only attribute via :scope[grow] in row.css. */
23
30
  grow: boolean;
24
- /** Justify content */
31
+ /** Main-axis justify (start/center/end/between/space-between/space-around). Accepts `@bp` notation: justify="start between@md". */
25
32
  justify: string;
26
- /** Enable flex wrap */
33
+ /** Enable flex-wrap unconditionally. For viewport-responsive wrapping use [wrap-at] instead. */
27
34
  wrap: boolean;
35
+ /** Enable flex-wrap from the named breakpoint upward (xs/sm/md/lg/xl). `wrap-at="sm"` = no-wrap on xs, wrap from sm up. Complements the boolean [wrap] (always-wrap) without conflicting with it. */
36
+ wrapAt: string;
28
37
  }
@@ -6,10 +6,19 @@ tag: row-ui
6
6
  component: Row
7
7
  category: layout
8
8
  version: 1
9
- description: Flex row layout primitive.
9
+ description: |
10
+ Flex row layout primitive — horizontal stack of children with
11
+ [gap] / [align] / [justify] / [grow] / [wrap]. The horizontal
12
+ counterpart to <col-ui>. Use <row-ui> for horizontal toolbars,
13
+ inline-control clusters, button groups, table cells. For action
14
+ clusters inside chrome containers (<header-ui> / <footer-ui>) use
15
+ the parent's [slot="action"] convention instead — the chrome scope
16
+ already lays out actions correctly without wrapping in row-ui.
10
17
  props:
11
18
  align:
12
- description: Align items
19
+ description: >-
20
+ Cross-axis alignment (start/center/end/stretch/baseline). Accepts
21
+ `@bp` notation: align="start center@sm".
13
22
  type: string
14
23
  default: center
15
24
  draggable:
@@ -19,8 +28,8 @@ props:
19
28
  reflect: true
20
29
  gap:
21
30
  description: >-
22
- Gap between children. Accepts either the named scale (xs/sm/md/lg/xl)
23
- or a numeric rung on the spacing scale ("1"…"16").
31
+ Gap between children. Named scale (xs/sm/md/lg/xl) or numeric spacing
32
+ rung ("1"…"16"). Accepts `@bp` notation: gap="2 4@md".
24
33
  type: string
25
34
  default: md
26
35
  grow:
@@ -29,13 +38,25 @@ props:
29
38
  default: false
30
39
  reflect: true
31
40
  justify:
32
- description: Justify content
41
+ description: >-
42
+ Main-axis justify (start/center/end/between/space-between/space-around).
43
+ Accepts `@bp` notation: justify="start between@md".
33
44
  type: string
34
45
  default: start
35
46
  wrap:
36
- description: Enable flex wrap
47
+ description: >-
48
+ Enable flex-wrap unconditionally. For viewport-responsive wrapping use
49
+ [wrap-at] instead.
37
50
  type: boolean
38
51
  default: false
52
+ wrapAt:
53
+ description: >-
54
+ Enable flex-wrap from the named breakpoint upward (xs/sm/md/lg/xl).
55
+ `wrap-at="sm"` = no-wrap on xs, wrap from sm up. Complements the
56
+ boolean [wrap] (always-wrap) without conflicting with it.
57
+ type: string
58
+ default: ""
59
+ attribute: wrap-at
39
60
  events: {}
40
61
  slots:
41
62
  default:
@@ -46,7 +67,13 @@ states:
46
67
  traits: []
47
68
  tokens: {}
48
69
  a2ui:
49
- rules: []
70
+ rules:
71
+ - rule: 'Horizontal-stack flex container. Children flow left-to-right with token-driven gap.'
72
+ reason: 'Canonical horizontal layout.'
73
+ - rule: 'Pair with <col-ui> for vertical layouts; both share the same gap-token contract.'
74
+ reason: 'Layout symmetry.'
75
+ - rule: 'Wrap attribute enables flex-wrap; default is nowrap.'
76
+ reason: 'Single-line vs multi-line knob.'
50
77
  anti_patterns: []
51
78
  examples:
52
79
  - name: chat-interface
@@ -348,7 +375,8 @@ examples:
348
375
  ]
349
376
  keywords:
350
377
  - row
351
- synonyms: {}
378
+ synonyms:
379
+ row: [hstack, horizontal-stack, hbox]
352
380
  related:
353
381
  - avatar
354
382
  - input
@@ -94,7 +94,11 @@
94
94
  "combobox"
95
95
  ],
96
96
  "name": "UISearch",
97
- "related": [],
97
+ "related": [
98
+ "Input",
99
+ "Command",
100
+ "Select"
101
+ ],
98
102
  "slots": {
99
103
  "clear": {
100
104
  "description": "Clear button (shown when value is non-empty)"
@@ -71,7 +71,13 @@ tokens:
71
71
  --search-radius:
72
72
  description: Input border radius
73
73
  a2ui:
74
- rules: []
74
+ rules:
75
+ - rule: 'Search-input variant of <input-ui> with built-in search icon + clear affordance.'
76
+ reason: 'Search-input canonical primitive.'
77
+ - rule: 'For command-palette interactions use <command-ui> (which composes search + menu).'
78
+ reason: 'Specialized command surface.'
79
+ - rule: 'Emits input events on each keystroke; debounce in the consumer for live-search.'
80
+ reason: 'Standard event model.'
75
81
  anti_patterns: []
76
82
  examples:
77
83
  - name: basic-search
@@ -153,4 +159,7 @@ synonyms:
153
159
  - search
154
160
  - command
155
161
  - palette
156
- related: []
162
+ related:
163
+ - Input
164
+ - Command
165
+ - Select
@@ -70,7 +70,13 @@
70
70
  "name": "idle"
71
71
  }
72
72
  ],
73
- "synonyms": {},
73
+ "synonyms": {
74
+ "section": [
75
+ "section-region",
76
+ "body-region",
77
+ "content-section"
78
+ ]
79
+ },
74
80
  "tag": "section-ui",
75
81
  "tokens": {},
76
82
  "traits": [],
@@ -27,7 +27,40 @@ states:
27
27
  traits: []
28
28
  tokens: {}
29
29
  a2ui:
30
- rules: []
30
+ rules:
31
+ - >-
32
+ Use <section-ui> as the content body region inside a primitive
33
+ container parent (<card-ui>, <drawer-ui>, <modal-ui>, <page-ui>)
34
+ OR inside the body region of a bespoke shell-tier sidebar
35
+ (<admin-sidebar> nav body — site/index.html and the admin-shell
36
+ playground use this canonically). It is a CSS-only chrome stub
37
+ for ADR-0009 slot vocabulary; the parent's @scope handles padding
38
+ and borders.
39
+ - >-
40
+ `scroll` is a CONDITIONAL attribute. It makes section-ui the
41
+ scroll container ONLY inside <card-ui> / <drawer-ui> / <modal-ui>.
42
+ Inside <page-ui> and shell-tier hosts (<admin-shell>,
43
+ <admin-page-body>) it is a no-op — those parents own their own
44
+ scroll surface. Never nest <section-ui scroll> inside another
45
+ scroll container (nested scroll is a UX anti-pattern).
46
+ - >-
47
+ Use `bleed` to remove section padding so children reach the
48
+ card / drawer edges — typical for cover images, full-width charts,
49
+ or media galleries (apps/saas/members.contents.html uses this
50
+ pattern to wrap <table-ui raw>). Mix bleed and non-bleed sections
51
+ in the same card to alternate edge-to-edge media with padded
52
+ prose.
53
+ - >-
54
+ Do NOT substitute <section-ui> for bespoke shell-tier body
55
+ regions. Inside <admin-page> use <admin-page-body>; inside
56
+ <admin-content> use the bespoke children. <section-ui> is
57
+ reserved for the primitive container chrome triad + the
58
+ <admin-sidebar> nav body.
59
+ - >-
60
+ <section-ui> is the right place for layout primitives
61
+ (<col-ui>, <row-ui>, <grid-ui>) that organize body content. Do
62
+ NOT put those layout primitives inside <header-ui> or <footer-ui>
63
+ — the parent's chrome scope already lays those rows out.
31
64
  anti_patterns: []
32
65
  examples:
33
66
  - name: chat-interface
@@ -329,7 +362,8 @@ examples:
329
362
  ]
330
363
  keywords:
331
364
  - section
332
- synonyms: {}
365
+ synonyms:
366
+ section: [section-region, body-region, content-section]
333
367
  related:
334
368
  - avatar
335
369
  - input
@@ -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/Segment.json",
4
4
  "title": "Segment",
5
- "description": "Individual segment option, child of segmented-ui.",
5
+ "description": "Individual segment child of <segmented-ui> — carries the [value],\n[text], optional [icon], and [selected] state for one option in\na horizontal segmented selector. Distinct from <tab-ui> (a view\nswitcher's child) and <option> (native option for <select-ui>).\nUse segment-ui only as a direct child of <segmented-ui>; never\nstandalone.\n",
6
6
  "type": "object",
7
7
  "allOf": [
8
8
  {
@@ -99,7 +99,13 @@
99
99
  "name": "disabled"
100
100
  }
101
101
  ],
102
- "synonyms": {},
102
+ "synonyms": {
103
+ "segment": [
104
+ "segment-button",
105
+ "segmented-option",
106
+ "option-button"
107
+ ]
108
+ },
103
109
  "tag": "segment-ui",
104
110
  "tokens": {},
105
111
  "traits": [],
@@ -1,5 +1,11 @@
1
1
  /**
2
- * `<segment-ui>` — Individual segment option, child of segmented-ui.
2
+ * `<segment-ui>` — Individual segment child of <segmented-ui> — carries the [value],
3
+ [text], optional [icon], and [selected] state for one option in
4
+ a horizontal segmented selector. Distinct from <tab-ui> (a view
5
+ switcher's child) and <option> (native option for <select-ui>).
6
+ Use segment-ui only as a direct child of <segmented-ui>; never
7
+ standalone.
8
+
3
9
  *
4
10
  * @see https://ui-kit.exe.xyz/site/components/segment
5
11
  *
@@ -6,7 +6,13 @@ tag: segment-ui
6
6
  component: Segment
7
7
  category: navigation
8
8
  version: 1
9
- description: Individual segment option, child of segmented-ui.
9
+ description: |
10
+ Individual segment child of <segmented-ui> — carries the [value],
11
+ [text], optional [icon], and [selected] state for one option in
12
+ a horizontal segmented selector. Distinct from <tab-ui> (a view
13
+ switcher's child) and <option> (native option for <select-ui>).
14
+ Use segment-ui only as a direct child of <segmented-ui>; never
15
+ standalone.
10
16
  # Per ADR-0027 — primitives that programmatically create other primitives
11
17
  # do NOT auto-import them. Consumer (or demo shell) must explicitly import.
12
18
  composes:
@@ -46,7 +52,13 @@ states:
46
52
  traits: []
47
53
  tokens: {}
48
54
  a2ui:
49
- rules: []
55
+ rules:
56
+ - rule: 'Child of <segmented-ui> — one selectable option button in a single-select group.'
57
+ reason: 'Cluster contract.'
58
+ - rule: 'Different from <toggle-option-ui> (which is multi-select inside <toggle-group-ui>).'
59
+ reason: 'Single vs multi-select sibling distinction.'
60
+ - rule: 'Selected state managed by parent <segmented-ui> via active attribute; do not set selected directly on segment.'
61
+ reason: 'Parent owns selection state.'
50
62
  anti_patterns: []
51
63
  examples:
52
64
  - name: segmented-control
@@ -220,6 +232,7 @@ examples:
220
232
  ]
221
233
  keywords:
222
234
  - segment
223
- synonyms: {}
235
+ synonyms:
236
+ segment: [segment-button, segmented-option, option-button]
224
237
  related:
225
238
  - segmented-control
@@ -53,7 +53,12 @@
53
53
  "button-group"
54
54
  ],
55
55
  "name": "UISegmented",
56
- "related": [],
56
+ "related": [
57
+ "Segment",
58
+ "ToggleGroup",
59
+ "Tabs",
60
+ "Radio"
61
+ ],
57
62
  "slots": {
58
63
  "default": {
59
64
  "description": "Child segment-ui elements that form the toggle group. Children MUST be segment-ui — bare segment tags render text but are silently ignored for the sliding indicator and role/aria-checked state."
@@ -32,6 +32,11 @@
32
32
  grid-auto-columns: 1fr;
33
33
  align-items: stretch;
34
34
  position: relative;
35
+ /* Allow shrinking inside flex/grid containers (e.g. card header action
36
+ slot). Without this, inline-grid never shrinks below its max-content
37
+ width and the control overflows rather than triggering the per-segment
38
+ ::after text-overflow:ellipsis rules. */
39
+ min-width: 0;
35
40
  /* Children use `position: relative; z-index: 1` (segments) so they
36
41
  paint above the absolute indicator. Without an own stacking context
37
42
  here, those z-indexed children escape into the parent context and
@@ -24,7 +24,13 @@ states:
24
24
  traits: []
25
25
  tokens: {}
26
26
  a2ui:
27
- rules: []
27
+ rules:
28
+ - rule: 'Single-select segmented control. Hosts <segment-ui> children; exactly one selected at a time.'
29
+ reason: 'Single-select cluster contract.'
30
+ - rule: 'For multi-select use <toggle-group-ui> + <toggle-option-ui> instead.'
31
+ reason: 'Selection model boundary.'
32
+ - rule: 'Use for view-mode switches (grid/list, light/dark) or short filter sets (3-5 options); for longer sets use <tabs-ui> or <select-ui>.'
33
+ reason: 'Capacity guidance.'
28
34
  anti_patterns: []
29
35
  examples:
30
36
  - name: basic-segmented
@@ -116,4 +122,8 @@ synonyms:
116
122
  tags:
117
123
  - SegmentedControl
118
124
  - Segmented
119
- related: []
125
+ related:
126
+ - Segment
127
+ - ToggleGroup
128
+ - Tabs
129
+ - Radio