@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,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: slideshow
|
|
6
|
+
sourceFile: packages/design-system/src/components/slideshow.tsx
|
|
7
|
+
client: true
|
|
8
|
+
category: web-app-media
|
|
9
|
+
categoryFromBarrel: web-app-media
|
|
10
|
+
barrelExported: true
|
|
11
|
+
importPath: "@adres/mgda-ui"
|
|
12
|
+
exports:
|
|
13
|
+
- name: Slideshow
|
|
14
|
+
kind: component
|
|
15
|
+
typeText: "ForwardRefExoticComponent<SlideshowProps & RefAttributes<HTMLDivElement>>"
|
|
16
|
+
- name: SlideshowProps
|
|
17
|
+
kind: type
|
|
18
|
+
- name: SlideshowSlide
|
|
19
|
+
kind: component
|
|
20
|
+
typeText: "ForwardRefExoticComponent<SlideshowSlideProps & RefAttributes<HTMLDivElement>>"
|
|
21
|
+
- name: SlideshowSlideProps
|
|
22
|
+
kind: type
|
|
23
|
+
- name: SlideshowVariant
|
|
24
|
+
kind: type
|
|
25
|
+
primaryExport: Slideshow
|
|
26
|
+
subcomponents:
|
|
27
|
+
- SlideshowSlide
|
|
28
|
+
props:
|
|
29
|
+
Slideshow:
|
|
30
|
+
- name: autoplay
|
|
31
|
+
type: "false | number"
|
|
32
|
+
required: false
|
|
33
|
+
declaredIn: self
|
|
34
|
+
doc: "Auto-advance interval in ms. Pauses on hover / focus / explicit toggle. Pass `false` to disable (default). When enabled, a visible pause button appears in the top-right corner."
|
|
35
|
+
- name: index
|
|
36
|
+
type: number
|
|
37
|
+
required: false
|
|
38
|
+
declaredIn: self
|
|
39
|
+
doc: "Controlled active index."
|
|
40
|
+
- name: loop
|
|
41
|
+
type: boolean
|
|
42
|
+
required: false
|
|
43
|
+
declaredIn: self
|
|
44
|
+
doc: "Wrap around at the edges (default true)."
|
|
45
|
+
- name: onIndexChange
|
|
46
|
+
type: "((index: number) => void)"
|
|
47
|
+
required: false
|
|
48
|
+
declaredIn: self
|
|
49
|
+
doc: "Callback fired when the active slide changes."
|
|
50
|
+
- name: showArrows
|
|
51
|
+
type: boolean
|
|
52
|
+
required: false
|
|
53
|
+
declaredIn: self
|
|
54
|
+
doc: "Show prev/next arrow buttons (default true)."
|
|
55
|
+
- name: showDots
|
|
56
|
+
type: boolean
|
|
57
|
+
required: false
|
|
58
|
+
declaredIn: self
|
|
59
|
+
doc: "Show dot indicators (default true)."
|
|
60
|
+
- name: variant
|
|
61
|
+
type: SlideshowVariant
|
|
62
|
+
required: false
|
|
63
|
+
declaredIn: self
|
|
64
|
+
doc: "Transition style - \"slide\" (default) or \"fade\"."
|
|
65
|
+
extendsProps:
|
|
66
|
+
- "React.HTMLAttributes<HTMLDivElement>"
|
|
67
|
+
variants:
|
|
68
|
+
variant:
|
|
69
|
+
kind: enum
|
|
70
|
+
options:
|
|
71
|
+
- slide
|
|
72
|
+
- fade
|
|
73
|
+
default: slide
|
|
74
|
+
on: Slideshow
|
|
75
|
+
variantSource: prop-union
|
|
76
|
+
compoundVariants: []
|
|
77
|
+
sizeMaps: []
|
|
78
|
+
dataSlots: []
|
|
79
|
+
dependsOn:
|
|
80
|
+
internal: []
|
|
81
|
+
lib:
|
|
82
|
+
- cn
|
|
83
|
+
- motion
|
|
84
|
+
hooks:
|
|
85
|
+
- use-reduced-motion
|
|
86
|
+
external:
|
|
87
|
+
- lucide-react
|
|
88
|
+
- motion/react
|
|
89
|
+
- react
|
|
90
|
+
contexts: []
|
|
91
|
+
stories:
|
|
92
|
+
- exportName: Default
|
|
93
|
+
id: components-slideshow--default
|
|
94
|
+
storybookTitle: Components/Slideshow
|
|
95
|
+
docsId: components-slideshow--documentation
|
|
96
|
+
argTypeOptions: {}
|
|
97
|
+
resolvedCleanly: true
|
|
98
|
+
contractHash: "7c31eae3e85b"
|
|
99
|
+
factsHash: "3fd9118e5714"
|
|
100
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
101
|
+
status: stable
|
|
102
|
+
summary: "A single-frame, one-at-a-time carousel with slide/fade transitions, drag-to-navigate, autoplay, and WCAG-compliant pause controls."
|
|
103
|
+
useWhen:
|
|
104
|
+
- "presenting a sequence of slides one at a time in a single frame - a hero carousel, a testimonial rotator, a promo banner sequence"
|
|
105
|
+
useInstead:
|
|
106
|
+
- id: media-gallery
|
|
107
|
+
when: "the images belong to one item and should be browsable as a grid with a separate fullscreen viewer, not rotate through one frame"
|
|
108
|
+
related:
|
|
109
|
+
- media-gallery
|
|
110
|
+
a11y:
|
|
111
|
+
notes:
|
|
112
|
+
- "Follows the WAI-ARIA carousel pattern: role=\"region\" and aria-roledescription=\"carousel\" on the root, role=\"group\" and aria-roledescription=\"slide\" on the active slide, and a live region announcing slide changes."
|
|
113
|
+
- "Autoplay pauses automatically on hover or keyboard focus (per WAI-ARIA carousel guidance) and always ships a visible pause/play button when enabled (per WCAG 2.2.2, a required control for auto-moving content) - both are already wired in, no extra setup needed."
|
|
114
|
+
keyboard:
|
|
115
|
+
- "ArrowLeft/ArrowRight change slides while the carousel has focus; the whole region is a single tab stop rather than each slide or control being separately tabbable in sequence."
|
|
116
|
+
radixHandles: false
|
|
117
|
+
pitfalls:
|
|
118
|
+
- "Slideshow only ever renders the active slide - it does not mount all children at once, so a slide's own mount/unmount side effects (video autoplay, analytics) fire every time it becomes active, not once up front."
|
|
119
|
+
- "autoplay expects a number of milliseconds or false - there is no boolean true to just turn it on; passing true is a type error, and passing 0 disables it (falsy) rather than firing continuously."
|
|
120
|
+
- "loop=false disables wraparound, so the arrow buttons visually disable themselves at the ends - the dots remain clickable to jump anywhere regardless of loop."
|
|
121
|
+
- "index/onIndexChange make the active slide controllable, but there is no separate defaultIndex for an uncontrolled starting slide other than 0 - to start elsewhere without fully controlling it, pass index once on mount and stop passing it afterward."
|
|
122
|
+
canonicalSnippet: |
|
|
123
|
+
import { Slideshow, SlideshowSlide } from "@adres/mgda-ui"
|
|
124
|
+
|
|
125
|
+
<Slideshow autoplay={5000} variant="fade">
|
|
126
|
+
<SlideshowSlide>Slide one</SlideshowSlide>
|
|
127
|
+
<SlideshowSlide>Slide two</SlideshowSlide>
|
|
128
|
+
<SlideshowSlide>Slide three</SlideshowSlide>
|
|
129
|
+
</Slideshow>
|
|
130
|
+
reviewedAt: 2026-09-01
|
|
131
|
+
reviewedAgainstContractHash: "7c31eae3e85b"
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Usage
|
|
135
|
+
|
|
136
|
+
`Slideshow` rotates through slides one at a time in a single frame - a hero
|
|
137
|
+
carousel, a testimonial rotator, a sequence of promo banners. Reach for
|
|
138
|
+
`MediaGallery` instead when the images belong to one item and should be
|
|
139
|
+
browsable as a grid with a separate fullscreen viewer, rather than rotating
|
|
140
|
+
through one frame.
|
|
141
|
+
|
|
142
|
+
`variant="slide"` (default) translates slides horizontally with drag support;
|
|
143
|
+
`variant="fade"` cross-fades instead, useful when slides do not share the
|
|
144
|
+
same visual weight or aspect ratio. Set `autoplay` to a millisecond interval
|
|
145
|
+
to auto-advance - it pauses automatically on hover or focus and always shows
|
|
146
|
+
a visible pause/play button, per the accessibility guidance the component
|
|
147
|
+
already follows; there is no plain boolean form.
|
|
148
|
+
|
|
149
|
+
`loop` (default true) controls whether the ends wrap around; `showArrows` and
|
|
150
|
+
`showDots` toggle the two navigation affordances independently. Use
|
|
151
|
+
`index`/`onIndexChange` to control the active slide externally, for example
|
|
152
|
+
to sync it with another part of the page.
|
|
153
|
+
|
|
154
|
+
## Anatomy
|
|
155
|
+
|
|
156
|
+
| Part | Role |
|
|
157
|
+
| --- | --- |
|
|
158
|
+
| `Slideshow` | Root and viewport. Owns `variant`, `autoplay`, `loop`, `showArrows`, `showDots`, and the active index. Renders only the active slide. |
|
|
159
|
+
| `SlideshowSlide` | One slide's content wrapper. Its children are whatever the slide should show - an image, a card, arbitrary content. |
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: source
|
|
6
|
+
sourceFile: packages/design-system/src/components/source.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: Source
|
|
14
|
+
kind: component
|
|
15
|
+
typeText: "({ href, children }: SourceProps) => Element"
|
|
16
|
+
- name: SourceContent
|
|
17
|
+
kind: component
|
|
18
|
+
typeText: "({ title, description, favicon, className }: SourceContentProps) => Element"
|
|
19
|
+
- name: SourceContentProps
|
|
20
|
+
kind: type
|
|
21
|
+
- name: sourceDomain
|
|
22
|
+
kind: function
|
|
23
|
+
typeText: "(href: string) => string"
|
|
24
|
+
- name: SourceProps
|
|
25
|
+
kind: type
|
|
26
|
+
- name: SourceTrigger
|
|
27
|
+
kind: component
|
|
28
|
+
typeText: "ForwardRefExoticComponent<SourceTriggerProps & RefAttributes<HTMLAnchorElement>>"
|
|
29
|
+
- name: SourceTriggerProps
|
|
30
|
+
kind: type
|
|
31
|
+
primaryExport: Source
|
|
32
|
+
subcomponents:
|
|
33
|
+
- SourceContent
|
|
34
|
+
- SourceTrigger
|
|
35
|
+
props:
|
|
36
|
+
Source:
|
|
37
|
+
- name: children
|
|
38
|
+
type: ReactNode
|
|
39
|
+
required: true
|
|
40
|
+
declaredIn: self
|
|
41
|
+
- name: href
|
|
42
|
+
type: string
|
|
43
|
+
required: true
|
|
44
|
+
declaredIn: self
|
|
45
|
+
SourceContent:
|
|
46
|
+
- name: className
|
|
47
|
+
type: string
|
|
48
|
+
required: false
|
|
49
|
+
declaredIn: self
|
|
50
|
+
- name: description
|
|
51
|
+
type: string
|
|
52
|
+
required: false
|
|
53
|
+
declaredIn: self
|
|
54
|
+
- name: favicon
|
|
55
|
+
type: string
|
|
56
|
+
required: false
|
|
57
|
+
declaredIn: self
|
|
58
|
+
doc: "Image URL for the site's icon; a link icon otherwise."
|
|
59
|
+
- name: title
|
|
60
|
+
type: string
|
|
61
|
+
required: true
|
|
62
|
+
declaredIn: self
|
|
63
|
+
SourceTrigger:
|
|
64
|
+
- name: favicon
|
|
65
|
+
type: "boolean | string"
|
|
66
|
+
required: false
|
|
67
|
+
declaredIn: self
|
|
68
|
+
doc: "Shows a favicon before the label. Pass an image URL to use it; otherwise a link icon."
|
|
69
|
+
- name: label
|
|
70
|
+
type: ReactNode
|
|
71
|
+
required: false
|
|
72
|
+
declaredIn: self
|
|
73
|
+
doc: "Replaces the domain, e.g. a citation number."
|
|
74
|
+
extendsProps: []
|
|
75
|
+
variants: {}
|
|
76
|
+
variantSource: none
|
|
77
|
+
compoundVariants: []
|
|
78
|
+
sizeMaps: []
|
|
79
|
+
dataSlots:
|
|
80
|
+
- source-trigger
|
|
81
|
+
dependsOn:
|
|
82
|
+
internal:
|
|
83
|
+
- popover
|
|
84
|
+
- text
|
|
85
|
+
lib:
|
|
86
|
+
- cn
|
|
87
|
+
hooks: []
|
|
88
|
+
external:
|
|
89
|
+
- lucide-react
|
|
90
|
+
- react
|
|
91
|
+
contexts:
|
|
92
|
+
- name: SourceContext
|
|
93
|
+
type: SourceContextValue
|
|
94
|
+
default: null
|
|
95
|
+
stories:
|
|
96
|
+
- exportName: InText
|
|
97
|
+
id: components-source--in-text
|
|
98
|
+
storybookTitle: Components/Source
|
|
99
|
+
docsId: components-source--documentation
|
|
100
|
+
argTypeOptions: {}
|
|
101
|
+
resolvedCleanly: true
|
|
102
|
+
contractHash: "68fe1400de6f"
|
|
103
|
+
factsHash: "961f531d3a9e"
|
|
104
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
105
|
+
status: beta
|
|
106
|
+
summary: "A link to where an answer came from: a small pill in running text labelled with the domain, previewing the page on hover and keyboard focus. Works from a URL alone."
|
|
107
|
+
useWhen:
|
|
108
|
+
- "an answer cites web pages and you only have a URL, title and short description"
|
|
109
|
+
- "the citation should be a real link people can open straight from the text"
|
|
110
|
+
useInstead:
|
|
111
|
+
- id: citations
|
|
112
|
+
when: "sources are numbered with a publisher, date and the passage used, and listed under the answer"
|
|
113
|
+
related:
|
|
114
|
+
- citations
|
|
115
|
+
- chat-message
|
|
116
|
+
a11y:
|
|
117
|
+
notes:
|
|
118
|
+
- "The pill is a real link; its name is the domain, or \"Source 2, domain\" with a custom label."
|
|
119
|
+
- "The preview opens on hover and on keyboard focus without moving focus, and closes on blur, pointer leave or Escape."
|
|
120
|
+
- "The preview repeats the pill's link, so it is skipped in the tab order; keyboard users lose nothing."
|
|
121
|
+
- "Favicons are decorative (empty alt); a link icon stands in when there is none or it fails to load."
|
|
122
|
+
radixHandles: true
|
|
123
|
+
pitfalls:
|
|
124
|
+
- "No favicon service is called. Pass favicon with an image URL you trust; true shows a link icon."
|
|
125
|
+
- "Pass a full URL so the domain can be read; anything else is shown as given."
|
|
126
|
+
- "Keep label short: a number or a short name. The pill truncates at a small width."
|
|
127
|
+
canonicalSnippet: |
|
|
128
|
+
import { Source, SourceTrigger, SourceContent } from "@adres/mgda-ui"
|
|
129
|
+
|
|
130
|
+
<Source href="https://www.propertyfinder.ae/en/yas-island">
|
|
131
|
+
<SourceTrigger favicon />
|
|
132
|
+
<SourceContent
|
|
133
|
+
title="Townhouses for sale in Yas Island"
|
|
134
|
+
description="42 townhouses under AED 5M, 11 with a private garden."
|
|
135
|
+
/>
|
|
136
|
+
</Source>
|
|
137
|
+
reviewedAt: 2026-10-06
|
|
138
|
+
reviewedAgainstContractHash: "68fe1400de6f"
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Usage
|
|
142
|
+
|
|
143
|
+
Put a `Source` inline after the claim it backs. `SourceTrigger` is the pill:
|
|
144
|
+
a link to `href`, labelled with its domain (`propertyfinder.ae`) unless you
|
|
145
|
+
pass `label`, such as a citation number. `favicon` adds an icon before the
|
|
146
|
+
label: an image URL you provide, or `true` for a link icon.
|
|
147
|
+
|
|
148
|
+
`SourceContent` is the preview that opens on hover and keyboard focus: the
|
|
149
|
+
domain, a `title` and an optional `description`, all one link to the source.
|
|
150
|
+
`sourceDomain` returns the label text for custom layouts.
|
|
151
|
+
|
|
152
|
+
## Anatomy
|
|
153
|
+
|
|
154
|
+
- `Source` - holds the URL and the hover state.
|
|
155
|
+
- `SourceTrigger` - the inline link pill.
|
|
156
|
+
- `SourceContent` - the hover preview with domain, title and description.
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: spinner
|
|
6
|
+
sourceFile: packages/design-system/src/components/spinner.tsx
|
|
7
|
+
client: true
|
|
8
|
+
category: web-app-feedback
|
|
9
|
+
categoryFromBarrel: web-app-feedback
|
|
10
|
+
barrelExported: true
|
|
11
|
+
importPath: "@adres/mgda-ui"
|
|
12
|
+
exports:
|
|
13
|
+
- name: Spinner
|
|
14
|
+
kind: component
|
|
15
|
+
typeText: "ForwardRefExoticComponent<SpinnerProps & RefAttributes<SVGSVGElement>>"
|
|
16
|
+
- name: SpinnerProps
|
|
17
|
+
kind: type
|
|
18
|
+
- name: SpinnerSize
|
|
19
|
+
kind: type
|
|
20
|
+
primaryExport: Spinner
|
|
21
|
+
subcomponents: []
|
|
22
|
+
props:
|
|
23
|
+
Spinner:
|
|
24
|
+
- name: decorative
|
|
25
|
+
type: boolean
|
|
26
|
+
required: false
|
|
27
|
+
declaredIn: self
|
|
28
|
+
doc: "Hide from assistive tech (`aria-hidden`, drops `role` and `aria-label`). Use when a sibling element already announces the loading state - e.g. inside a button with visible \"Saving...\" text - to avoid duplicate screen-reader announcements."
|
|
29
|
+
- name: label
|
|
30
|
+
type: string
|
|
31
|
+
required: false
|
|
32
|
+
declaredIn: self
|
|
33
|
+
doc: "Accessible label announced by screen readers via the live region. Defaults to `\"Loading\"`. Use this for i18n or to be more specific (\"Saving\", \"Searching\", \"Fetching listings\"). Ignored when `decorative` is true."
|
|
34
|
+
- name: size
|
|
35
|
+
type: "\"lg\" | \"md\" | \"sm\" | \"xl\""
|
|
36
|
+
required: false
|
|
37
|
+
declaredIn: self
|
|
38
|
+
variantKey: true
|
|
39
|
+
extendsProps:
|
|
40
|
+
- "React.SVGAttributes<SVGSVGElement>"
|
|
41
|
+
- "VariantProps<typeof spinnerVariants>"
|
|
42
|
+
variants:
|
|
43
|
+
size:
|
|
44
|
+
kind: enum
|
|
45
|
+
options:
|
|
46
|
+
- sm
|
|
47
|
+
- md
|
|
48
|
+
- lg
|
|
49
|
+
- xl
|
|
50
|
+
default: md
|
|
51
|
+
on: Spinner
|
|
52
|
+
variantSource: cva
|
|
53
|
+
compoundVariants: []
|
|
54
|
+
sizeMaps: []
|
|
55
|
+
dataSlots: []
|
|
56
|
+
dependsOn:
|
|
57
|
+
internal: []
|
|
58
|
+
lib:
|
|
59
|
+
- cn
|
|
60
|
+
hooks: []
|
|
61
|
+
external:
|
|
62
|
+
- class-variance-authority
|
|
63
|
+
- react
|
|
64
|
+
contexts: []
|
|
65
|
+
stories:
|
|
66
|
+
- exportName: Default
|
|
67
|
+
id: components-spinner--default
|
|
68
|
+
- exportName: Large
|
|
69
|
+
id: components-spinner--large
|
|
70
|
+
storybookTitle: Components/Spinner
|
|
71
|
+
docsId: components-spinner--documentation
|
|
72
|
+
argTypeOptions: {}
|
|
73
|
+
resolvedCleanly: true
|
|
74
|
+
contractHash: e95dc7cdfd4a
|
|
75
|
+
factsHash: bb3a461c6eac
|
|
76
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
77
|
+
status: stable
|
|
78
|
+
summary: "An indeterminate loading spinner, with a built-in accessible label and reduced-motion handling."
|
|
79
|
+
useWhen:
|
|
80
|
+
- "indicating something is loading with no known duration or percentage - an inline button state, a data fetch, a page-level loading state"
|
|
81
|
+
useInstead:
|
|
82
|
+
- id: progress
|
|
83
|
+
when: "there is a known value or percentage to show, not just an indeterminate wait"
|
|
84
|
+
- id: skeleton
|
|
85
|
+
when: "the shape of the content is already known while it loads - a placeholder that matches the eventual layout reduces perceived wait better than a spinner"
|
|
86
|
+
related:
|
|
87
|
+
- progress
|
|
88
|
+
- skeleton
|
|
89
|
+
a11y:
|
|
90
|
+
notes:
|
|
91
|
+
- "Sets role=\"status\" and aria-label (default \"Loading\") automatically - this is a live region, so screen readers announce it once on mount; it does not re-announce as time passes."
|
|
92
|
+
- "Set decorative when a sibling element already announces the loading state, e.g. a Button showing visible \"Saving...\" text - otherwise the visible message and the spinner's own announcement can double up for screen reader users."
|
|
93
|
+
- "Reduced motion does not stop the spin - a fully static spinner reads as a plain circle, not loading - it slows the animation to a 3-second cycle instead, keeping the semantic while respecting the preference."
|
|
94
|
+
radixHandles: false
|
|
95
|
+
pitfalls:
|
|
96
|
+
- "label is ignored entirely when decorative is true - setting both has no effect, decorative wins."
|
|
97
|
+
- "There is no built-in text near the spinner - label only reaches assistive tech via aria-label; sighted users see no visible loading text unless it is added alongside the spinner."
|
|
98
|
+
- "size uses a wider four-step scale (sm/md/lg/xl) than most sized primitives' three-step sm/md/lg - a size=\"xl\" ported from another component's scale does not exist there."
|
|
99
|
+
canonicalSnippet: |
|
|
100
|
+
import { Spinner } from "@adres/mgda-ui"
|
|
101
|
+
|
|
102
|
+
<Spinner size="md" label="Loading results" />
|
|
103
|
+
reviewedAt: 2026-09-01
|
|
104
|
+
reviewedAgainstContractHash: e95dc7cdfd4a
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Usage
|
|
108
|
+
|
|
109
|
+
`Spinner` is for an indeterminate wait - no known duration or percentage,
|
|
110
|
+
just an indication that something is happening. Reach for `Progress` instead
|
|
111
|
+
once there is a real value to show, and `Skeleton` when the shape of the
|
|
112
|
+
eventual content is already known, since a shape-matched placeholder reduces
|
|
113
|
+
perceived wait better than a spinning glyph.
|
|
114
|
+
|
|
115
|
+
`label` sets the accessible announcement (default `"Loading"`) - customize it
|
|
116
|
+
to be specific ("Saving", "Searching") or for i18n; it has no visible
|
|
117
|
+
on-screen text of its own, so add that separately if sighted users should see
|
|
118
|
+
the message too. Set `decorative` when a sibling element already announces
|
|
119
|
+
the loading state, such as a `Button` with visible "Saving..." text, to avoid
|
|
120
|
+
a duplicate screen-reader announcement - this also ignores `label`.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: stat-strip
|
|
6
|
+
sourceFile: packages/design-system/src/components/stat-strip.tsx
|
|
7
|
+
client: false
|
|
8
|
+
category: web-app-layout-navigation
|
|
9
|
+
categoryFromBarrel: web-app-layout-navigation
|
|
10
|
+
barrelExported: true
|
|
11
|
+
importPath: "@adres/mgda-ui"
|
|
12
|
+
exports:
|
|
13
|
+
- name: StatStrip
|
|
14
|
+
kind: component
|
|
15
|
+
typeText: "ForwardRefExoticComponent<StatStripProps & RefAttributes<HTMLDivElement>>"
|
|
16
|
+
- name: StatStripItem
|
|
17
|
+
kind: type
|
|
18
|
+
- name: StatStripProps
|
|
19
|
+
kind: type
|
|
20
|
+
- name: StatStripTone
|
|
21
|
+
kind: type
|
|
22
|
+
- name: statStripVariants
|
|
23
|
+
kind: variants
|
|
24
|
+
typeText: "TVReturnType<{ tone: { neutral: { root: string; item: string; }; primary: { root: string; item: string; }; secondary: { root: string; item: string; }; }; }, { root: string; label: string; list: string; item: string; }, u...[truncated]"
|
|
25
|
+
primaryExport: StatStrip
|
|
26
|
+
subcomponents: []
|
|
27
|
+
props:
|
|
28
|
+
StatStrip:
|
|
29
|
+
- name: items
|
|
30
|
+
type: "StatStripItem[]"
|
|
31
|
+
required: true
|
|
32
|
+
declaredIn: self
|
|
33
|
+
- name: label
|
|
34
|
+
type: ReactNode
|
|
35
|
+
required: false
|
|
36
|
+
declaredIn: self
|
|
37
|
+
doc: "Leading caption naming the set, e.g. \"Madhmoun MLS global stats\"."
|
|
38
|
+
- name: tone
|
|
39
|
+
type: "\"neutral\" | \"primary\" | \"secondary\""
|
|
40
|
+
required: false
|
|
41
|
+
declaredIn: self
|
|
42
|
+
variantKey: true
|
|
43
|
+
extendsProps:
|
|
44
|
+
- "Omit<React.HTMLAttributes<HTMLDivElement>, \"children\">"
|
|
45
|
+
- "VariantProps<typeof statStripVariants>"
|
|
46
|
+
variants:
|
|
47
|
+
tone:
|
|
48
|
+
kind: enum
|
|
49
|
+
options:
|
|
50
|
+
- neutral
|
|
51
|
+
- primary
|
|
52
|
+
- secondary
|
|
53
|
+
default: neutral
|
|
54
|
+
on: StatStrip
|
|
55
|
+
variantSource: tv
|
|
56
|
+
compoundVariants: []
|
|
57
|
+
sizeMaps: []
|
|
58
|
+
dataSlots:
|
|
59
|
+
- stat-strip
|
|
60
|
+
dependsOn:
|
|
61
|
+
internal: []
|
|
62
|
+
lib:
|
|
63
|
+
- cn
|
|
64
|
+
hooks: []
|
|
65
|
+
external:
|
|
66
|
+
- react
|
|
67
|
+
- tailwind-variants
|
|
68
|
+
contexts: []
|
|
69
|
+
stories:
|
|
70
|
+
- exportName: Default
|
|
71
|
+
id: components-statstrip--default
|
|
72
|
+
- exportName: Tones
|
|
73
|
+
id: components-statstrip--tones
|
|
74
|
+
- exportName: WithoutLabel
|
|
75
|
+
id: components-statstrip--without-label
|
|
76
|
+
storybookTitle: Components/StatStrip
|
|
77
|
+
docsId: components-statstrip--documentation
|
|
78
|
+
argTypeOptions:
|
|
79
|
+
tone:
|
|
80
|
+
- neutral
|
|
81
|
+
- primary
|
|
82
|
+
- secondary
|
|
83
|
+
resolvedCleanly: true
|
|
84
|
+
contractHash: e912832b643f
|
|
85
|
+
factsHash: a5acbbc99beb
|
|
86
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
87
|
+
status: beta
|
|
88
|
+
summary: "A compact single-line bar of headline figures (icon, label, value) with an optional leading caption, for the top of a dashboard."
|
|
89
|
+
useWhen:
|
|
90
|
+
- "a few platform-wide or account-wide totals sit above a dashboard, such as sold, on-market and deals"
|
|
91
|
+
- "figures need to be glanceable without taking a card row of their own"
|
|
92
|
+
useInstead:
|
|
93
|
+
- id: kpi-card
|
|
94
|
+
when: "each figure needs a trend, an explanation or room to be the focus"
|
|
95
|
+
- id: stats
|
|
96
|
+
when: "the figures are a marketing section with large numbers and descriptions"
|
|
97
|
+
- id: data-list
|
|
98
|
+
when: "the values are facts such as licence numbers, not figures to compare"
|
|
99
|
+
related:
|
|
100
|
+
- kpi-card
|
|
101
|
+
- stats
|
|
102
|
+
a11y:
|
|
103
|
+
notes:
|
|
104
|
+
- "Renders a definition list, so each label is announced with its value; the caption labels the list via aria-labelledby."
|
|
105
|
+
- "Mark item icons aria-hidden; the label already names the figure."
|
|
106
|
+
radixHandles: false
|
|
107
|
+
pitfalls:
|
|
108
|
+
- "Keep it to about four items; more wraps onto several lines from sm up and loses the strip's purpose."
|
|
109
|
+
- "Values are not formatted for you; pass them already formatted (\"1,086\")."
|
|
110
|
+
canonicalSnippet: |
|
|
111
|
+
import { StatStrip } from "@adres/mgda-ui"
|
|
112
|
+
|
|
113
|
+
<StatStrip
|
|
114
|
+
tone="secondary"
|
|
115
|
+
label="Platform stats"
|
|
116
|
+
items={platformStats}
|
|
117
|
+
/>
|
|
118
|
+
reviewedAt: 2026-10-06
|
|
119
|
+
reviewedAgainstContractHash: e912832b643f
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Usage
|
|
123
|
+
|
|
124
|
+
`StatStrip` puts a handful of headline totals in one compact line. Each item
|
|
125
|
+
is an optional icon, a label and a value, rendered as a definition list. The
|
|
126
|
+
`tone` (`neutral`, `primary` or `secondary`) tints the whole strip using the
|
|
127
|
+
mode-aware `weakest` fills, so it reads in light and dark without overrides.
|
|
128
|
+
Below `sm` the items fall into two columns.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: stats
|
|
6
|
+
sourceFile: packages/design-system/src/components/stats.tsx
|
|
7
|
+
client: true
|
|
8
|
+
category: marketing
|
|
9
|
+
categoryFromBarrel: marketing
|
|
10
|
+
barrelExported: true
|
|
11
|
+
importPath: "@adres/mgda-ui"
|
|
12
|
+
exports:
|
|
13
|
+
- name: Stat
|
|
14
|
+
kind: type
|
|
15
|
+
- name: Stats
|
|
16
|
+
kind: component
|
|
17
|
+
typeText: "({ className, eyebrow, title, description, stats, ...props }: StatsProps) => Element"
|
|
18
|
+
- name: StatsProps
|
|
19
|
+
kind: type
|
|
20
|
+
primaryExport: Stats
|
|
21
|
+
subcomponents: []
|
|
22
|
+
props:
|
|
23
|
+
Stats:
|
|
24
|
+
- name: description
|
|
25
|
+
type: ReactNode
|
|
26
|
+
required: false
|
|
27
|
+
declaredIn: self
|
|
28
|
+
- name: eyebrow
|
|
29
|
+
type: ReactNode
|
|
30
|
+
required: false
|
|
31
|
+
declaredIn: self
|
|
32
|
+
- name: stats
|
|
33
|
+
type: "Stat[]"
|
|
34
|
+
required: true
|
|
35
|
+
declaredIn: self
|
|
36
|
+
- name: title
|
|
37
|
+
type: ReactNode
|
|
38
|
+
required: false
|
|
39
|
+
declaredIn: self
|
|
40
|
+
extendsProps:
|
|
41
|
+
- "Omit<React.HTMLAttributes<HTMLElement>, \"title\">"
|
|
42
|
+
variants: {}
|
|
43
|
+
variantSource: none
|
|
44
|
+
compoundVariants: []
|
|
45
|
+
sizeMaps: []
|
|
46
|
+
dataSlots: []
|
|
47
|
+
dependsOn:
|
|
48
|
+
internal: []
|
|
49
|
+
lib:
|
|
50
|
+
- cn
|
|
51
|
+
- motion
|
|
52
|
+
hooks:
|
|
53
|
+
- use-reduced-motion
|
|
54
|
+
external:
|
|
55
|
+
- motion/react
|
|
56
|
+
- react
|
|
57
|
+
contexts: []
|
|
58
|
+
stories:
|
|
59
|
+
- exportName: Default
|
|
60
|
+
id: components-stats--default
|
|
61
|
+
storybookTitle: Components/Stats
|
|
62
|
+
docsId: components-stats--documentation
|
|
63
|
+
argTypeOptions: {}
|
|
64
|
+
resolvedCleanly: true
|
|
65
|
+
contractHash: "78f9fd08f2ae"
|
|
66
|
+
factsHash: fb7c350dd8df
|
|
67
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
68
|
+
status: stable
|
|
69
|
+
summary: "A marketing stat block: an optional eyebrow/title/description header above a responsive grid of large numbers with labels, in a seamless bordered layout."
|
|
70
|
+
useWhen:
|
|
71
|
+
- "showcasing a handful of headline numbers on a marketing or landing page - customers served, uptime, years in business"
|
|
72
|
+
useInstead:
|
|
73
|
+
- id: kpi-card
|
|
74
|
+
when: "the metric belongs to a dashboard, not a marketing page, and needs its own bordered card, loading state, or trend delta"
|
|
75
|
+
- id: bar-graph
|
|
76
|
+
when: "the numbers need to be visually compared against each other, not just displayed side by side"
|
|
77
|
+
related:
|
|
78
|
+
- kpi-card
|
|
79
|
+
- bar-graph
|
|
80
|
+
a11y:
|
|
81
|
+
notes:
|
|
82
|
+
- "Renders a real dl/dt/dd structure - each stat's label and value are semantically paired the same way DataList's are, even though the visual layout is a grid of tiles rather than rows."
|
|
83
|
+
radixHandles: false
|
|
84
|
+
pitfalls:
|
|
85
|
+
- "The grid's column count is derived entirely from stats.length (2/3/4/5+ each get their own breakpoint treatment) - there is no columns override prop, unlike FeatureGrid or Testimonials which do expose one."
|
|
86
|
+
- "value is ReactNode, not a number - the component does not format, animate-count, or add a unit or suffix on its own; pre-format the string (\"10k+\", \"99.9%\") before passing it."
|
|
87
|
+
- "The stagger entrance animation runs on scroll-into-view, the same as FeatureGrid and Testimonials - a Stats block already in the viewport on page load still needs to cross the configured viewport margin to trigger."
|
|
88
|
+
canonicalSnippet: |
|
|
89
|
+
import { Stats } from "@adres/mgda-ui"
|
|
90
|
+
|
|
91
|
+
const sectionTitle = "Trusted at scale"
|
|
92
|
+
const metrics = [
|
|
93
|
+
{ label: "Customers", value: "10k+" },
|
|
94
|
+
{ label: "Uptime", value: "99.9%" },
|
|
95
|
+
{ label: "Countries", value: "40+" },
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
<Stats title={sectionTitle} stats={metrics} />
|
|
99
|
+
reviewedAt: 2026-09-01
|
|
100
|
+
reviewedAgainstContractHash: "78f9fd08f2ae"
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Usage
|
|
104
|
+
|
|
105
|
+
`Stats` showcases a handful of headline numbers on a marketing or landing
|
|
106
|
+
page - customers served, uptime, years in business - in a seamless bordered
|
|
107
|
+
grid of label/value tiles. Reach for `KpiCard` instead when the metric
|
|
108
|
+
belongs to a dashboard rather than a marketing page and needs its own card
|
|
109
|
+
chrome, loading state, or trend delta, and `BarGraph` when the numbers need
|
|
110
|
+
to be visually compared against each other rather than just displayed side
|
|
111
|
+
by side.
|
|
112
|
+
|
|
113
|
+
The grid's column count is derived entirely from how many `stats` are
|
|
114
|
+
passed - there is no `columns` override, unlike `FeatureGrid` or
|
|
115
|
+
`Testimonials`. `value` is `ReactNode`, not a number: pre-format it
|
|
116
|
+
("10k+", "99.9%") before passing it in, since the component does not add
|
|
117
|
+
units, suffixes, or count-up animation on its own.
|