@adres/mgda-ui 0.0.0-stage → 0.0.1

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 (325) hide show
  1. package/brand-knowledge.json +451 -0
  2. package/knowledge/accordion.md +135 -0
  3. package/knowledge/activity-rings.md +123 -0
  4. package/knowledge/alert.md +184 -0
  5. package/knowledge/answer-actions.md +217 -0
  6. package/knowledge/aspect-ratio.md +82 -0
  7. package/knowledge/avatar.md +158 -0
  8. package/knowledge/badge.md +172 -0
  9. package/knowledge/bar-graph.md +167 -0
  10. package/knowledge/bento-grid.md +115 -0
  11. package/knowledge/blockquote.md +153 -0
  12. package/knowledge/box-list.md +177 -0
  13. package/knowledge/bullet-list.md +128 -0
  14. package/knowledge/button-group.md +179 -0
  15. package/knowledge/button.md +231 -0
  16. package/knowledge/calendar.md +168 -0
  17. package/knowledge/card.md +321 -0
  18. package/knowledge/cards-nav.md +170 -0
  19. package/knowledge/chain-of-thought.md +164 -0
  20. package/knowledge/chat-container.md +135 -0
  21. package/knowledge/chat-message.md +224 -0
  22. package/knowledge/checkbox-card.md +172 -0
  23. package/knowledge/checkbox.md +111 -0
  24. package/knowledge/citations.md +241 -0
  25. package/knowledge/combobox.md +265 -0
  26. package/knowledge/countdown-pill.md +153 -0
  27. package/knowledge/cta.md +118 -0
  28. package/knowledge/data-list.md +173 -0
  29. package/knowledge/data-table.md +220 -0
  30. package/knowledge/dialog.md +249 -0
  31. package/knowledge/drawer.md +236 -0
  32. package/knowledge/dropdown-menu.md +238 -0
  33. package/knowledge/dropzone.md +153 -0
  34. package/knowledge/email-chips-input.md +161 -0
  35. package/knowledge/empty-state.md +106 -0
  36. package/knowledge/entity-header.md +166 -0
  37. package/knowledge/feature-grid.md +120 -0
  38. package/knowledge/feedback-bar.md +127 -0
  39. package/knowledge/footer.md +116 -0
  40. package/knowledge/heading.md +189 -0
  41. package/knowledge/hero.md +361 -0
  42. package/knowledge/input-button.md +187 -0
  43. package/knowledge/input-group.md +185 -0
  44. package/knowledge/input.md +256 -0
  45. package/knowledge/inset.md +177 -0
  46. package/knowledge/kpi-card.md +206 -0
  47. package/knowledge/list-nav.md +181 -0
  48. package/knowledge/logo-cloud.md +102 -0
  49. package/knowledge/media-gallery.md +158 -0
  50. package/knowledge/message-actions.md +175 -0
  51. package/knowledge/nav-sidebar.md +225 -0
  52. package/knowledge/number-stepper.md +159 -0
  53. package/knowledge/page-header.md +109 -0
  54. package/knowledge/pagination.md +225 -0
  55. package/knowledge/popover.md +159 -0
  56. package/knowledge/pricing.md +132 -0
  57. package/knowledge/progress.md +156 -0
  58. package/knowledge/prompt-input.md +337 -0
  59. package/knowledge/prompt-suggestions.md +168 -0
  60. package/knowledge/quota-bar.md +160 -0
  61. package/knowledge/quote.md +116 -0
  62. package/knowledge/radio-card.md +172 -0
  63. package/knowledge/radio-group.md +135 -0
  64. package/knowledge/reasoning.md +142 -0
  65. package/knowledge/search.md +131 -0
  66. package/knowledge/section-nav.md +162 -0
  67. package/knowledge/segmented-control.md +181 -0
  68. package/knowledge/select-button.md +205 -0
  69. package/knowledge/select.md +210 -0
  70. package/knowledge/separator.md +75 -0
  71. package/knowledge/shimmer-text.md +140 -0
  72. package/knowledge/sidebar.md +227 -0
  73. package/knowledge/skeleton.md +142 -0
  74. package/knowledge/slider.md +133 -0
  75. package/knowledge/slideshow.md +159 -0
  76. package/knowledge/source.md +156 -0
  77. package/knowledge/spinner.md +120 -0
  78. package/knowledge/stat-strip.md +128 -0
  79. package/knowledge/stats.md +117 -0
  80. package/knowledge/step-indicator.md +157 -0
  81. package/knowledge/switch.md +88 -0
  82. package/knowledge/table.md +190 -0
  83. package/knowledge/tabs.md +169 -0
  84. package/knowledge/testimonials.md +115 -0
  85. package/knowledge/text-link.md +192 -0
  86. package/knowledge/text.md +194 -0
  87. package/knowledge/thinking-bar.md +115 -0
  88. package/knowledge/thinking-steps.md +140 -0
  89. package/knowledge/toaster.md +127 -0
  90. package/knowledge/toggle.md +113 -0
  91. package/knowledge/tool-call-card.md +241 -0
  92. package/knowledge/tooltip.md +120 -0
  93. package/knowledge/top-nav.md +138 -0
  94. package/knowledge.json +19854 -0
  95. package/package.json +94 -4
  96. package/src/components/accordion.stories.tsx +46 -0
  97. package/src/components/accordion.tsx +74 -0
  98. package/src/components/activity-rings.stories.tsx +73 -0
  99. package/src/components/activity-rings.tsx +121 -0
  100. package/src/components/alert.stories.tsx +43 -0
  101. package/src/components/alert.tsx +132 -0
  102. package/src/components/answer-actions.stories.tsx +54 -0
  103. package/src/components/answer-actions.test.tsx +37 -0
  104. package/src/components/answer-actions.tsx +313 -0
  105. package/src/components/aspect-ratio.stories.tsx +32 -0
  106. package/src/components/aspect-ratio.tsx +5 -0
  107. package/src/components/avatar.stories.tsx +40 -0
  108. package/src/components/avatar.tsx +154 -0
  109. package/src/components/badge.stories.tsx +27 -0
  110. package/src/components/badge.tsx +63 -0
  111. package/src/components/bar-graph.stories.tsx +28 -0
  112. package/src/components/bar-graph.tsx +204 -0
  113. package/src/components/bento-grid.stories.tsx +23 -0
  114. package/src/components/bento-grid.tsx +67 -0
  115. package/src/components/blockquote.stories.tsx +28 -0
  116. package/src/components/blockquote.tsx +88 -0
  117. package/src/components/box-list.stories.tsx +25 -0
  118. package/src/components/box-list.tsx +108 -0
  119. package/src/components/bullet-list.stories.tsx +22 -0
  120. package/src/components/bullet-list.tsx +101 -0
  121. package/src/components/button-group.stories.tsx +31 -0
  122. package/src/components/button-group.tsx +156 -0
  123. package/src/components/button.stories.tsx +66 -0
  124. package/src/components/button.test.ts +17 -0
  125. package/src/components/button.tsx +139 -0
  126. package/src/components/calendar.stories.tsx +25 -0
  127. package/src/components/calendar.tsx +367 -0
  128. package/src/components/card.stories.tsx +44 -0
  129. package/src/components/card.tsx +392 -0
  130. package/src/components/cards-nav.stories.tsx +35 -0
  131. package/src/components/cards-nav.tsx +115 -0
  132. package/src/components/chain-of-thought.stories.tsx +67 -0
  133. package/src/components/chain-of-thought.test.tsx +50 -0
  134. package/src/components/chain-of-thought.tsx +170 -0
  135. package/src/components/chat-container.stories.tsx +47 -0
  136. package/src/components/chat-container.test.tsx +49 -0
  137. package/src/components/chat-container.tsx +222 -0
  138. package/src/components/chat-message.stories.tsx +52 -0
  139. package/src/components/chat-message.test.tsx +36 -0
  140. package/src/components/chat-message.tsx +163 -0
  141. package/src/components/checkbox-card.stories.tsx +27 -0
  142. package/src/components/checkbox-card.tsx +200 -0
  143. package/src/components/checkbox.stories.tsx +26 -0
  144. package/src/components/checkbox.tsx +61 -0
  145. package/src/components/citations.stories.tsx +64 -0
  146. package/src/components/citations.test.tsx +61 -0
  147. package/src/components/citations.tsx +220 -0
  148. package/src/components/combobox.stories.tsx +184 -0
  149. package/src/components/combobox.test.tsx +82 -0
  150. package/src/components/combobox.tsx +407 -0
  151. package/src/components/countdown-pill.stories.tsx +24 -0
  152. package/src/components/countdown-pill.tsx +129 -0
  153. package/src/components/cta.stories.tsx +29 -0
  154. package/src/components/cta.tsx +52 -0
  155. package/src/components/data-list.stories.tsx +50 -0
  156. package/src/components/data-list.test.tsx +35 -0
  157. package/src/components/data-list.tsx +181 -0
  158. package/src/components/data-table.stories.tsx +29 -0
  159. package/src/components/data-table.tsx +200 -0
  160. package/src/components/dialog.stories.tsx +42 -0
  161. package/src/components/dialog.tsx +200 -0
  162. package/src/components/drawer.stories.tsx +48 -0
  163. package/src/components/drawer.tsx +385 -0
  164. package/src/components/dropdown-menu.stories.tsx +41 -0
  165. package/src/components/dropdown-menu.tsx +252 -0
  166. package/src/components/dropzone.stories.tsx +19 -0
  167. package/src/components/dropzone.tsx +250 -0
  168. package/src/components/email-chips-input.stories.tsx +135 -0
  169. package/src/components/email-chips-input.tsx +210 -0
  170. package/src/components/empty-state.stories.tsx +22 -0
  171. package/src/components/empty-state.tsx +35 -0
  172. package/src/components/entity-header.stories.tsx +43 -0
  173. package/src/components/entity-header.test.tsx +35 -0
  174. package/src/components/entity-header.tsx +92 -0
  175. package/src/components/feature-grid.stories.tsx +25 -0
  176. package/src/components/feature-grid.tsx +87 -0
  177. package/src/components/feedback-bar.stories.tsx +25 -0
  178. package/src/components/feedback-bar.test.tsx +24 -0
  179. package/src/components/feedback-bar.tsx +62 -0
  180. package/src/components/footer.stories.tsx +23 -0
  181. package/src/components/footer.tsx +78 -0
  182. package/src/components/heading.stories.tsx +45 -0
  183. package/src/components/heading.test.tsx +22 -0
  184. package/src/components/heading.tsx +77 -0
  185. package/src/components/hero.stories.tsx +38 -0
  186. package/src/components/hero.tsx +498 -0
  187. package/src/components/input-button.stories.tsx +19 -0
  188. package/src/components/input-button.tsx +112 -0
  189. package/src/components/input-group.stories.tsx +38 -0
  190. package/src/components/input-group.tsx +157 -0
  191. package/src/components/input.stories.tsx +31 -0
  192. package/src/components/input.tsx +284 -0
  193. package/src/components/inset.stories.tsx +29 -0
  194. package/src/components/inset.tsx +70 -0
  195. package/src/components/kpi-card.stories.tsx +29 -0
  196. package/src/components/kpi-card.tsx +284 -0
  197. package/src/components/list-nav.stories.tsx +22 -0
  198. package/src/components/list-nav.tsx +145 -0
  199. package/src/components/logo-cloud.stories.tsx +23 -0
  200. package/src/components/logo-cloud.tsx +42 -0
  201. package/src/components/media-gallery.stories.tsx +25 -0
  202. package/src/components/media-gallery.tsx +347 -0
  203. package/src/components/message-actions.stories.tsx +45 -0
  204. package/src/components/message-actions.test.tsx +32 -0
  205. package/src/components/message-actions.tsx +119 -0
  206. package/src/components/nav-sidebar.stories.tsx +58 -0
  207. package/src/components/nav-sidebar.test.tsx +54 -0
  208. package/src/components/nav-sidebar.tsx +462 -0
  209. package/src/components/number-stepper.stories.tsx +19 -0
  210. package/src/components/number-stepper.tsx +158 -0
  211. package/src/components/page-header.stories.tsx +25 -0
  212. package/src/components/page-header.tsx +64 -0
  213. package/src/components/pagination.stories.tsx +110 -0
  214. package/src/components/pagination.test.tsx +46 -0
  215. package/src/components/pagination.tsx +144 -0
  216. package/src/components/popover.stories.tsx +26 -0
  217. package/src/components/popover.tsx +62 -0
  218. package/src/components/pricing.stories.tsx +42 -0
  219. package/src/components/pricing.tsx +130 -0
  220. package/src/components/progress.stories.tsx +22 -0
  221. package/src/components/progress.tsx +189 -0
  222. package/src/components/prompt-input.stories.tsx +62 -0
  223. package/src/components/prompt-input.test.tsx +106 -0
  224. package/src/components/prompt-input.tsx +343 -0
  225. package/src/components/prompt-suggestions.stories.tsx +53 -0
  226. package/src/components/prompt-suggestions.test.tsx +37 -0
  227. package/src/components/prompt-suggestions.tsx +122 -0
  228. package/src/components/quota-bar.stories.tsx +19 -0
  229. package/src/components/quota-bar.tsx +191 -0
  230. package/src/components/quote.stories.tsx +18 -0
  231. package/src/components/quote.tsx +43 -0
  232. package/src/components/radio-card.stories.tsx +27 -0
  233. package/src/components/radio-card.tsx +225 -0
  234. package/src/components/radio-group.stories.tsx +32 -0
  235. package/src/components/radio-group.tsx +68 -0
  236. package/src/components/reasoning.stories.tsx +50 -0
  237. package/src/components/reasoning.test.tsx +48 -0
  238. package/src/components/reasoning.tsx +143 -0
  239. package/src/components/search.stories.tsx +18 -0
  240. package/src/components/search.tsx +133 -0
  241. package/src/components/section-nav.stories.tsx +59 -0
  242. package/src/components/section-nav.test.tsx +36 -0
  243. package/src/components/section-nav.tsx +146 -0
  244. package/src/components/segmented-control.stories.tsx +22 -0
  245. package/src/components/segmented-control.tsx +301 -0
  246. package/src/components/select-button.stories.tsx +27 -0
  247. package/src/components/select-button.tsx +174 -0
  248. package/src/components/select.stories.tsx +27 -0
  249. package/src/components/select.tsx +198 -0
  250. package/src/components/separator.stories.tsx +22 -0
  251. package/src/components/separator.tsx +23 -0
  252. package/src/components/shimmer-text.stories.tsx +23 -0
  253. package/src/components/shimmer-text.test.tsx +35 -0
  254. package/src/components/shimmer-text.tsx +43 -0
  255. package/src/components/sidebar.stories.tsx +25 -0
  256. package/src/components/sidebar.tsx +234 -0
  257. package/src/components/skeleton.stories.tsx +22 -0
  258. package/src/components/skeleton.tsx +96 -0
  259. package/src/components/slider.stories.tsx +20 -0
  260. package/src/components/slider.tsx +176 -0
  261. package/src/components/slideshow.stories.tsx +30 -0
  262. package/src/components/slideshow.tsx +291 -0
  263. package/src/components/source.stories.tsx +32 -0
  264. package/src/components/source.test.tsx +40 -0
  265. package/src/components/source.tsx +161 -0
  266. package/src/components/spinner.stories.tsx +19 -0
  267. package/src/components/spinner.tsx +76 -0
  268. package/src/components/stat-strip.stories.tsx +36 -0
  269. package/src/components/stat-strip.test.tsx +25 -0
  270. package/src/components/stat-strip.tsx +85 -0
  271. package/src/components/stats.stories.tsx +24 -0
  272. package/src/components/stats.tsx +83 -0
  273. package/src/components/step-indicator.stories.tsx +18 -0
  274. package/src/components/step-indicator.test.tsx +18 -0
  275. package/src/components/step-indicator.tsx +286 -0
  276. package/src/components/switch.stories.tsx +26 -0
  277. package/src/components/switch.tsx +32 -0
  278. package/src/components/table.stories.tsx +38 -0
  279. package/src/components/table.tsx +220 -0
  280. package/src/components/tabs.stories.tsx +25 -0
  281. package/src/components/tabs.tsx +276 -0
  282. package/src/components/testimonials.stories.tsx +22 -0
  283. package/src/components/testimonials.tsx +109 -0
  284. package/src/components/text-link.stories.tsx +47 -0
  285. package/src/components/text-link.test.tsx +18 -0
  286. package/src/components/text-link.tsx +88 -0
  287. package/src/components/text.stories.tsx +49 -0
  288. package/src/components/text.tsx +105 -0
  289. package/src/components/thinking-bar.stories.tsx +19 -0
  290. package/src/components/thinking-bar.test.tsx +27 -0
  291. package/src/components/thinking-bar.tsx +64 -0
  292. package/src/components/thinking-steps.stories.tsx +44 -0
  293. package/src/components/thinking-steps.test.tsx +42 -0
  294. package/src/components/thinking-steps.tsx +92 -0
  295. package/src/components/toaster.stories.tsx +80 -0
  296. package/src/components/toaster.tsx +36 -0
  297. package/src/components/toggle.stories.tsx +21 -0
  298. package/src/components/toggle.tsx +103 -0
  299. package/src/components/tool-call-card.stories.tsx +97 -0
  300. package/src/components/tool-call-card.test.tsx +88 -0
  301. package/src/components/tool-call-card.tsx +231 -0
  302. package/src/components/tooltip.stories.tsx +25 -0
  303. package/src/components/tooltip.tsx +43 -0
  304. package/src/components/top-nav.stories.tsx +20 -0
  305. package/src/components/top-nav.tsx +76 -0
  306. package/src/docs/Colors.stories.tsx +192 -0
  307. package/src/docs/GettingStarted.mdx +72 -0
  308. package/src/docs/Mcp.mdx +52 -0
  309. package/src/docs/Typography.stories.tsx +114 -0
  310. package/src/hooks/use-in-view.ts +32 -0
  311. package/src/hooks/use-reduced-motion.ts +26 -0
  312. package/src/index.ts +343 -0
  313. package/src/lib/cn.test.ts +67 -0
  314. package/src/lib/cn.ts +81 -0
  315. package/src/lib/motion.ts +109 -0
  316. package/src/lib/prefix-utilities.test.ts +56 -0
  317. package/src/lib/prefix-utilities.ts +50 -0
  318. package/src/styles/base.css +489 -0
  319. package/src/styles/motion.css +69 -0
  320. package/src/styles/overrides.css +44 -0
  321. package/src/styles/typography.css +173 -0
  322. package/src/theme/theme.css +391 -0
  323. package/src/theme/tokens.ts +29 -0
  324. package/src/theme/types.ts +26 -0
  325. package/README.md +0 -3
