@adres/mgda-ui 0.0.0-stage → 0.0.2
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,158 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: avatar
|
|
6
|
+
sourceFile: packages/design-system/src/components/avatar.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: Avatar
|
|
14
|
+
kind: component
|
|
15
|
+
typeText: "ForwardRefExoticComponent<AvatarProps & RefAttributes<HTMLSpanElement>>"
|
|
16
|
+
- name: AvatarFallback
|
|
17
|
+
kind: component
|
|
18
|
+
typeText: "ForwardRefExoticComponent<Omit<AvatarFallbackProps & RefAttributes<HTMLSpanElement>, \"ref\"> & RefAttributes<HTMLSpanElement>>"
|
|
19
|
+
- name: AvatarFallbackProps
|
|
20
|
+
kind: type
|
|
21
|
+
- name: AvatarImage
|
|
22
|
+
kind: component
|
|
23
|
+
typeText: "ForwardRefExoticComponent<Omit<AvatarImageProps & RefAttributes<HTMLImageElement>, \"ref\"> & RefAttributes<HTMLImageElement>>"
|
|
24
|
+
- name: AvatarImageProps
|
|
25
|
+
kind: type
|
|
26
|
+
- name: AvatarProps
|
|
27
|
+
kind: type
|
|
28
|
+
- name: AvatarSize
|
|
29
|
+
kind: type
|
|
30
|
+
- name: AvatarStack
|
|
31
|
+
kind: component
|
|
32
|
+
typeText: "ForwardRefExoticComponent<AvatarStackProps & RefAttributes<HTMLDivElement>>"
|
|
33
|
+
- name: AvatarStackProps
|
|
34
|
+
kind: type
|
|
35
|
+
primaryExport: Avatar
|
|
36
|
+
subcomponents:
|
|
37
|
+
- AvatarFallback
|
|
38
|
+
- AvatarImage
|
|
39
|
+
- AvatarStack
|
|
40
|
+
props:
|
|
41
|
+
Avatar:
|
|
42
|
+
- name: size
|
|
43
|
+
type: "\"2xl\" | \"lg\" | \"md\" | \"sm\" | \"xl\" | \"xs\""
|
|
44
|
+
required: false
|
|
45
|
+
declaredIn: self
|
|
46
|
+
variantKey: true
|
|
47
|
+
AvatarStack:
|
|
48
|
+
- name: max
|
|
49
|
+
type: number
|
|
50
|
+
required: false
|
|
51
|
+
declaredIn: self
|
|
52
|
+
doc: "Maximum number of children to render before collapsing the remainder into a `+N` fallback chip. When omitted, every child is shown."
|
|
53
|
+
- name: size
|
|
54
|
+
type: AvatarSize
|
|
55
|
+
required: false
|
|
56
|
+
declaredIn: self
|
|
57
|
+
doc: "Size applied to every Avatar child via context. Individual children can still override with their own `size` prop."
|
|
58
|
+
variantKey: true
|
|
59
|
+
extendsProps:
|
|
60
|
+
- "React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>"
|
|
61
|
+
- "VariantProps<typeof avatarVariants>"
|
|
62
|
+
variants:
|
|
63
|
+
size:
|
|
64
|
+
kind: enum
|
|
65
|
+
options:
|
|
66
|
+
- xs
|
|
67
|
+
- sm
|
|
68
|
+
- md
|
|
69
|
+
- lg
|
|
70
|
+
- xl
|
|
71
|
+
- "2xl"
|
|
72
|
+
default: md
|
|
73
|
+
on: Avatar
|
|
74
|
+
variantSource: cva
|
|
75
|
+
compoundVariants: []
|
|
76
|
+
sizeMaps:
|
|
77
|
+
- STACK_OVERLAP
|
|
78
|
+
dataSlots:
|
|
79
|
+
- avatar
|
|
80
|
+
dependsOn:
|
|
81
|
+
internal: []
|
|
82
|
+
lib:
|
|
83
|
+
- cn
|
|
84
|
+
hooks: []
|
|
85
|
+
external:
|
|
86
|
+
- "@radix-ui/react-avatar"
|
|
87
|
+
- class-variance-authority
|
|
88
|
+
- react
|
|
89
|
+
contexts:
|
|
90
|
+
- name: AvatarStackContext
|
|
91
|
+
type: "{ size?: AvatarSize }"
|
|
92
|
+
default: null
|
|
93
|
+
stories:
|
|
94
|
+
- exportName: Default
|
|
95
|
+
id: components-avatar--default
|
|
96
|
+
- exportName: Fallback
|
|
97
|
+
id: components-avatar--fallback
|
|
98
|
+
- exportName: Stack
|
|
99
|
+
id: components-avatar--stack
|
|
100
|
+
storybookTitle: Components/Avatar
|
|
101
|
+
docsId: components-avatar--documentation
|
|
102
|
+
argTypeOptions: {}
|
|
103
|
+
resolvedCleanly: true
|
|
104
|
+
contractHash: e7e5d86e9f90
|
|
105
|
+
factsHash: "6feb1a01b8e3"
|
|
106
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
107
|
+
status: stable
|
|
108
|
+
summary: "A circular user or entity image with an automatic fallback (initials or icon), plus AvatarStack for overlapping groups."
|
|
109
|
+
useWhen:
|
|
110
|
+
- "representing a person, team, or entity with a photo, with a graceful fallback when the image fails or has not loaded"
|
|
111
|
+
- "showing a group of collaborators, attendees, or contacts as an overlapping stack (AvatarStack)"
|
|
112
|
+
useInstead:
|
|
113
|
+
- id: badge
|
|
114
|
+
when: "you need a small status indicator, not an image or initials"
|
|
115
|
+
a11y:
|
|
116
|
+
notes:
|
|
117
|
+
- "AvatarImage renders nothing until the image loads, and AvatarFallback fills the gap during load or on error - always render both, or the avatar goes blank when the image can't load."
|
|
118
|
+
- "AvatarFallback carries no accessible name of its own - give the outer Avatar (or a wrapping element) an aria-label when the fallback content (initials or an icon) is not context enough on its own."
|
|
119
|
+
radixHandles: true
|
|
120
|
+
pitfalls:
|
|
121
|
+
- "AvatarImage shows nothing at all while loading or on error, never a native broken-image glyph - Radix swaps straight to AvatarFallback, so both must be rendered as siblings or the avatar renders empty."
|
|
122
|
+
- "size lives on Avatar (or is inherited from an AvatarStack ancestor via context) - AvatarImage and AvatarFallback have no size prop of their own; they just fill whatever size Avatar renders at."
|
|
123
|
+
- "AvatarStack's max counts the fallback chip itself: visibleCount is max - 1, so max={1} renders zero real avatars plus a single \"+N\" chip - pass max >= 2 for a stack that should still show at least one real avatar."
|
|
124
|
+
canonicalSnippet: |
|
|
125
|
+
import { Avatar, AvatarFallback, AvatarImage } from "@adres/mgda-ui"
|
|
126
|
+
|
|
127
|
+
<Avatar size="md">
|
|
128
|
+
<AvatarImage src="/avatars/jane.jpg" alt="Jane Cooper" />
|
|
129
|
+
<AvatarFallback>JC</AvatarFallback>
|
|
130
|
+
</Avatar>
|
|
131
|
+
reviewedAt: 2026-08-31
|
|
132
|
+
reviewedAgainstContractHash: e7e5d86e9f90
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Usage
|
|
136
|
+
|
|
137
|
+
Always render `AvatarImage` and `AvatarFallback` together: Radix shows the
|
|
138
|
+
fallback automatically while the image loads and if it fails, and shows the
|
|
139
|
+
image once it succeeds - there's no in-between state where nothing renders as
|
|
140
|
+
long as both are present.
|
|
141
|
+
|
|
142
|
+
`size` lives on `Avatar` and cascades to `AvatarImage`/`AvatarFallback`
|
|
143
|
+
automatically since they simply fill the parent's dimensions; set it once on
|
|
144
|
+
the root rather than trying to size the image or fallback directly.
|
|
145
|
+
|
|
146
|
+
Reach for `AvatarStack` for a group of collaborators, attendees, or contacts
|
|
147
|
+
shown as overlapping circles - it sets `size` on every child `Avatar` via
|
|
148
|
+
context (so you don't repeat it) and, when `max` is given and the group
|
|
149
|
+
exceeds it, collapses the remainder into a "+N" `AvatarFallback` chip.
|
|
150
|
+
|
|
151
|
+
## Anatomy
|
|
152
|
+
|
|
153
|
+
| Part | Role |
|
|
154
|
+
| --- | --- |
|
|
155
|
+
| `Avatar` | The root. Owns `size`, or inherits it from an `AvatarStack` ancestor via context. |
|
|
156
|
+
| `AvatarImage` | The photo. Renders only once it has loaded successfully. |
|
|
157
|
+
| `AvatarFallback` | Shown while the image is loading or has errored - typically initials or an icon. |
|
|
158
|
+
| `AvatarStack` | An overlapping horizontal group. Provides `size` to every child `Avatar` via context and can collapse overflow into a "+N" `AvatarFallback` chip. |
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: badge
|
|
6
|
+
sourceFile: packages/design-system/src/components/badge.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: Badge
|
|
14
|
+
kind: component
|
|
15
|
+
typeText: "ForwardRefExoticComponent<BadgeProps & RefAttributes<HTMLSpanElement>>"
|
|
16
|
+
- name: BadgeProps
|
|
17
|
+
kind: type
|
|
18
|
+
- name: badgeVariants
|
|
19
|
+
kind: variants
|
|
20
|
+
typeText: "(props?: (ConfigVariants<{ variant: { default: string; secondary: string; outline: string; muted: string; success: string; warning: string; destructive: string; accent: string; }; size: { sm: string; base: string; lg: st...[truncated]"
|
|
21
|
+
primaryExport: Badge
|
|
22
|
+
subcomponents: []
|
|
23
|
+
props:
|
|
24
|
+
Badge:
|
|
25
|
+
- name: size
|
|
26
|
+
type: "\"base\" | \"lg\" | \"sm\""
|
|
27
|
+
required: false
|
|
28
|
+
declaredIn: self
|
|
29
|
+
variantKey: true
|
|
30
|
+
- name: variant
|
|
31
|
+
type: "\"accent\" | \"default\" | \"destructive\" | \"muted\" | \"outline\" | \"secondary\" | \"success\" | \"warning\""
|
|
32
|
+
required: false
|
|
33
|
+
declaredIn: self
|
|
34
|
+
variantKey: true
|
|
35
|
+
extendsProps:
|
|
36
|
+
- "React.HTMLAttributes<HTMLSpanElement>"
|
|
37
|
+
- "VariantProps<typeof badgeVariants>"
|
|
38
|
+
variants:
|
|
39
|
+
variant:
|
|
40
|
+
kind: enum
|
|
41
|
+
options:
|
|
42
|
+
- default
|
|
43
|
+
- secondary
|
|
44
|
+
- outline
|
|
45
|
+
- muted
|
|
46
|
+
- success
|
|
47
|
+
- warning
|
|
48
|
+
- destructive
|
|
49
|
+
- accent
|
|
50
|
+
default: default
|
|
51
|
+
on: Badge
|
|
52
|
+
size:
|
|
53
|
+
kind: enum
|
|
54
|
+
options:
|
|
55
|
+
- sm
|
|
56
|
+
- base
|
|
57
|
+
- lg
|
|
58
|
+
default: base
|
|
59
|
+
on: Badge
|
|
60
|
+
variantSource: cva
|
|
61
|
+
compoundVariants: []
|
|
62
|
+
sizeMaps: []
|
|
63
|
+
dataSlots:
|
|
64
|
+
- badge
|
|
65
|
+
dependsOn:
|
|
66
|
+
internal: []
|
|
67
|
+
lib:
|
|
68
|
+
- cn
|
|
69
|
+
hooks: []
|
|
70
|
+
external:
|
|
71
|
+
- class-variance-authority
|
|
72
|
+
- react
|
|
73
|
+
contexts: []
|
|
74
|
+
stories:
|
|
75
|
+
- exportName: Default
|
|
76
|
+
id: components-badge--default
|
|
77
|
+
- exportName: Secondary
|
|
78
|
+
id: components-badge--secondary
|
|
79
|
+
- exportName: Success
|
|
80
|
+
id: components-badge--success
|
|
81
|
+
storybookTitle: Components/Badge
|
|
82
|
+
docsId: components-badge--documentation
|
|
83
|
+
argTypeOptions: {}
|
|
84
|
+
resolvedCleanly: true
|
|
85
|
+
contractHash: d42002d6a70f
|
|
86
|
+
factsHash: a8f61aa739f6
|
|
87
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
88
|
+
status: stable
|
|
89
|
+
summary: "A small, non-interactive chip that labels status, category or a count."
|
|
90
|
+
useWhen:
|
|
91
|
+
- "labelling state on a row or card - active, pending, overdue"
|
|
92
|
+
- "showing a small count, where a single digit should read as a circle"
|
|
93
|
+
- "tagging a category or type inline with text"
|
|
94
|
+
useInstead:
|
|
95
|
+
- id: button
|
|
96
|
+
when: "the chip is interactive - it triggers an action or opens a menu"
|
|
97
|
+
- id: alert
|
|
98
|
+
when: "the message is a banner-level notification rather than an inline label"
|
|
99
|
+
- id: countdown-pill
|
|
100
|
+
when: "the label expresses time remaining and should tick down"
|
|
101
|
+
related:
|
|
102
|
+
- alert
|
|
103
|
+
- countdown-pill
|
|
104
|
+
- button
|
|
105
|
+
- text
|
|
106
|
+
tokens:
|
|
107
|
+
- "--radius-badge"
|
|
108
|
+
- "--primary-weaker"
|
|
109
|
+
- "--primary-foreground"
|
|
110
|
+
- "--secondary-weaker"
|
|
111
|
+
- "--secondary-foreground"
|
|
112
|
+
- "--neutral-weakest"
|
|
113
|
+
- "--neutral-foreground"
|
|
114
|
+
- "--success-weakest"
|
|
115
|
+
- "--success-foreground"
|
|
116
|
+
- "--warning-weakest"
|
|
117
|
+
- "--warning-foreground"
|
|
118
|
+
- "--destructive-weakest"
|
|
119
|
+
- "--destructive-foreground"
|
|
120
|
+
- "--accent-weakest"
|
|
121
|
+
- "--accent-foreground"
|
|
122
|
+
- "--border"
|
|
123
|
+
- "--ring"
|
|
124
|
+
a11y:
|
|
125
|
+
notes:
|
|
126
|
+
- "Badge renders a plain span with no implicit ARIA role, so it contributes text content and nothing else."
|
|
127
|
+
- "Colour must not be the only carrier of meaning. A red badge reading \"3\" says nothing to a screen reader about being errors, so put the meaning in the text or in an accessible name on the surrounding control (WCAG 1.4.1)."
|
|
128
|
+
requiredProps:
|
|
129
|
+
- "none, but if the badge is the only indicator of a state, the meaning must appear in text somewhere"
|
|
130
|
+
keyboard:
|
|
131
|
+
- "Not focusable, by design. It takes no part in tab order."
|
|
132
|
+
radixHandles: false
|
|
133
|
+
pitfalls:
|
|
134
|
+
- "Badge is a span, so it is not clickable or focusable. The base classes include a focus-visible ring, which makes it look like it could be interactive, but a span receives no focus without tabIndex. Adding onClick produces a mouse-only control that keyboard users cannot reach: use Button instead."
|
|
135
|
+
- "The default variant is a primary tint, not a neutral grey. For a plain, unemphatic chip reach for muted, otherwise every badge on the page competes with the primary action."
|
|
136
|
+
- "min-w on each size equals that size's box height, so single-character content renders as a circle and longer content stretches into a stadium. That is deliberate for counts, but it means a one-character label will not look the same shape as a two-character one."
|
|
137
|
+
rtl: "Safe. Layout is inline-flex with gap and logical padding utilities, so it mirrors without changes."
|
|
138
|
+
brandNotes: "Chip radius comes from --radius-badge alone. A brand that sets it fully round gets the circular count treatment the min-w sizing is tuned for; a brand that sets it small gets rectangular tags from the same component."
|
|
139
|
+
canonicalSnippet: |
|
|
140
|
+
import { Badge } from "@adres/mgda-ui"
|
|
141
|
+
|
|
142
|
+
<Badge variant="success" size="base">Active</Badge>
|
|
143
|
+
reviewedAt: 2026-08-19
|
|
144
|
+
reviewedAgainstContractHash: d42002d6a70f
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Usage
|
|
148
|
+
|
|
149
|
+
Badge is a label, not a control. It answers "what state is this row in" at a glance,
|
|
150
|
+
and it is deliberately inert: no focus, no click, no role.
|
|
151
|
+
|
|
152
|
+
The eight variants map to semantic roles rather than colours, so `success` stays
|
|
153
|
+
legible in both light and dark without a `dark:` override. Each soft-filled variant
|
|
154
|
+
uses a `weaker` or `weakest` emphasis alias that auto-inverts to a deep tint in dark
|
|
155
|
+
mode, which is why the `-foreground` pair keeps its contrast in both.
|
|
156
|
+
|
|
157
|
+
Reach for `muted` as the neutral default in dense UI. Save `default` for the one
|
|
158
|
+
badge that should draw the eye, and treat `destructive` and `warning` as real signals
|
|
159
|
+
rather than decoration.
|
|
160
|
+
|
|
161
|
+
### Counts
|
|
162
|
+
|
|
163
|
+
The `min-w` on every size matches its own box height, so a single digit renders as a
|
|
164
|
+
circle:
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
<Badge variant="destructive" size="sm">3</Badge>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Two or more characters expand past the circle into a stadium. That is the intended
|
|
171
|
+
behaviour for notification counts, but it does mean badge width is content-dependent,
|
|
172
|
+
so a column of counts will not align unless you constrain it yourself.
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: bar-graph
|
|
6
|
+
sourceFile: packages/design-system/src/components/bar-graph.tsx
|
|
7
|
+
client: true
|
|
8
|
+
category: web-app-patterns
|
|
9
|
+
categoryFromBarrel: web-app-patterns
|
|
10
|
+
barrelExported: true
|
|
11
|
+
importPath: "@adres/mgda-ui"
|
|
12
|
+
exports:
|
|
13
|
+
- name: BarGraph
|
|
14
|
+
kind: component
|
|
15
|
+
typeText: "ForwardRefExoticComponent<BarGraphProps & RefAttributes<HTMLDivElement>>"
|
|
16
|
+
- name: BarGraphDirection
|
|
17
|
+
kind: type
|
|
18
|
+
- name: BarGraphItem
|
|
19
|
+
kind: type
|
|
20
|
+
- name: BarGraphProps
|
|
21
|
+
kind: type
|
|
22
|
+
- name: BarGraphSize
|
|
23
|
+
kind: type
|
|
24
|
+
primaryExport: BarGraph
|
|
25
|
+
subcomponents: []
|
|
26
|
+
props:
|
|
27
|
+
BarGraph:
|
|
28
|
+
- name: bars
|
|
29
|
+
type: "BarGraphItem[]"
|
|
30
|
+
required: true
|
|
31
|
+
declaredIn: self
|
|
32
|
+
doc: "One item per bar, rendered in order."
|
|
33
|
+
- name: direction
|
|
34
|
+
type: BarGraphDirection
|
|
35
|
+
required: false
|
|
36
|
+
declaredIn: self
|
|
37
|
+
doc: "Growth direction. `horizontal` grows left → right (default); `vertical` grows bottom → top."
|
|
38
|
+
- name: labelAlign
|
|
39
|
+
type: "\"left\" | \"right\""
|
|
40
|
+
required: false
|
|
41
|
+
declaredIn: self
|
|
42
|
+
doc: "Horizontal-mode label alignment within its fixed-width column. `right` (default) sets a shared axis flush against the bars; `left` aligns with a left-aligned heading above the chart instead. No effect in `vertical` mode (labels there are centred under each bar)."
|
|
43
|
+
- name: max
|
|
44
|
+
type: number
|
|
45
|
+
required: false
|
|
46
|
+
declaredIn: self
|
|
47
|
+
doc: "Ceiling value - each bar fills to `value / max`. Omit to let the tallest bar reach 100 % (relative comparison). Pass explicitly when bars are fractions of a known whole."
|
|
48
|
+
- name: showCount
|
|
49
|
+
type: boolean
|
|
50
|
+
required: false
|
|
51
|
+
declaredIn: self
|
|
52
|
+
doc: "Render the raw value count beside / above each bar. Defaults to `true`."
|
|
53
|
+
- name: showPct
|
|
54
|
+
type: boolean
|
|
55
|
+
required: false
|
|
56
|
+
declaredIn: self
|
|
57
|
+
doc: "Render the computed percentage beside / above each bar. Defaults to `true`."
|
|
58
|
+
- name: size
|
|
59
|
+
type: BarGraphSize
|
|
60
|
+
required: false
|
|
61
|
+
declaredIn: self
|
|
62
|
+
doc: "Visual density: drives bar thickness, chart height, and type scale."
|
|
63
|
+
extendsProps:
|
|
64
|
+
- "React.HTMLAttributes<HTMLDivElement>"
|
|
65
|
+
variants:
|
|
66
|
+
direction:
|
|
67
|
+
kind: enum
|
|
68
|
+
options:
|
|
69
|
+
- horizontal
|
|
70
|
+
- vertical
|
|
71
|
+
default: horizontal
|
|
72
|
+
on: BarGraph
|
|
73
|
+
size:
|
|
74
|
+
kind: enum
|
|
75
|
+
options:
|
|
76
|
+
- sm
|
|
77
|
+
- md
|
|
78
|
+
- lg
|
|
79
|
+
default: md
|
|
80
|
+
on: BarGraph
|
|
81
|
+
labelAlign:
|
|
82
|
+
kind: enum
|
|
83
|
+
options:
|
|
84
|
+
- left
|
|
85
|
+
- right
|
|
86
|
+
default: right
|
|
87
|
+
on: BarGraph
|
|
88
|
+
variantSource: prop-union
|
|
89
|
+
compoundVariants: []
|
|
90
|
+
sizeMaps:
|
|
91
|
+
- H_TRACK_H
|
|
92
|
+
- LABEL_CLS
|
|
93
|
+
- LABEL_W
|
|
94
|
+
- STAT_CLS
|
|
95
|
+
- V_CHART_H
|
|
96
|
+
dataSlots: []
|
|
97
|
+
dependsOn:
|
|
98
|
+
internal: []
|
|
99
|
+
lib:
|
|
100
|
+
- cn
|
|
101
|
+
hooks: []
|
|
102
|
+
external:
|
|
103
|
+
- react
|
|
104
|
+
contexts: []
|
|
105
|
+
stories:
|
|
106
|
+
- exportName: Default
|
|
107
|
+
id: components-bargraph--default
|
|
108
|
+
- exportName: Vertical
|
|
109
|
+
id: components-bargraph--vertical
|
|
110
|
+
storybookTitle: Components/BarGraph
|
|
111
|
+
docsId: components-bargraph--documentation
|
|
112
|
+
argTypeOptions: {}
|
|
113
|
+
resolvedCleanly: true
|
|
114
|
+
contractHash: "2d7c0dfc611a"
|
|
115
|
+
factsHash: "948a45cd5c9b"
|
|
116
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
117
|
+
status: stable
|
|
118
|
+
summary: "A labeled bar chart, horizontal or vertical, comparing several categories' values against a shared or independent maximum."
|
|
119
|
+
useWhen:
|
|
120
|
+
- "comparing several distinct categories' values side by side - a breakdown by status, a quarter-over-quarter comparison"
|
|
121
|
+
useInstead:
|
|
122
|
+
- id: activity-rings
|
|
123
|
+
when: "the values are 2-4 nested progress metrics toward their own individual goals, not independent categories to compare"
|
|
124
|
+
- id: progress
|
|
125
|
+
when: "there is only one bar - a single determinate value, not a comparison across categories"
|
|
126
|
+
related:
|
|
127
|
+
- activity-rings
|
|
128
|
+
- progress
|
|
129
|
+
a11y:
|
|
130
|
+
notes:
|
|
131
|
+
- "Purely visual - no ARIA roles or labels are added automatically. Pair it with a visible heading, or wrap it with your own accessible description, since a screen reader has no built-in way to read out each bar's label and value from this markup alone."
|
|
132
|
+
radixHandles: false
|
|
133
|
+
pitfalls:
|
|
134
|
+
- "max defaults to the tallest bar's own value, making every chart relative to itself - two BarGraphs meant to be visually comparable, e.g. side by side on a dashboard, need an explicit, shared max, or their scales silently differ."
|
|
135
|
+
- "color is a raw Tailwind background utility string (e.g. \"ax:bg-chart-1\") supplied per bar, not a semantic variant - there is no built-in palette cycling, so passing the same color to two bars makes them visually indistinguishable even though their labels differ."
|
|
136
|
+
- "direction=\"vertical\" and the default horizontal layout use different visual axes (bottom-to-top growth vs. left-to-right) - switching direction on an existing chart changes which size map actually controls the chart's dimensions, so re-check sizing after switching."
|
|
137
|
+
canonicalSnippet: |
|
|
138
|
+
import { BarGraph } from "@adres/mgda-ui"
|
|
139
|
+
|
|
140
|
+
<BarGraph
|
|
141
|
+
bars={[
|
|
142
|
+
{ label: "Compliant", value: 42, color: "ax:bg-success" },
|
|
143
|
+
{ label: "At risk", value: 8, color: "ax:bg-warning" },
|
|
144
|
+
]}
|
|
145
|
+
/>
|
|
146
|
+
reviewedAt: 2026-09-29
|
|
147
|
+
reviewedAgainstContractHash: "2d7c0dfc611a"
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Usage
|
|
151
|
+
|
|
152
|
+
`BarGraph` compares several distinct categories' values side by side - a
|
|
153
|
+
status breakdown, a quarter-over-quarter comparison. Reach for
|
|
154
|
+
`ActivityRings` instead when the values are 2-4 nested progress metrics
|
|
155
|
+
toward their own individual goals rather than independent categories, and
|
|
156
|
+
`Progress` when there is only one value and no comparison to make.
|
|
157
|
+
|
|
158
|
+
`max` defaults to the tallest bar's own value, so a single chart always
|
|
159
|
+
scales to fill its space - pass `max` explicitly when two charts need to
|
|
160
|
+
stay visually comparable against the same scale, or when bars represent
|
|
161
|
+
fractions of a known whole rather than a relative comparison.
|
|
162
|
+
|
|
163
|
+
`direction="horizontal"` (default) grows bars left-to-right with a label
|
|
164
|
+
column on the left; `direction="vertical"` grows bottom-to-top with labels
|
|
165
|
+
underneath. `size` scales bar thickness, chart height, and type together.
|
|
166
|
+
`showPct`/`showCount` independently toggle the two stat readouts next to
|
|
167
|
+
each bar.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: bento-grid
|
|
6
|
+
sourceFile: packages/design-system/src/components/bento-grid.tsx
|
|
7
|
+
client: false
|
|
8
|
+
category: layout
|
|
9
|
+
categoryFromBarrel: layout
|
|
10
|
+
barrelExported: true
|
|
11
|
+
importPath: "@adres/mgda-ui"
|
|
12
|
+
exports:
|
|
13
|
+
- name: BentoGrid
|
|
14
|
+
kind: component
|
|
15
|
+
typeText: "ForwardRefExoticComponent<BentoGridProps & RefAttributes<HTMLDivElement>>"
|
|
16
|
+
- name: BentoGridProps
|
|
17
|
+
kind: type
|
|
18
|
+
- name: BentoItem
|
|
19
|
+
kind: component
|
|
20
|
+
typeText: "ForwardRefExoticComponent<BentoItemProps & RefAttributes<HTMLDivElement>>"
|
|
21
|
+
- name: BentoItemProps
|
|
22
|
+
kind: type
|
|
23
|
+
primaryExport: BentoGrid
|
|
24
|
+
subcomponents:
|
|
25
|
+
- BentoItem
|
|
26
|
+
props:
|
|
27
|
+
BentoGrid:
|
|
28
|
+
- name: cols
|
|
29
|
+
type: "2 | 3 | 4"
|
|
30
|
+
required: false
|
|
31
|
+
declaredIn: self
|
|
32
|
+
doc: "Number of columns at all breakpoints. Default: 3."
|
|
33
|
+
BentoItem:
|
|
34
|
+
- name: colSpan
|
|
35
|
+
type: "1 | 2 | 3 | 4"
|
|
36
|
+
required: false
|
|
37
|
+
declaredIn: self
|
|
38
|
+
doc: "How many grid columns this cell spans. Default: 1."
|
|
39
|
+
- name: rowSpan
|
|
40
|
+
type: "1 | 2 | 3"
|
|
41
|
+
required: false
|
|
42
|
+
declaredIn: self
|
|
43
|
+
doc: "How many grid rows this cell spans. Default: 1."
|
|
44
|
+
extendsProps:
|
|
45
|
+
- "React.HTMLAttributes<HTMLDivElement>"
|
|
46
|
+
variants: {}
|
|
47
|
+
variantSource: none
|
|
48
|
+
compoundVariants: []
|
|
49
|
+
sizeMaps: []
|
|
50
|
+
dataSlots: []
|
|
51
|
+
dependsOn:
|
|
52
|
+
internal: []
|
|
53
|
+
lib:
|
|
54
|
+
- cn
|
|
55
|
+
hooks: []
|
|
56
|
+
external:
|
|
57
|
+
- react
|
|
58
|
+
contexts: []
|
|
59
|
+
stories:
|
|
60
|
+
- exportName: Default
|
|
61
|
+
id: components-bentogrid--default
|
|
62
|
+
storybookTitle: Components/BentoGrid
|
|
63
|
+
docsId: components-bentogrid--documentation
|
|
64
|
+
argTypeOptions: {}
|
|
65
|
+
resolvedCleanly: true
|
|
66
|
+
contractHash: a67a28506ba1
|
|
67
|
+
factsHash: f13f1b759a10
|
|
68
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
69
|
+
status: stable
|
|
70
|
+
summary: "A CSS grid layout for asymmetric dashboard/marketing tiles, where cells span different column and row counts."
|
|
71
|
+
useWhen:
|
|
72
|
+
- "a dashboard or landing section mixes a hero tile with several smaller cards in one asymmetric grid"
|
|
73
|
+
- "you need column/row spans without hand-writing Tailwind grid classes for every breakpoint"
|
|
74
|
+
useInstead:
|
|
75
|
+
- id: card
|
|
76
|
+
when: "you only need a single, uniform card and not a mixed-span grid layout"
|
|
77
|
+
related:
|
|
78
|
+
- card
|
|
79
|
+
a11y:
|
|
80
|
+
notes:
|
|
81
|
+
- "BentoGrid and BentoItem render plain divs with no implicit landmark or list semantics - if the tiles are a list of equivalent items, wrap them in a `<ul>`/`<li>` or add appropriate ARIA roles yourself."
|
|
82
|
+
radixHandles: false
|
|
83
|
+
pitfalls:
|
|
84
|
+
- "cols and colSpan/rowSpan map to fixed literal Tailwind classes (e.g. grid-cols-3, col-span-2) rather than arbitrary values, so a colSpan larger than the grid's cols visually overflows rather than clamping - keep item spans <= the grid's cols."
|
|
85
|
+
canonicalSnippet: |
|
|
86
|
+
import { BentoGrid, BentoItem } from "@adres/mgda-ui"
|
|
87
|
+
|
|
88
|
+
<BentoGrid cols={3} className="ax:max-w-3xl">
|
|
89
|
+
<BentoItem colSpan={2} className="ax:p-lg">Wide feature</BentoItem>
|
|
90
|
+
<BentoItem className="ax:p-lg">Side card</BentoItem>
|
|
91
|
+
<BentoItem className="ax:p-lg">Analytics</BentoItem>
|
|
92
|
+
<BentoItem colSpan={2} className="ax:p-lg">Reports</BentoItem>
|
|
93
|
+
</BentoGrid>
|
|
94
|
+
reviewedAt: 2026-09-01
|
|
95
|
+
reviewedAgainstContractHash: a67a28506ba1
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Usage
|
|
99
|
+
|
|
100
|
+
`BentoGrid` lays out `BentoItem` cells in a CSS grid where individual cells can
|
|
101
|
+
span more than one column or row, producing the mixed hero-tile-plus-cards
|
|
102
|
+
layout common on dashboards and marketing pages ("bento box" grids). Set the
|
|
103
|
+
grid's overall column count once with `cols` (2, 3, or 4), then give any
|
|
104
|
+
`BentoItem` a larger footprint with `colSpan` (1-4) and `rowSpan` (1-3).
|
|
105
|
+
|
|
106
|
+
Keep item spans within the grid's `cols` - a `BentoItem colSpan={4}` inside a
|
|
107
|
+
`cols={3}` grid overflows the row rather than clamping to fit.
|
|
108
|
+
|
|
109
|
+
## Anatomy
|
|
110
|
+
|
|
111
|
+
- `BentoGrid` - the grid container. Sets `grid-cols-*` and a fixed gap; accepts
|
|
112
|
+
all standard `div` attributes via `React.HTMLAttributes<HTMLDivElement>`.
|
|
113
|
+
- `BentoItem` - a single cell. Renders a rounded, bordered card (`bg-card`,
|
|
114
|
+
`border-border`) and applies `col-span-*`/`row-span-*` from its props.
|
|
115
|
+
Content (text, icons, charts) goes directly inside as children.
|