@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
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: activity-rings
|
|
6
|
+
sourceFile: packages/design-system/src/components/activity-rings.tsx
|
|
7
|
+
client: false
|
|
8
|
+
category: web-app-patterns
|
|
9
|
+
categoryFromBarrel: web-app-patterns
|
|
10
|
+
barrelExported: true
|
|
11
|
+
importPath: "@adres/mgda-ui"
|
|
12
|
+
exports:
|
|
13
|
+
- name: ActivityRing
|
|
14
|
+
kind: type
|
|
15
|
+
- name: ActivityRings
|
|
16
|
+
kind: component
|
|
17
|
+
typeText: "({ rings, size, strokeWidth, ariaLabel, }: ActivityRingsProps) => Element"
|
|
18
|
+
- name: ActivityRingsProps
|
|
19
|
+
kind: type
|
|
20
|
+
primaryExport: ActivityRings
|
|
21
|
+
subcomponents: []
|
|
22
|
+
props:
|
|
23
|
+
ActivityRings:
|
|
24
|
+
- name: ariaLabel
|
|
25
|
+
type: string
|
|
26
|
+
required: false
|
|
27
|
+
declaredIn: self
|
|
28
|
+
doc: "Accessible label describing what the rings represent in aggregate."
|
|
29
|
+
- name: rings
|
|
30
|
+
type: "ActivityRing[]"
|
|
31
|
+
required: true
|
|
32
|
+
declaredIn: self
|
|
33
|
+
doc: "Rings rendered from the *outside in*. Pass 1-4 entries; the spacing is computed from the SVG box so a small set still looks balanced."
|
|
34
|
+
- name: size
|
|
35
|
+
type: number
|
|
36
|
+
required: false
|
|
37
|
+
declaredIn: self
|
|
38
|
+
doc: "Visual diameter in CSS pixels. The internal SVG viewBox is always `0 0 120 120`; this prop just scales it."
|
|
39
|
+
- name: strokeWidth
|
|
40
|
+
type: number
|
|
41
|
+
required: false
|
|
42
|
+
declaredIn: self
|
|
43
|
+
doc: "Stroke thickness for each ring in viewBox units. Defaults to 12."
|
|
44
|
+
extendsProps: []
|
|
45
|
+
variants: {}
|
|
46
|
+
variantSource: none
|
|
47
|
+
compoundVariants: []
|
|
48
|
+
sizeMaps: []
|
|
49
|
+
dataSlots: []
|
|
50
|
+
dependsOn:
|
|
51
|
+
internal: []
|
|
52
|
+
lib: []
|
|
53
|
+
hooks: []
|
|
54
|
+
external:
|
|
55
|
+
- react
|
|
56
|
+
contexts: []
|
|
57
|
+
stories:
|
|
58
|
+
- exportName: Default
|
|
59
|
+
id: components-activityrings--default
|
|
60
|
+
- exportName: SingleRing
|
|
61
|
+
id: components-activityrings--single-ring
|
|
62
|
+
storybookTitle: Components/ActivityRings
|
|
63
|
+
docsId: components-activityrings--documentation
|
|
64
|
+
argTypeOptions: {}
|
|
65
|
+
resolvedCleanly: true
|
|
66
|
+
contractHash: a5e2d28bdfd3
|
|
67
|
+
factsHash: "3676e5cf0652"
|
|
68
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
69
|
+
status: stable
|
|
70
|
+
summary: "Concentric Apple-style progress arcs in a single SVG, for showing 2-4 simultaneous progress values at once."
|
|
71
|
+
useWhen:
|
|
72
|
+
- "visualizing 2-4 related progress values together as one glanceable shape - a fitness-style summary, a multi-metric dashboard tile"
|
|
73
|
+
useInstead:
|
|
74
|
+
- id: progress
|
|
75
|
+
when: "there is only one value to show - use Progress shape=\"ring\" instead, the single-arc equivalent"
|
|
76
|
+
- id: bar-graph
|
|
77
|
+
when: "comparing several distinct categories rather than 2-4 nested progress values toward their own individual goals"
|
|
78
|
+
related:
|
|
79
|
+
- progress
|
|
80
|
+
- bar-graph
|
|
81
|
+
a11y:
|
|
82
|
+
notes:
|
|
83
|
+
- "Renders role=\"img\" with a single ariaLabel describing the whole set - individual ring values are not exposed to assistive tech separately, so ariaLabel needs to summarize every ring's meaning and value in one sentence (e.g. \"Move 80%, Exercise 45%, Stand 100%\"), not just name the widget."
|
|
84
|
+
radixHandles: false
|
|
85
|
+
pitfalls:
|
|
86
|
+
- "ActivityRings only knows about pct and className per ring - it computes no percentages and picks no colors itself; callers must already have turned domain data (course completion, fitness minutes) into a 0-1 fraction and a stroke class."
|
|
87
|
+
- "Rings render outside-in from the rings array in order - the first entry is the outermost, largest ring. Reordering the array changes which metric is visually biggest, not just its color."
|
|
88
|
+
- "This is a different component from Progress's shape=\"ring\" mode, where a previous single-arc component lived before being merged into Progress - ActivityRings only exists for the multi-ring case, not for showing just one value."
|
|
89
|
+
canonicalSnippet: |
|
|
90
|
+
import { ActivityRings } from "@adres/mgda-ui"
|
|
91
|
+
|
|
92
|
+
const summary = "Move 80%, Exercise 45%, Stand 100%"
|
|
93
|
+
|
|
94
|
+
<ActivityRings
|
|
95
|
+
ariaLabel={summary}
|
|
96
|
+
rings={[
|
|
97
|
+
{ pct: 0.8, className: "ax:stroke-chart-1" },
|
|
98
|
+
{ pct: 0.45, className: "ax:stroke-chart-2" },
|
|
99
|
+
{ pct: 1, className: "ax:stroke-chart-3" },
|
|
100
|
+
]}
|
|
101
|
+
/>
|
|
102
|
+
reviewedAt: 2026-09-01
|
|
103
|
+
reviewedAgainstContractHash: a5e2d28bdfd3
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Usage
|
|
107
|
+
|
|
108
|
+
`ActivityRings` shows 2-4 related progress values together as one glanceable
|
|
109
|
+
concentric shape - a fitness-style daily summary, a multi-metric dashboard
|
|
110
|
+
tile. Reach for `Progress` with `shape="ring"` instead when there is only one
|
|
111
|
+
value to show; that is the single-arc equivalent this component does not
|
|
112
|
+
duplicate. Reach for `BarGraph` when the values are distinct categories being
|
|
113
|
+
compared, not nested progress toward their own goals.
|
|
114
|
+
|
|
115
|
+
The component is a pure visual primitive - it computes no percentages and
|
|
116
|
+
assigns no colors. Compute each `pct` (a 0-1 fraction) and pick a stroke
|
|
117
|
+
`className` per ring before passing them in. Rings render outside-in in
|
|
118
|
+
array order, so the first entry is the largest, outermost ring - reordering
|
|
119
|
+
changes which metric reads as biggest.
|
|
120
|
+
|
|
121
|
+
`ariaLabel` is the only accessible description of the whole widget; since
|
|
122
|
+
individual ring values are not separately exposed to assistive tech,
|
|
123
|
+
summarize every ring's meaning and value in one sentence.
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: alert
|
|
6
|
+
sourceFile: packages/design-system/src/components/alert.tsx
|
|
7
|
+
client: true
|
|
8
|
+
category: web-app-core-primitives
|
|
9
|
+
categoryFromBarrel: web-app-core-primitives
|
|
10
|
+
barrelExported: true
|
|
11
|
+
importPath: "@adres/mgda-ui"
|
|
12
|
+
exports:
|
|
13
|
+
- name: Alert
|
|
14
|
+
kind: component
|
|
15
|
+
typeText: "ForwardRefExoticComponent<AlertProps & RefAttributes<HTMLDivElement>>"
|
|
16
|
+
- name: AlertDescription
|
|
17
|
+
kind: component
|
|
18
|
+
typeText: "ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>>"
|
|
19
|
+
- name: AlertProps
|
|
20
|
+
kind: type
|
|
21
|
+
- name: AlertSize
|
|
22
|
+
kind: type
|
|
23
|
+
- name: AlertTitle
|
|
24
|
+
kind: component
|
|
25
|
+
typeText: "ForwardRefExoticComponent<HTMLAttributes<HTMLHeadingElement> & RefAttributes<HTMLHeadingElement>>"
|
|
26
|
+
primaryExport: Alert
|
|
27
|
+
subcomponents:
|
|
28
|
+
- AlertDescription
|
|
29
|
+
- AlertTitle
|
|
30
|
+
props:
|
|
31
|
+
Alert:
|
|
32
|
+
- name: hideIcon
|
|
33
|
+
type: boolean
|
|
34
|
+
required: false
|
|
35
|
+
declaredIn: self
|
|
36
|
+
doc: "Hide the leading icon AND snap content to the first column. Use when the alert appears inline next to another leading element that already conveys the meaning."
|
|
37
|
+
- name: icon
|
|
38
|
+
type: ReactNode
|
|
39
|
+
required: false
|
|
40
|
+
declaredIn: self
|
|
41
|
+
doc: "Override the default variant icon with custom content (e.g. <Calendar />, <Sparkles />, <Lock />). The custom icon inherits the variant's color via the alert's `[&>svg]:text-*` selector - pass an SVG element. Remember to set `aria-hidden=\"true\"` on the icon yourself. Ignored when `hideIcon` is true."
|
|
42
|
+
- name: size
|
|
43
|
+
type: AlertSize
|
|
44
|
+
required: false
|
|
45
|
+
declaredIn: self
|
|
46
|
+
variantKey: true
|
|
47
|
+
- name: variant
|
|
48
|
+
type: "\"default\" | \"destructive\" | \"info\" | \"primary\" | \"success\" | \"warning\""
|
|
49
|
+
required: false
|
|
50
|
+
declaredIn: self
|
|
51
|
+
variantKey: true
|
|
52
|
+
extendsProps:
|
|
53
|
+
- "React.HTMLAttributes<HTMLDivElement>"
|
|
54
|
+
- "VariantProps<typeof alertVariants>"
|
|
55
|
+
variants:
|
|
56
|
+
variant:
|
|
57
|
+
kind: enum
|
|
58
|
+
options:
|
|
59
|
+
- default
|
|
60
|
+
- info
|
|
61
|
+
- primary
|
|
62
|
+
- success
|
|
63
|
+
- warning
|
|
64
|
+
- destructive
|
|
65
|
+
default: default
|
|
66
|
+
on: Alert
|
|
67
|
+
size:
|
|
68
|
+
kind: enum
|
|
69
|
+
options:
|
|
70
|
+
- sm
|
|
71
|
+
- md
|
|
72
|
+
default: md
|
|
73
|
+
on: Alert
|
|
74
|
+
variantSource: cva
|
|
75
|
+
compoundVariants: []
|
|
76
|
+
sizeMaps: []
|
|
77
|
+
dataSlots: []
|
|
78
|
+
dependsOn:
|
|
79
|
+
internal: []
|
|
80
|
+
lib:
|
|
81
|
+
- cn
|
|
82
|
+
hooks: []
|
|
83
|
+
external:
|
|
84
|
+
- class-variance-authority
|
|
85
|
+
- lucide-react
|
|
86
|
+
- react
|
|
87
|
+
contexts:
|
|
88
|
+
- name: AlertContext
|
|
89
|
+
type: "{ size: AlertSize }"
|
|
90
|
+
default: null
|
|
91
|
+
stories:
|
|
92
|
+
- exportName: Default
|
|
93
|
+
id: components-alert--default
|
|
94
|
+
- exportName: Success
|
|
95
|
+
id: components-alert--success
|
|
96
|
+
- exportName: Destructive
|
|
97
|
+
id: components-alert--destructive
|
|
98
|
+
storybookTitle: Components/Alert
|
|
99
|
+
docsId: components-alert--documentation
|
|
100
|
+
argTypeOptions: {}
|
|
101
|
+
resolvedCleanly: true
|
|
102
|
+
contractHash: "83fc1b1eacfe"
|
|
103
|
+
factsHash: f153284a377a
|
|
104
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
105
|
+
status: stable
|
|
106
|
+
summary: "A persistent, page or section-level message with a semantic color and leading icon - not for transient background-action feedback."
|
|
107
|
+
useWhen:
|
|
108
|
+
- "surfacing a warning, error, success confirmation, or info message tied to a region of the page that should stay visible until dismissed or resolved"
|
|
109
|
+
- "explaining validation or system state above a form or panel"
|
|
110
|
+
useInstead:
|
|
111
|
+
- id: toaster
|
|
112
|
+
when: "the message is transient feedback for something the user has already moved past - use toast() instead"
|
|
113
|
+
- id: empty-state
|
|
114
|
+
when: "there is no content at all, not a message about content"
|
|
115
|
+
related:
|
|
116
|
+
- toaster
|
|
117
|
+
- badge
|
|
118
|
+
tokens:
|
|
119
|
+
- "--primary-weakest"
|
|
120
|
+
- "--primary-weaker"
|
|
121
|
+
- "--primary-foreground"
|
|
122
|
+
- "--success-weakest"
|
|
123
|
+
- "--success-weaker"
|
|
124
|
+
- "--success-foreground"
|
|
125
|
+
- "--warning-weakest"
|
|
126
|
+
- "--warning-weaker"
|
|
127
|
+
- "--warning-foreground"
|
|
128
|
+
- "--destructive-weakest"
|
|
129
|
+
- "--destructive-weaker"
|
|
130
|
+
- "--destructive-foreground"
|
|
131
|
+
- "--card"
|
|
132
|
+
- "--foreground-strong"
|
|
133
|
+
- "--border"
|
|
134
|
+
a11y:
|
|
135
|
+
notes:
|
|
136
|
+
- "role=\"alert\" is set unconditionally, which triggers an assertive screen-reader announcement the moment the element is inserted into the DOM - mounting an Alert dynamically (after an async action) announces it immediately; one already present at initial page load has no live announcement to trigger."
|
|
137
|
+
- "A custom icon passed via icon needs aria-hidden=\"true\" set by the caller - only the built-in variant icons get it automatically."
|
|
138
|
+
requiredProps:
|
|
139
|
+
- "AlertTitle is optional in the type system but should be included in practice - without it, an assertive announcement reads only the description, losing the headline."
|
|
140
|
+
keyboard:
|
|
141
|
+
- "Not interactive - no keyboard handling."
|
|
142
|
+
radixHandles: false
|
|
143
|
+
pitfalls:
|
|
144
|
+
- "icon is ignored whenever hideIcon is true, so setting both has no visible effect - hideIcon wins."
|
|
145
|
+
- "AlertTitle and AlertDescription read their type scale from AlertContext, keyed to the parent Alert's size - they cannot be resized independently of it."
|
|
146
|
+
- "role=\"alert\" fires an assertive live-region announcement on mount - inserting several Alerts at once (e.g. a list of validation errors) announces all of them, which can overwhelm a screen reader user; consider one wrapping message for bulk validation instead."
|
|
147
|
+
canonicalSnippet: |
|
|
148
|
+
import { Alert, AlertDescription, AlertTitle } from "@adres/mgda-ui"
|
|
149
|
+
|
|
150
|
+
<Alert variant="destructive">
|
|
151
|
+
<AlertTitle>Payment failed</AlertTitle>
|
|
152
|
+
<AlertDescription>Update your card details and try again.</AlertDescription>
|
|
153
|
+
</Alert>
|
|
154
|
+
reviewedAt: 2026-08-31
|
|
155
|
+
reviewedAgainstContractHash: "83fc1b1eacfe"
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Usage
|
|
159
|
+
|
|
160
|
+
`Alert` is for a message tied to a region of the page that should stay visible
|
|
161
|
+
- a validation summary above a form, a warning banner on a panel, a persistent
|
|
162
|
+
success confirmation. It is not for transient feedback about something the
|
|
163
|
+
user has already moved past; reach for `toast()` (`Toaster`) for that instead.
|
|
164
|
+
|
|
165
|
+
`variant` picks both the color and the default leading icon: `default`/`info`
|
|
166
|
+
are neutral, `primary` is an on-brand callout, and `success`/`warning`/
|
|
167
|
+
`destructive` map to their respective severities. Override the icon with
|
|
168
|
+
`icon`, or drop it entirely with `hideIcon` when the alert sits next to
|
|
169
|
+
another element that already signals the same meaning.
|
|
170
|
+
|
|
171
|
+
`size` (`sm`/`md`, default `md`) scales padding, gap, and the icon together
|
|
172
|
+
with the type size of `AlertTitle`/`AlertDescription` - set it once on `Alert`
|
|
173
|
+
rather than styling the sub-parts directly.
|
|
174
|
+
|
|
175
|
+
## Anatomy
|
|
176
|
+
|
|
177
|
+
| Part | Role |
|
|
178
|
+
| --- | --- |
|
|
179
|
+
| `Alert` | The container. Sets `role="alert"`, owns `variant`/`size`/`icon`/`hideIcon`, and renders the leading icon. |
|
|
180
|
+
| `AlertTitle` | The headline. An `h5`, sized from the parent `Alert`'s `size` via context. |
|
|
181
|
+
| `AlertDescription` | Supporting text. Renders a `div`, not a `p`, so it can host block-level children like lists or a button row. |
|
|
182
|
+
|
|
183
|
+
`AlertContext` is why `AlertTitle`/`AlertDescription` never need their own
|
|
184
|
+
`size` prop - they read it from the nearest `Alert` ancestor.
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: answer-actions
|
|
6
|
+
sourceFile: packages/design-system/src/components/answer-actions.tsx
|
|
7
|
+
client: true
|
|
8
|
+
category: web-app-ai
|
|
9
|
+
categoryFromBarrel: web-app-ai
|
|
10
|
+
barrelExported: true
|
|
11
|
+
importPath: "@adres/mgda-ui"
|
|
12
|
+
exports:
|
|
13
|
+
- name: AnswerActions
|
|
14
|
+
kind: component
|
|
15
|
+
typeText: "ForwardRefExoticComponent<AnswerActionsProps & RefAttributes<HTMLDivElement>>"
|
|
16
|
+
- name: AnswerActionsProps
|
|
17
|
+
kind: type
|
|
18
|
+
- name: AnswerFeedback
|
|
19
|
+
kind: type
|
|
20
|
+
- name: AnswerReport
|
|
21
|
+
kind: type
|
|
22
|
+
- name: FeedbackReasonChips
|
|
23
|
+
kind: component
|
|
24
|
+
typeText: "({ reasons, selected, onToggle, label, className, ...props }: FeedbackReasonChipsProps) => Element"
|
|
25
|
+
- name: FeedbackReasonChipsProps
|
|
26
|
+
kind: type
|
|
27
|
+
primaryExport: AnswerActions
|
|
28
|
+
subcomponents:
|
|
29
|
+
- FeedbackReasonChips
|
|
30
|
+
props:
|
|
31
|
+
AnswerActions:
|
|
32
|
+
- name: negativeReasons
|
|
33
|
+
type: "string[]"
|
|
34
|
+
required: true
|
|
35
|
+
declaredIn: self
|
|
36
|
+
doc: "Reasons offered after thumbs down; one or a comment is required to send."
|
|
37
|
+
- name: onCopyLink
|
|
38
|
+
type: "(() => void)"
|
|
39
|
+
required: false
|
|
40
|
+
declaredIn: self
|
|
41
|
+
doc: "Adds \"Copy link\" to the More menu."
|
|
42
|
+
- name: onFeedback
|
|
43
|
+
type: "((feedback: AnswerFeedback) => void)"
|
|
44
|
+
required: false
|
|
45
|
+
declaredIn: self
|
|
46
|
+
doc: "Sent feedback, for logging."
|
|
47
|
+
- name: onRegenerate
|
|
48
|
+
type: "(() => void)"
|
|
49
|
+
required: false
|
|
50
|
+
declaredIn: self
|
|
51
|
+
- name: onReport
|
|
52
|
+
type: "((report: AnswerReport) => void)"
|
|
53
|
+
required: false
|
|
54
|
+
declaredIn: self
|
|
55
|
+
- name: onUndo
|
|
56
|
+
type: "(() => void)"
|
|
57
|
+
required: false
|
|
58
|
+
declaredIn: self
|
|
59
|
+
doc: "The \"Undo\" link after sending was used."
|
|
60
|
+
- name: onVersionChange
|
|
61
|
+
type: "((version: number) => void)"
|
|
62
|
+
required: false
|
|
63
|
+
declaredIn: self
|
|
64
|
+
- name: positiveReasons
|
|
65
|
+
type: "string[]"
|
|
66
|
+
required: true
|
|
67
|
+
declaredIn: self
|
|
68
|
+
doc: "Reasons offered after thumbs up; optional to send."
|
|
69
|
+
- name: regenerateDisabled
|
|
70
|
+
type: boolean
|
|
71
|
+
required: false
|
|
72
|
+
declaredIn: self
|
|
73
|
+
doc: "Keeps Regenerate in place but disabled, e.g. when no more versions can be made."
|
|
74
|
+
- name: regenerating
|
|
75
|
+
type: boolean
|
|
76
|
+
required: false
|
|
77
|
+
declaredIn: self
|
|
78
|
+
- name: reportDescription
|
|
79
|
+
type: string
|
|
80
|
+
required: false
|
|
81
|
+
declaredIn: self
|
|
82
|
+
doc: "Who reads reports and what happens next."
|
|
83
|
+
- name: reportReasons
|
|
84
|
+
type: "{ value: string; label: string; }[]"
|
|
85
|
+
required: false
|
|
86
|
+
declaredIn: self
|
|
87
|
+
doc: "Adds \"Report a problem\" to the More menu, with these reasons."
|
|
88
|
+
- name: text
|
|
89
|
+
type: string
|
|
90
|
+
required: true
|
|
91
|
+
declaredIn: self
|
|
92
|
+
doc: "Text the Copy action copies (the visible version)."
|
|
93
|
+
- name: version
|
|
94
|
+
type: number
|
|
95
|
+
required: false
|
|
96
|
+
declaredIn: self
|
|
97
|
+
doc: "Zero-based index of the visible version."
|
|
98
|
+
- name: versionCount
|
|
99
|
+
type: number
|
|
100
|
+
required: false
|
|
101
|
+
declaredIn: self
|
|
102
|
+
FeedbackReasonChips:
|
|
103
|
+
- name: label
|
|
104
|
+
type: string
|
|
105
|
+
required: true
|
|
106
|
+
declaredIn: self
|
|
107
|
+
doc: "Accessible name of the group."
|
|
108
|
+
- name: onToggle
|
|
109
|
+
type: "(reason: string) => void"
|
|
110
|
+
required: true
|
|
111
|
+
declaredIn: self
|
|
112
|
+
- name: reasons
|
|
113
|
+
type: "string[]"
|
|
114
|
+
required: true
|
|
115
|
+
declaredIn: self
|
|
116
|
+
- name: selected
|
|
117
|
+
type: "string[]"
|
|
118
|
+
required: true
|
|
119
|
+
declaredIn: self
|
|
120
|
+
extendsProps:
|
|
121
|
+
- "Omit<React.HTMLAttributes<HTMLDivElement>, \"onCopy\">"
|
|
122
|
+
variants: {}
|
|
123
|
+
variantSource: none
|
|
124
|
+
compoundVariants: []
|
|
125
|
+
sizeMaps: []
|
|
126
|
+
dataSlots:
|
|
127
|
+
- answer-actions
|
|
128
|
+
dependsOn:
|
|
129
|
+
internal:
|
|
130
|
+
- button
|
|
131
|
+
- dialog
|
|
132
|
+
- dropdown-menu
|
|
133
|
+
- input
|
|
134
|
+
- message-actions
|
|
135
|
+
- radio-group
|
|
136
|
+
- text
|
|
137
|
+
- text-link
|
|
138
|
+
lib:
|
|
139
|
+
- cn
|
|
140
|
+
hooks: []
|
|
141
|
+
external:
|
|
142
|
+
- lucide-react
|
|
143
|
+
- react
|
|
144
|
+
contexts: []
|
|
145
|
+
stories:
|
|
146
|
+
- exportName: Default
|
|
147
|
+
id: components-answeractions--default
|
|
148
|
+
- exportName: WithVersions
|
|
149
|
+
id: components-answeractions--with-versions
|
|
150
|
+
- exportName: WithReport
|
|
151
|
+
id: components-answeractions--with-report
|
|
152
|
+
storybookTitle: Components/AnswerActions
|
|
153
|
+
docsId: components-answeractions--documentation
|
|
154
|
+
argTypeOptions: {}
|
|
155
|
+
resolvedCleanly: true
|
|
156
|
+
contractHash: "5504d1cb162b"
|
|
157
|
+
factsHash: "329e9db1fdd8"
|
|
158
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
159
|
+
status: beta
|
|
160
|
+
summary: "The full action row under an AI answer: copy, rate with a short reasons form, regenerate with a version pager, and report a problem, with undo for sent feedback."
|
|
161
|
+
useWhen:
|
|
162
|
+
- "an assistant answer should collect feedback in one or two taps"
|
|
163
|
+
- "regenerated answers keep earlier versions people can page through"
|
|
164
|
+
- "people need a way to report a harmful or wrong answer"
|
|
165
|
+
useInstead:
|
|
166
|
+
- id: message-actions
|
|
167
|
+
when: "only copy, thumbs and regenerate are needed, with no reasons form, versions or report"
|
|
168
|
+
- id: feedback-bar
|
|
169
|
+
when: "you only need one compact \"Was this helpful?\" prompt for a whole conversation or page"
|
|
170
|
+
related:
|
|
171
|
+
- message-actions
|
|
172
|
+
- chat-message
|
|
173
|
+
- dialog
|
|
174
|
+
a11y:
|
|
175
|
+
notes:
|
|
176
|
+
- "The row is role=\"toolbar\" labelled \"Answer actions\"; ratings are toggles with aria-pressed."
|
|
177
|
+
- "After a rating, focus moves to the first reason chip; reason chips are toggles in a labelled group."
|
|
178
|
+
- "The version count and the thanks line are polite live regions."
|
|
179
|
+
- "Report opens a dialog with a labelled radio group; Send stays disabled until a reason is picked."
|
|
180
|
+
radixHandles: true
|
|
181
|
+
pitfalls:
|
|
182
|
+
- "Thumbs down requires a reason or a comment to send; thumbs up only offers the form (Skip)."
|
|
183
|
+
- "The More menu only appears with onCopyLink or reportReasons; pass reportDescription to say who reads reports."
|
|
184
|
+
- "The bar shows no toasts itself; confirm reports, undo or copied links from onReport, onUndo and onCopyLink."
|
|
185
|
+
- "Rating state is internal and resets on remount; key the bar by answer id."
|
|
186
|
+
canonicalSnippet: |
|
|
187
|
+
import { AnswerActions } from "@adres/mgda-ui"
|
|
188
|
+
|
|
189
|
+
<AnswerActions
|
|
190
|
+
text={answer}
|
|
191
|
+
negativeReasons={["Wrong price", "Out of date"]}
|
|
192
|
+
positiveReasons={["Accurate", "Clear"]}
|
|
193
|
+
onFeedback={logFeedback}
|
|
194
|
+
onRegenerate={regenerate}
|
|
195
|
+
/>
|
|
196
|
+
reviewedAt: 2026-10-06
|
|
197
|
+
reviewedAgainstContractHash: "5504d1cb162b"
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Usage
|
|
201
|
+
|
|
202
|
+
`AnswerActions` builds on `MessageActions`. Copy copies `text`. A thumb opens a
|
|
203
|
+
short form: reason chips from `negativeReasons` or `positiveReasons` and an
|
|
204
|
+
optional comment. Down needs a reason or comment; up can be skipped. Sent
|
|
205
|
+
feedback goes to `onFeedback` and shows a thanks line with Undo (`onUndo`).
|
|
206
|
+
|
|
207
|
+
With `versionCount` above 1 and `onVersionChange`, a pager steps through
|
|
208
|
+
regenerated versions; `regenerating` spins Regenerate and
|
|
209
|
+
`regenerateDisabled` keeps it visible but off. `onCopyLink` and
|
|
210
|
+
`reportReasons` fill the More menu; Report opens a dialog whose
|
|
211
|
+
`reportDescription` says who reads reports, and `onReport` receives the
|
|
212
|
+
reason and details.
|
|
213
|
+
|
|
214
|
+
## Anatomy
|
|
215
|
+
|
|
216
|
+
- `AnswerActions` - toolbar, reasons form, thanks line and report dialog.
|
|
217
|
+
- `FeedbackReasonChips` - multi-select reason toggles, for custom feedback forms.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: aspect-ratio
|
|
6
|
+
sourceFile: packages/design-system/src/components/aspect-ratio.tsx
|
|
7
|
+
client: true
|
|
8
|
+
category: web-app-core-primitives
|
|
9
|
+
categoryFromBarrel: web-app-core-primitives
|
|
10
|
+
barrelExported: true
|
|
11
|
+
importPath: "@adres/mgda-ui"
|
|
12
|
+
exports:
|
|
13
|
+
- name: AspectRatio
|
|
14
|
+
kind: component
|
|
15
|
+
radixSource: "@radix-ui/react-aspect-ratio#Root"
|
|
16
|
+
typeText: "ForwardRefExoticComponent<AspectRatioProps & RefAttributes<HTMLDivElement>>"
|
|
17
|
+
primaryExport: AspectRatio
|
|
18
|
+
subcomponents: []
|
|
19
|
+
props: {}
|
|
20
|
+
extendsProps: []
|
|
21
|
+
variants: {}
|
|
22
|
+
variantSource: none
|
|
23
|
+
compoundVariants: []
|
|
24
|
+
sizeMaps: []
|
|
25
|
+
dataSlots: []
|
|
26
|
+
dependsOn:
|
|
27
|
+
internal: []
|
|
28
|
+
lib: []
|
|
29
|
+
hooks: []
|
|
30
|
+
external:
|
|
31
|
+
- "@radix-ui/react-aspect-ratio"
|
|
32
|
+
contexts: []
|
|
33
|
+
stories:
|
|
34
|
+
- exportName: Default
|
|
35
|
+
id: components-aspectratio--default
|
|
36
|
+
- exportName: Square
|
|
37
|
+
id: components-aspectratio--square
|
|
38
|
+
storybookTitle: Components/AspectRatio
|
|
39
|
+
docsId: components-aspectratio--documentation
|
|
40
|
+
argTypeOptions: {}
|
|
41
|
+
resolvedCleanly: true
|
|
42
|
+
contractHash: a1a3f872053d
|
|
43
|
+
factsHash: d3670c113e24
|
|
44
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
45
|
+
status: stable
|
|
46
|
+
summary: "Constrains a child to a fixed width-to-height ratio, a direct Radix Root re-export."
|
|
47
|
+
useWhen:
|
|
48
|
+
- "an image, video, or map embed needs to keep a fixed aspect ratio (16/9, 1/1, 4/3) as its container resizes"
|
|
49
|
+
a11y:
|
|
50
|
+
notes:
|
|
51
|
+
- "AspectRatio only controls layout - it adds no role or label, so the accessibility of its child (e.g. an img's alt text) is entirely on the caller."
|
|
52
|
+
radixHandles: true
|
|
53
|
+
pitfalls:
|
|
54
|
+
- "AspectRatio is re-exported directly from Radix (export const AspectRatio = AspectRatioPrimitive.Root), so the extractor captured no props or extends clause at all - the validator will not let canonicalSnippet demonstrate the ratio prop even though it is the component's entire purpose. See the ## Usage example below for the real usage, written outside the machine-checked snippet."
|
|
55
|
+
- "The child must fill the container (typically w-full h-full plus object-cover for an image) - AspectRatio only sizes its own wrapper, not the child, which will not visually respect the ratio on its own."
|
|
56
|
+
canonicalSnippet: |
|
|
57
|
+
import { AspectRatio } from "@adres/mgda-ui"
|
|
58
|
+
|
|
59
|
+
<AspectRatio>
|
|
60
|
+
<img src="/cover.jpg" alt="" className="ax:h-full ax:w-full ax:object-cover" />
|
|
61
|
+
</AspectRatio>
|
|
62
|
+
reviewedAt: 2026-08-31
|
|
63
|
+
reviewedAgainstContractHash: a1a3f872053d
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Usage
|
|
67
|
+
|
|
68
|
+
`AspectRatio` wraps a child in a box that maintains a fixed width-to-height
|
|
69
|
+
ratio as its container resizes - most commonly an image or video. Pass
|
|
70
|
+
`ratio` (a number, width divided by height) and size the child to fill the
|
|
71
|
+
wrapper:
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
<AspectRatio ratio={16 / 9}>
|
|
75
|
+
<img src="/cover.jpg" alt="" className="ax:h-full ax:w-full ax:object-cover" />
|
|
76
|
+
</AspectRatio>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`ratio` cannot appear in this file's machine-checked `canonicalSnippet` above
|
|
80
|
+
- see the pitfall on why - but it is the whole reason to reach for this
|
|
81
|
+
component; use the example above, not the bare one in the frontmatter, as the
|
|
82
|
+
real usage reference.
|