@@ -0,0 +1,118 @@
1
+ ---
2
+ # >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
3
+ derived:
4
+ schemaVersion: 1
5
+ id: cta
6
+ sourceFile: packages/design-system/src/components/cta.tsx
7
+ client: true
8
+ category: marketing
9
+ categoryFromBarrel: marketing
10
+ barrelExported: true
11
+ importPath: "@adres/mgda-ui"
12
+ exports:
13
+ - name: CTA
14
+ kind: component
15
+ typeText: "ForwardRefExoticComponent<CTAProps & RefAttributes<HTMLElement>>"
16
+ - name: CTAProps
17
+ kind: type
18
+ primaryExport: CTA
19
+ subcomponents: []
20
+ props:
21
+ CTA:
22
+ - name: actions
23
+ type: ReactNode
24
+ required: true
25
+ declaredIn: self
26
+ - name: description
27
+ type: ReactNode
28
+ required: false
29
+ declaredIn: self
30
+ - name: emphasis
31
+ type: "\"primary\" | \"subtle\""
32
+ required: false
33
+ declaredIn: self
34
+ doc: "Visual emphasis - 'subtle' uses muted surface, 'primary' uses brand surface."
35
+ - name: title
36
+ type: ReactNode
37
+ required: true
38
+ declaredIn: self
39
+ extendsProps:
40
+ - "Omit<React.HTMLAttributes<HTMLElement>, \"title\">"
41
+ variants:
42
+ emphasis:
43
+ kind: enum
44
+ options:
45
+ - primary
46
+ - subtle
47
+ default: subtle
48
+ on: CTA
49
+ variantSource: prop-union
50
+ compoundVariants: []
51
+ sizeMaps: []
52
+ dataSlots: []
53
+ dependsOn:
54
+ internal: []
55
+ lib:
56
+ - cn
57
+ hooks: []
58
+ external:
59
+ - react
60
+ contexts: []
61
+ stories:
62
+ - exportName: Default
63
+ id: components-cta--default
64
+ - exportName: Primary
65
+ id: components-cta--primary
66
+ storybookTitle: Components/CTA
67
+ docsId: components-cta--documentation
68
+ argTypeOptions: {}
69
+ resolvedCleanly: true
70
+ contractHash: "03902c637b57"
71
+ factsHash: "0a48dcfc8d34"
72
+ # >>> AUTHORED - humans own everything below this line. <<<
73
+ status: stable
74
+ summary: "A closing call-to-action section for marketing pages - a centered headline, optional description, and an action row, in two emphasis levels."
75
+ useWhen:
76
+ - "closing out a marketing page with one clear next action - \"Get started\", \"Book a demo\", a final conversion push"
77
+ useInstead:
78
+ - id: feature-grid
79
+ when: "the section should showcase several product features, not drive toward one action"
80
+ related:
81
+ - feature-grid
82
+ a11y:
83
+ notes:
84
+ - "Renders a real section with an h2 title - it composes into the page's heading hierarchy, so ensure only one h1 precedes it and this genuinely reads as a section-level heading."
85
+ - "actions is untyped ReactNode - the component adds no button semantics itself, so whatever is passed, typically one or more Button components, needs its own real interactive markup and accessible naming."
86
+ radixHandles: false
87
+ pitfalls:
88
+ - "emphasis=\"primary\" swaps to the brand surface and inverts foreground text automatically - passing your own text color classes via className on children can fight this inversion rather than complementing it."
89
+ - "title accepts ReactNode, not just a string, but the component renders it directly inside an h2 with no wrapping - passing block-level content there can produce invalid heading markup."
90
+ - "There is no built-in max-width constraint on actions beyond flex-wrap - a long list of action buttons wraps rather than overflowing, but a page with many CTAs should still keep this section to one, maybe two, clear actions for it to read as intended."
91
+ canonicalSnippet: |
92
+ import { Button, CTA } from "@adres/mgda-ui"
93
+
94
+ const heading = "Ready to get started?"
95
+
96
+ <CTA
97
+ title={heading}
98
+ emphasis="primary"
99
+ actions={<Button variant="secondary">Book a demo</Button>}
100
+ />
101
+ reviewedAt: 2026-09-01
102
+ reviewedAgainstContractHash: "03902c637b57"
103
+ ---
104
+
105
+ ## Usage
106
+
107
+ `CTA` is a closing call-to-action section for marketing pages - a centered
108
+ headline, optional supporting text, and an action row, meant to drive toward
109
+ one clear next step. Reach for `FeatureGrid` instead when the section should
110
+ showcase several product features rather than push toward one action.
111
+
112
+ `emphasis="subtle"` (default) uses a muted surface for a CTA that sits
113
+ mid-page among other sections; `emphasis="primary"` uses the brand surface
114
+ with inverted foreground text for a stronger, usually page-closing, moment.
115
+
116
+ `actions` is untyped `ReactNode` - the component adds no button semantics of
117
+ its own, so pass real interactive elements, typically one or two `Button`s,
118
+ rather than plain text or links without their own accessible markup.
@@ -0,0 +1,173 @@
1
+ ---
2
+ # >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
3
+ derived:
4
+ schemaVersion: 1
5
+ id: data-list
6
+ sourceFile: packages/design-system/src/components/data-list.tsx
7
+ client: true
8
+ category: web-app-data
9
+ categoryFromBarrel: web-app-data
10
+ barrelExported: true
11
+ importPath: "@adres/mgda-ui"
12
+ exports:
13
+ - name: DataList
14
+ kind: component
15
+ typeText: "ForwardRefExoticComponent<DataListProps & RefAttributes<HTMLDListElement>>"
16
+ - name: DataListColumns
17
+ kind: type
18
+ - name: DataListItem
19
+ kind: component
20
+ typeText: "ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>>"
21
+ - name: DataListLabel
22
+ kind: component
23
+ typeText: "ForwardRefExoticComponent<HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement>>"
24
+ - name: DataListOrientation
25
+ kind: type
26
+ - name: DataListProps
27
+ kind: type
28
+ - name: DataListSize
29
+ kind: type
30
+ - name: DataListValue
31
+ kind: component
32
+ typeText: "ForwardRefExoticComponent<HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement>>"
33
+ primaryExport: DataList
34
+ subcomponents:
35
+ - DataListItem
36
+ - DataListLabel
37
+ - DataListValue
38
+ props:
39
+ DataList:
40
+ - name: columns
41
+ type: DataListColumns
42
+ required: false
43
+ declaredIn: self
44
+ doc: "Columns from `sm` up when `orientation=\"grid\"`; two below `sm`."
45
+ - name: orientation
46
+ type: DataListOrientation
47
+ required: false
48
+ declaredIn: self
49
+ doc: "`grid` lays items out in columns, label above value, without dividers - for short facts such as licence numbers or key dates."
50
+ - name: size
51
+ type: DataListSize
52
+ required: false
53
+ declaredIn: self
54
+ extendsProps:
55
+ - "React.HTMLAttributes<HTMLDListElement>"
56
+ variants:
57
+ size:
58
+ kind: enum
59
+ options:
60
+ - sm
61
+ - md
62
+ - lg
63
+ default: md
64
+ on: DataList
65
+ orientation:
66
+ kind: enum
67
+ options:
68
+ - grid
69
+ - horizontal
70
+ - vertical
71
+ default: horizontal
72
+ on: DataList
73
+ variantSource: prop-union
74
+ compoundVariants: []
75
+ sizeMaps:
76
+ - GRID_COLUMNS
77
+ - ITEM_GAP
78
+ - ITEM_GAP_X
79
+ - ITEM_PADDING
80
+ - LABEL_MIN_WIDTH
81
+ - LABEL_TEXT
82
+ - VALUE_TEXT
83
+ dataSlots: []
84
+ dependsOn:
85
+ internal: []
86
+ lib:
87
+ - cn
88
+ hooks: []
89
+ external:
90
+ - react
91
+ contexts:
92
+ - name: DataListContext
93
+ type: DataListContextValue
94
+ default: null
95
+ stories:
96
+ - exportName: Default
97
+ id: components-datalist--default
98
+ - exportName: Grid
99
+ id: components-datalist--grid
100
+ storybookTitle: Components/DataList
101
+ docsId: components-datalist--documentation
102
+ argTypeOptions: {}
103
+ resolvedCleanly: true
104
+ contractHash: "767a2e901e81"
105
+ factsHash: e022b7c1ee6d
106
+ # >>> AUTHORED - humans own everything below this line. <<<
107
+ status: stable
108
+ summary: "A semantic label/value summary list (dl/dt/dd), for a flat set of fields - not a table, not expandable sections."
109
+ useWhen:
110
+ - "showing a flat set of read-only label/value pairs - a record summary, metadata panel, review-before-submit screen"
111
+ useInstead:
112
+ - id: table
113
+ when: "there are multiple comparable records with the same fields, not a single record's fields"
114
+ - id: accordion
115
+ when: "any of the fields need to expand or collapse rather than always being visible"
116
+ related:
117
+ - table
118
+ - accordion
119
+ a11y:
120
+ notes:
121
+ - "Uses real dl/dt/dd elements, so the label/value relationship is conveyed to assistive tech natively - no extra ARIA is needed."
122
+ radixHandles: false
123
+ pitfalls:
124
+ - "orientation=\"horizontal\" (default) is itself responsive - it stacks label above value on mobile and only becomes a side-by-side row from the sm breakpoint up. orientation=\"vertical\" always stacks, at every width."
125
+ - "orientation=\"grid\" lays short facts in columns (columns 2, 3 or 4 from sm up; always two below sm), label above value, with no dividers. Use it for licence numbers or key dates beside a header; long values belong in the default list."
126
+ - "columns only applies to orientation=\"grid\"; on the other orientations it is ignored."
127
+ - "size drives five separate maps at once (item padding, label/value gap, label min-width, label and value type scale) - the md size intentionally uses a non-token half-step (py-2.5) specifically to match Table's md row height, so do not round it to a token value when customizing."
128
+ - "Horizontal rows share one subgrid track, so the label column sizes to the widest label across every row. min-width applies from sm up only as a floor when every label is short; a long label (e.g. a translated string) can still grow past it rather than wrap or clip."
129
+ canonicalSnippet: |
130
+ import { DataList, DataListItem, DataListLabel, DataListValue } from "@adres/mgda-ui"
131
+
132
+ <DataList size="md">
133
+ <DataListItem>
134
+ <DataListLabel>Status</DataListLabel>
135
+ <DataListValue>Active</DataListValue>
136
+ </DataListItem>
137
+ <DataListItem>
138
+ <DataListLabel>Created</DataListLabel>
139
+ <DataListValue>Jan 12, 2026</DataListValue>
140
+ </DataListItem>
141
+ </DataList>
142
+ reviewedAt: 2026-10-06
143
+ reviewedAgainstContractHash: "767a2e901e81"
144
+ ---
145
+
146
+ ## Usage
147
+
148
+ `DataList` is for a flat set of read-only label/value pairs describing one
149
+ record - a summary panel, metadata block, or review screen. Reach for `Table`
150
+ instead once there are multiple records sharing the same fields, and
151
+ `Accordion` if any field's value needs to expand or collapse rather than
152
+ always being visible.
153
+
154
+ `orientation="horizontal"` (default) is itself responsive: label above value
155
+ on mobile, a baseline-aligned row from the `sm` breakpoint up. Use
156
+ `orientation="vertical"` to always stack, at every width, regardless of
157
+ screen size.
158
+
159
+ `size` scales padding, the label/value gap, the label's minimum width (so
160
+ short labels form an aligned column without clipping a long one), and both
161
+ elements' type together - set it once on `DataList` rather than on the
162
+ sub-components.
163
+
164
+ ## Anatomy
165
+
166
+ `DataList` renders real semantic `<dl>`/`<dt>`/`<dd>` elements throughout.
167
+
168
+ | Part | Role |
169
+ | --- | --- |
170
+ | `DataList` | The `<dl>` root. Owns `size` and `orientation`, shared via context. |
171
+ | `DataListItem` | One row: a `<div>` grouping one label and its value. |
172
+ | `DataListLabel` | The `<dt>`. Gets a minimum width in horizontal orientation so a column of labels aligns. |
173
+ | `DataListValue` | The `<dd>`. |
@@ -0,0 +1,220 @@
1
+ ---
2
+ # >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
3
+ derived:
4
+ schemaVersion: 1
5
+ id: data-table
6
+ sourceFile: packages/design-system/src/components/data-table.tsx
7
+ client: true
8
+ category: web-app-data
9
+ categoryFromBarrel: web-app-data
10
+ barrelExported: true
11
+ importPath: "@adres/mgda-ui"
12
+ exports:
13
+ - name: ColumnDef
14
+ kind: type
15
+ - name: DataTable
16
+ kind: component
17
+ typeParameters:
18
+ - T
19
+ typeText: "<T>({ columns, data, size, className, rowKey, rowClassName, onRowClick, emptyMessage, headless, ...props }: DataTableProps<T>) => Element"
20
+ - name: DataTableAlign
21
+ kind: type
22
+ - name: DataTableProps
23
+ kind: type
24
+ - name: DataTableSize
25
+ kind: type
26
+ - name: rowStyle
27
+ kind: const
28
+ typeText: "{ readonly title: \"ax:font-medium ax:text-foreground-strong\"; readonly default: \"ax:font-normal ax:text-foreground\"; readonly muted: \"ax:font-normal ax:text-muted-foreground\"; }"
29
+ - name: SortDirection
30
+ kind: type
31
+ primaryExport: DataTable
32
+ subcomponents: []
33
+ props:
34
+ DataTable:
35
+ - name: columns
36
+ type: "ColumnDef<T>[]"
37
+ required: true
38
+ declaredIn: self
39
+ - name: data
40
+ type: "T[]"
41
+ required: true
42
+ declaredIn: self
43
+ - name: emptyMessage
44
+ type: string
45
+ required: false
46
+ declaredIn: self
47
+ doc: "Shown when data is empty."
48
+ - name: headless
49
+ type: boolean
50
+ required: false
51
+ declaredIn: self
52
+ doc: "Hide the header row entirely."
53
+ - name: onRowClick
54
+ type: "((row: T, index: number) => void)"
55
+ required: false
56
+ declaredIn: self
57
+ doc: "Row click handler. When provided, rows become clickable (cursor + role). Interactive children (buttons, links, menu triggers) should stopPropagation if they need to bypass the row click."
58
+ - name: rowClassName
59
+ type: "((row: T, index: number) => string | undefined)"
60
+ required: false
61
+ declaredIn: self
62
+ doc: "Per-row className. Lets callers visually mark rows (placeholders, status-specific tinting, etc.)."
63
+ - name: rowKey
64
+ type: "((row: T, index: number) => string | number)"
65
+ required: false
66
+ declaredIn: self
67
+ doc: "Key-accessor for React list rendering. Defaults to row index."
68
+ - name: size
69
+ type: DataTableSize
70
+ required: false
71
+ declaredIn: self
72
+ doc: "Visual density. Matches the Table component's size scale."
73
+ extendsProps:
74
+ - "Omit<React.HTMLAttributes<HTMLDivElement>, \"onClick\">"
75
+ variants:
76
+ size:
77
+ kind: enum
78
+ options:
79
+ - sm
80
+ - md
81
+ - lg
82
+ default: md
83
+ on: DataTable
84
+ variantSource: prop-union
85
+ compoundVariants: []
86
+ sizeMaps:
87
+ - CELL_PADDING
88
+ - CELL_TYPOGRAPHY
89
+ dataSlots:
90
+ - data-table
91
+ dependsOn:
92
+ internal: []
93
+ lib:
94
+ - cn
95
+ hooks: []
96
+ external:
97
+ - lucide-react
98
+ - react
99
+ contexts: []
100
+ stories:
101
+ - exportName: Default
102
+ id: components-datatable--default
103
+ storybookTitle: Components/DataTable
104
+ docsId: components-datatable--documentation
105
+ argTypeOptions: {}
106
+ resolvedCleanly: true
107
+ contractHash: d808fb84c598
108
+ factsHash: ce8594f5a4f4
109
+ # >>> AUTHORED - humans own everything below this line. <<<
110
+ status: stable
111
+ summary: "A column-driven table with built-in client-side sorting, density sizes and an empty state."
112
+ useWhen:
113
+ - "rendering rows of records where columns are defined in data, not markup"
114
+ - "you want click-to-sort without wiring the state yourself"
115
+ - "rows should be clickable to open a detail view"
116
+ useInstead:
117
+ - id: table
118
+ when: "you want to write the markup by hand, or need row spans, grouped headers, or a footer"
119
+ - id: data-list
120
+ when: "you are showing label and value pairs for a single record rather than many rows"
121
+ - id: empty-state
122
+ when: "the whole surface has no data and deserves a full illustration rather than one line in a cell"
123
+ related:
124
+ - table
125
+ - data-list
126
+ - empty-state
127
+ - skeleton
128
+ composesWith:
129
+ - badge
130
+ - button
131
+ - dropdown-menu
132
+ tokens:
133
+ - "--card"
134
+ - "--border"
135
+ - "--muted"
136
+ - "--muted-foreground"
137
+ - "--foreground"
138
+ - "--foreground-strong"
139
+ a11y:
140
+ notes:
141
+ - "aria-sort is set on the sorted header, so assistive technology reports the direction correctly."
142
+ - "Sortable headers are th elements with an onClick, not buttons, so sorting cannot be triggered from the keyboard. This is a known gap in the component, not something a caller can fix by passing a prop."
143
+ - "Clickable rows have the same problem: onRowClick attaches to the tr with a pointer cursor but no role, tabIndex or key handler, so the interaction is mouse-only. Where keyboard access matters, put a real Button or link inside a cell instead of relying on onRowClick."
144
+ requiredProps:
145
+ - "columns and data, both required"
146
+ keyboard:
147
+ - "None for sorting or row activation, see the notes above. Interactive elements you place inside cells keep their own keyboard behaviour."
148
+ radixHandles: false
149
+ pitfalls:
150
+ - "Sorting stringifies whatever accessor returns: String(accessor(row)) compared with localeCompare. If an accessor returns JSX, every value becomes \"[object Object]\" and the column silently does not sort. Give a sortable column an accessor that returns a string or number, and render the JSX in a separate non-sortable column."
151
+ - "Because the comparison is string-based, dates sort lexicographically. \"10 Jan\" lands before \"2 Feb\". Sort on an ISO date string or a timestamp instead."
152
+ - "Sort state is internal, so it resets whenever the component remounts and cannot be controlled, read, or initialised from outside."
153
+ - "Sorting is client-side over the data array you pass, so it only ever orders the current page. Combined with server pagination it sorts within the page and looks broken."
154
+ - "The click sequence is tri-state: ascending, then descending, then back to unsorted original order. The third click is easy to mistake for a bug."
155
+ - "onClick is deliberately omitted from the props type. Use onRowClick for rows, and note that interactive children need stopPropagation to avoid also firing it."
156
+ - "headless hides the header row, which also removes the only sorting affordance."
157
+ rtl: "Good. Column align uses logical start and end, which flip correctly, and ColumnDef.align documents that. Only align: center is direction-neutral."
158
+ brandNotes: "The shell uses --card with a --border ring and a --muted header, so brand changes flow through without touching the component. The exported rowStyle map carries weight and colour only, deliberately no font size, so density stays owned by the size prop."
159
+ canonicalSnippet: |
160
+ import { DataTable, rowStyle, type ColumnDef } from "@adres/mgda-ui"
161
+
162
+ type Unit = { id: string; name: string; sqft: number }
163
+
164
+ const columns: ColumnDef<Unit>[] = [
165
+ { key: "name", header: "Unit", accessor: (u) => u.name, sortable: true },
166
+ { key: "sqft", header: "Area", accessor: (u) => u.sqft, sortable: true, align: "end" },
167
+ ]
168
+
169
+ <DataTable
170
+ columns={columns}
171
+ data={units}
172
+ size="md"
173
+ rowKey={(u) => u.id}
174
+ onRowClick={(u) => open(u.id)}
175
+ emptyMessage="No units yet."
176
+ />
177
+ reviewedAt: 2026-09-29
178
+ reviewedAgainstContractHash: d808fb84c598
179
+ ---
180
+
181
+ ## Usage
182
+
183
+ DataTable trades flexibility for speed: you describe columns as data and get sorting,
184
+ density, an empty state and clickable rows without writing markup. When you need
185
+ control over the markup itself, drop to `Table`.
186
+
187
+ It is generic over the row type, so `ColumnDef<T>` gives you a typed `accessor` and
188
+ `onRowClick` receives the row, not an index. Keep the generic inferred by typing the
189
+ column array rather than casting inside the accessors.
190
+
191
+ ### The sorting trap
192
+
193
+ This is the single most important thing to know about this component. Sorting
194
+ compares `String(accessor(row))`, so an accessor that returns JSX produces
195
+ `"[object Object]"` for every row and the column quietly refuses to order.
196
+
197
+ ```tsx
198
+ // Broken: sorts by "[object Object]"
199
+ { key: "status", header: "Status", sortable: true,
200
+ accessor: (u) => <Badge>{u.status}</Badge> }
201
+
202
+ // Correct: sort on the value, render the chip in its own column
203
+ { key: "status", header: "Status", sortable: true, accessor: (u) => u.status }
204
+ ```
205
+
206
+ The same reasoning applies to dates and any formatted number: sort on the raw value,
207
+ present the formatted one.
208
+
209
+ ### Density and row text
210
+
211
+ `size` sets cell padding and cell typography together, matching `Table`'s scale so the
212
+ two components stay visually in sync. Use the exported `rowStyle` map inside accessors
213
+ to vary weight and colour, never size:
214
+
215
+ ```tsx
216
+ accessor: (u) => <span className={rowStyle.muted}>{u.ref}</span>
217
+ ```
218
+
219
+ `rowStyle` deliberately carries no font size, so the table's `size` prop stays the
220
+ single source of density.