@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.
- package/brand-knowledge.json +451 -0
- package/knowledge/accordion.md +135 -0
- package/knowledge/activity-rings.md +123 -0
- package/knowledge/alert.md +184 -0
- package/knowledge/answer-actions.md +217 -0
- package/knowledge/aspect-ratio.md +82 -0
- package/knowledge/avatar.md +158 -0
- package/knowledge/badge.md +172 -0
- package/knowledge/bar-graph.md +167 -0
- package/knowledge/bento-grid.md +115 -0
- package/knowledge/blockquote.md +153 -0
- package/knowledge/box-list.md +177 -0
- package/knowledge/bullet-list.md +128 -0
- package/knowledge/button-group.md +179 -0
- package/knowledge/button.md +231 -0
- package/knowledge/calendar.md +168 -0
- package/knowledge/card.md +321 -0
- package/knowledge/cards-nav.md +170 -0
- package/knowledge/chain-of-thought.md +164 -0
- package/knowledge/chat-container.md +135 -0
- package/knowledge/chat-message.md +224 -0
- package/knowledge/checkbox-card.md +172 -0
- package/knowledge/checkbox.md +111 -0
- package/knowledge/citations.md +241 -0
- package/knowledge/combobox.md +265 -0
- package/knowledge/countdown-pill.md +153 -0
- package/knowledge/cta.md +118 -0
- package/knowledge/data-list.md +173 -0
- package/knowledge/data-table.md +220 -0
- package/knowledge/dialog.md +249 -0
- package/knowledge/drawer.md +236 -0
- package/knowledge/dropdown-menu.md +238 -0
- package/knowledge/dropzone.md +153 -0
- package/knowledge/email-chips-input.md +161 -0
- package/knowledge/empty-state.md +106 -0
- package/knowledge/entity-header.md +166 -0
- package/knowledge/feature-grid.md +120 -0
- package/knowledge/feedback-bar.md +127 -0
- package/knowledge/footer.md +116 -0
- package/knowledge/heading.md +189 -0
- package/knowledge/hero.md +361 -0
- package/knowledge/input-button.md +187 -0
- package/knowledge/input-group.md +185 -0
- package/knowledge/input.md +256 -0
- package/knowledge/inset.md +177 -0
- package/knowledge/kpi-card.md +206 -0
- package/knowledge/list-nav.md +181 -0
- package/knowledge/logo-cloud.md +102 -0
- package/knowledge/media-gallery.md +158 -0
- package/knowledge/message-actions.md +175 -0
- package/knowledge/nav-sidebar.md +225 -0
- package/knowledge/number-stepper.md +159 -0
- package/knowledge/page-header.md +109 -0
- package/knowledge/pagination.md +225 -0
- package/knowledge/popover.md +159 -0
- package/knowledge/pricing.md +132 -0
- package/knowledge/progress.md +156 -0
- package/knowledge/prompt-input.md +337 -0
- package/knowledge/prompt-suggestions.md +168 -0
- package/knowledge/quota-bar.md +160 -0
- package/knowledge/quote.md +116 -0
- package/knowledge/radio-card.md +172 -0
- package/knowledge/radio-group.md +135 -0
- package/knowledge/reasoning.md +142 -0
- package/knowledge/search.md +131 -0
- package/knowledge/section-nav.md +162 -0
- package/knowledge/segmented-control.md +181 -0
- package/knowledge/select-button.md +205 -0
- package/knowledge/select.md +210 -0
- package/knowledge/separator.md +75 -0
- package/knowledge/shimmer-text.md +140 -0
- package/knowledge/sidebar.md +227 -0
- package/knowledge/skeleton.md +142 -0
- package/knowledge/slider.md +133 -0
- package/knowledge/slideshow.md +159 -0
- package/knowledge/source.md +156 -0
- package/knowledge/spinner.md +120 -0
- package/knowledge/stat-strip.md +128 -0
- package/knowledge/stats.md +117 -0
- package/knowledge/step-indicator.md +157 -0
- package/knowledge/switch.md +88 -0
- package/knowledge/table.md +190 -0
- package/knowledge/tabs.md +169 -0
- package/knowledge/testimonials.md +115 -0
- package/knowledge/text-link.md +192 -0
- package/knowledge/text.md +194 -0
- package/knowledge/thinking-bar.md +115 -0
- package/knowledge/thinking-steps.md +140 -0
- package/knowledge/toaster.md +127 -0
- package/knowledge/toggle.md +113 -0
- package/knowledge/tool-call-card.md +241 -0
- package/knowledge/tooltip.md +120 -0
- package/knowledge/top-nav.md +138 -0
- package/knowledge.json +19854 -0
- package/package.json +94 -4
- package/src/components/accordion.stories.tsx +46 -0
- package/src/components/accordion.tsx +74 -0
- package/src/components/activity-rings.stories.tsx +73 -0
- package/src/components/activity-rings.tsx +121 -0
- package/src/components/alert.stories.tsx +43 -0
- package/src/components/alert.tsx +132 -0
- package/src/components/answer-actions.stories.tsx +54 -0
- package/src/components/answer-actions.test.tsx +37 -0
- package/src/components/answer-actions.tsx +313 -0
- package/src/components/aspect-ratio.stories.tsx +32 -0
- package/src/components/aspect-ratio.tsx +5 -0
- package/src/components/avatar.stories.tsx +40 -0
- package/src/components/avatar.tsx +154 -0
- package/src/components/badge.stories.tsx +27 -0
- package/src/components/badge.tsx +63 -0
- package/src/components/bar-graph.stories.tsx +28 -0
- package/src/components/bar-graph.tsx +204 -0
- package/src/components/bento-grid.stories.tsx +23 -0
- package/src/components/bento-grid.tsx +67 -0
- package/src/components/blockquote.stories.tsx +28 -0
- package/src/components/blockquote.tsx +88 -0
- package/src/components/box-list.stories.tsx +25 -0
- package/src/components/box-list.tsx +108 -0
- package/src/components/bullet-list.stories.tsx +22 -0
- package/src/components/bullet-list.tsx +101 -0
- package/src/components/button-group.stories.tsx +31 -0
- package/src/components/button-group.tsx +156 -0
- package/src/components/button.stories.tsx +66 -0
- package/src/components/button.test.ts +17 -0
- package/src/components/button.tsx +139 -0
- package/src/components/calendar.stories.tsx +25 -0
- package/src/components/calendar.tsx +367 -0
- package/src/components/card.stories.tsx +44 -0
- package/src/components/card.tsx +392 -0
- package/src/components/cards-nav.stories.tsx +35 -0
- package/src/components/cards-nav.tsx +115 -0
- package/src/components/chain-of-thought.stories.tsx +67 -0
- package/src/components/chain-of-thought.test.tsx +50 -0
- package/src/components/chain-of-thought.tsx +170 -0
- package/src/components/chat-container.stories.tsx +47 -0
- package/src/components/chat-container.test.tsx +49 -0
- package/src/components/chat-container.tsx +222 -0
- package/src/components/chat-message.stories.tsx +52 -0
- package/src/components/chat-message.test.tsx +36 -0
- package/src/components/chat-message.tsx +163 -0
- package/src/components/checkbox-card.stories.tsx +27 -0
- package/src/components/checkbox-card.tsx +200 -0
- package/src/components/checkbox.stories.tsx +26 -0
- package/src/components/checkbox.tsx +61 -0
- package/src/components/citations.stories.tsx +64 -0
- package/src/components/citations.test.tsx +61 -0
- package/src/components/citations.tsx +220 -0
- package/src/components/combobox.stories.tsx +184 -0
- package/src/components/combobox.test.tsx +82 -0
- package/src/components/combobox.tsx +407 -0
- package/src/components/countdown-pill.stories.tsx +24 -0
- package/src/components/countdown-pill.tsx +129 -0
- package/src/components/cta.stories.tsx +29 -0
- package/src/components/cta.tsx +52 -0
- package/src/components/data-list.stories.tsx +50 -0
- package/src/components/data-list.test.tsx +35 -0
- package/src/components/data-list.tsx +181 -0
- package/src/components/data-table.stories.tsx +29 -0
- package/src/components/data-table.tsx +200 -0
- package/src/components/dialog.stories.tsx +42 -0
- package/src/components/dialog.tsx +200 -0
- package/src/components/drawer.stories.tsx +48 -0
- package/src/components/drawer.tsx +385 -0
- package/src/components/dropdown-menu.stories.tsx +41 -0
- package/src/components/dropdown-menu.tsx +252 -0
- package/src/components/dropzone.stories.tsx +19 -0
- package/src/components/dropzone.tsx +250 -0
- package/src/components/email-chips-input.stories.tsx +135 -0
- package/src/components/email-chips-input.tsx +210 -0
- package/src/components/empty-state.stories.tsx +22 -0
- package/src/components/empty-state.tsx +35 -0
- package/src/components/entity-header.stories.tsx +43 -0
- package/src/components/entity-header.test.tsx +35 -0
- package/src/components/entity-header.tsx +92 -0
- package/src/components/feature-grid.stories.tsx +25 -0
- package/src/components/feature-grid.tsx +87 -0
- package/src/components/feedback-bar.stories.tsx +25 -0
- package/src/components/feedback-bar.test.tsx +24 -0
- package/src/components/feedback-bar.tsx +62 -0
- package/src/components/footer.stories.tsx +23 -0
- package/src/components/footer.tsx +78 -0
- package/src/components/heading.stories.tsx +45 -0
- package/src/components/heading.test.tsx +22 -0
- package/src/components/heading.tsx +77 -0
- package/src/components/hero.stories.tsx +38 -0
- package/src/components/hero.tsx +498 -0
- package/src/components/input-button.stories.tsx +19 -0
- package/src/components/input-button.tsx +112 -0
- package/src/components/input-group.stories.tsx +38 -0
- package/src/components/input-group.tsx +157 -0
- package/src/components/input.stories.tsx +31 -0
- package/src/components/input.tsx +284 -0
- package/src/components/inset.stories.tsx +29 -0
- package/src/components/inset.tsx +70 -0
- package/src/components/kpi-card.stories.tsx +29 -0
- package/src/components/kpi-card.tsx +284 -0
- package/src/components/list-nav.stories.tsx +22 -0
- package/src/components/list-nav.tsx +145 -0
- package/src/components/logo-cloud.stories.tsx +23 -0
- package/src/components/logo-cloud.tsx +42 -0
- package/src/components/media-gallery.stories.tsx +25 -0
- package/src/components/media-gallery.tsx +347 -0
- package/src/components/message-actions.stories.tsx +45 -0
- package/src/components/message-actions.test.tsx +32 -0
- package/src/components/message-actions.tsx +119 -0
- package/src/components/nav-sidebar.stories.tsx +58 -0
- package/src/components/nav-sidebar.test.tsx +54 -0
- package/src/components/nav-sidebar.tsx +462 -0
- package/src/components/number-stepper.stories.tsx +19 -0
- package/src/components/number-stepper.tsx +158 -0
- package/src/components/page-header.stories.tsx +25 -0
- package/src/components/page-header.tsx +64 -0
- package/src/components/pagination.stories.tsx +110 -0
- package/src/components/pagination.test.tsx +46 -0
- package/src/components/pagination.tsx +144 -0
- package/src/components/popover.stories.tsx +26 -0
- package/src/components/popover.tsx +62 -0
- package/src/components/pricing.stories.tsx +42 -0
- package/src/components/pricing.tsx +130 -0
- package/src/components/progress.stories.tsx +22 -0
- package/src/components/progress.tsx +189 -0
- package/src/components/prompt-input.stories.tsx +62 -0
- package/src/components/prompt-input.test.tsx +106 -0
- package/src/components/prompt-input.tsx +343 -0
- package/src/components/prompt-suggestions.stories.tsx +53 -0
- package/src/components/prompt-suggestions.test.tsx +37 -0
- package/src/components/prompt-suggestions.tsx +122 -0
- package/src/components/quota-bar.stories.tsx +19 -0
- package/src/components/quota-bar.tsx +191 -0
- package/src/components/quote.stories.tsx +18 -0
- package/src/components/quote.tsx +43 -0
- package/src/components/radio-card.stories.tsx +27 -0
- package/src/components/radio-card.tsx +225 -0
- package/src/components/radio-group.stories.tsx +32 -0
- package/src/components/radio-group.tsx +68 -0
- package/src/components/reasoning.stories.tsx +50 -0
- package/src/components/reasoning.test.tsx +48 -0
- package/src/components/reasoning.tsx +143 -0
- package/src/components/search.stories.tsx +18 -0
- package/src/components/search.tsx +133 -0
- package/src/components/section-nav.stories.tsx +59 -0
- package/src/components/section-nav.test.tsx +36 -0
- package/src/components/section-nav.tsx +146 -0
- package/src/components/segmented-control.stories.tsx +22 -0
- package/src/components/segmented-control.tsx +301 -0
- package/src/components/select-button.stories.tsx +27 -0
- package/src/components/select-button.tsx +174 -0
- package/src/components/select.stories.tsx +27 -0
- package/src/components/select.tsx +198 -0
- package/src/components/separator.stories.tsx +22 -0
- package/src/components/separator.tsx +23 -0
- package/src/components/shimmer-text.stories.tsx +23 -0
- package/src/components/shimmer-text.test.tsx +35 -0
- package/src/components/shimmer-text.tsx +43 -0
- package/src/components/sidebar.stories.tsx +25 -0
- package/src/components/sidebar.tsx +234 -0
- package/src/components/skeleton.stories.tsx +22 -0
- package/src/components/skeleton.tsx +96 -0
- package/src/components/slider.stories.tsx +20 -0
- package/src/components/slider.tsx +176 -0
- package/src/components/slideshow.stories.tsx +30 -0
- package/src/components/slideshow.tsx +291 -0
- package/src/components/source.stories.tsx +32 -0
- package/src/components/source.test.tsx +40 -0
- package/src/components/source.tsx +161 -0
- package/src/components/spinner.stories.tsx +19 -0
- package/src/components/spinner.tsx +76 -0
- package/src/components/stat-strip.stories.tsx +36 -0
- package/src/components/stat-strip.test.tsx +25 -0
- package/src/components/stat-strip.tsx +85 -0
- package/src/components/stats.stories.tsx +24 -0
- package/src/components/stats.tsx +83 -0
- package/src/components/step-indicator.stories.tsx +18 -0
- package/src/components/step-indicator.test.tsx +18 -0
- package/src/components/step-indicator.tsx +286 -0
- package/src/components/switch.stories.tsx +26 -0
- package/src/components/switch.tsx +32 -0
- package/src/components/table.stories.tsx +38 -0
- package/src/components/table.tsx +220 -0
- package/src/components/tabs.stories.tsx +25 -0
- package/src/components/tabs.tsx +276 -0
- package/src/components/testimonials.stories.tsx +22 -0
- package/src/components/testimonials.tsx +109 -0
- package/src/components/text-link.stories.tsx +47 -0
- package/src/components/text-link.test.tsx +18 -0
- package/src/components/text-link.tsx +88 -0
- package/src/components/text.stories.tsx +49 -0
- package/src/components/text.tsx +105 -0
- package/src/components/thinking-bar.stories.tsx +19 -0
- package/src/components/thinking-bar.test.tsx +27 -0
- package/src/components/thinking-bar.tsx +64 -0
- package/src/components/thinking-steps.stories.tsx +44 -0
- package/src/components/thinking-steps.test.tsx +42 -0
- package/src/components/thinking-steps.tsx +92 -0
- package/src/components/toaster.stories.tsx +80 -0
- package/src/components/toaster.tsx +36 -0
- package/src/components/toggle.stories.tsx +21 -0
- package/src/components/toggle.tsx +103 -0
- package/src/components/tool-call-card.stories.tsx +97 -0
- package/src/components/tool-call-card.test.tsx +88 -0
- package/src/components/tool-call-card.tsx +231 -0
- package/src/components/tooltip.stories.tsx +25 -0
- package/src/components/tooltip.tsx +43 -0
- package/src/components/top-nav.stories.tsx +20 -0
- package/src/components/top-nav.tsx +76 -0
- package/src/docs/Colors.stories.tsx +192 -0
- package/src/docs/GettingStarted.mdx +72 -0
- package/src/docs/Mcp.mdx +52 -0
- package/src/docs/Typography.stories.tsx +114 -0
- package/src/hooks/use-in-view.ts +32 -0
- package/src/hooks/use-reduced-motion.ts +26 -0
- package/src/index.ts +343 -0
- package/src/lib/cn.test.ts +67 -0
- package/src/lib/cn.ts +81 -0
- package/src/lib/motion.ts +109 -0
- package/src/lib/prefix-utilities.test.ts +56 -0
- package/src/lib/prefix-utilities.ts +50 -0
- package/src/styles/base.css +489 -0
- package/src/styles/motion.css +69 -0
- package/src/styles/overrides.css +44 -0
- package/src/styles/typography.css +173 -0
- package/src/theme/theme.css +391 -0
- package/src/theme/tokens.ts +29 -0
- package/src/theme/types.ts +26 -0
- package/README.md +0 -3
package/knowledge/cta.md
ADDED
|
@@ -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.
|