@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: media-gallery
|
|
6
|
+
sourceFile: packages/design-system/src/components/media-gallery.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: Lightbox
|
|
14
|
+
kind: component
|
|
15
|
+
typeText: "({ media, index, onIndexChange, onClose, title }: LightboxProps) => Element"
|
|
16
|
+
- name: LightboxProps
|
|
17
|
+
kind: type
|
|
18
|
+
- name: MediaGallery
|
|
19
|
+
kind: component
|
|
20
|
+
typeText: "({ media, title, thumbnailCount, className }: MediaGalleryProps) => Element"
|
|
21
|
+
- name: MediaGalleryProps
|
|
22
|
+
kind: type
|
|
23
|
+
- name: MediaItem
|
|
24
|
+
kind: type
|
|
25
|
+
- name: MediaKind
|
|
26
|
+
kind: type
|
|
27
|
+
primaryExport: MediaGallery
|
|
28
|
+
subcomponents:
|
|
29
|
+
- Lightbox
|
|
30
|
+
props:
|
|
31
|
+
Lightbox:
|
|
32
|
+
- name: index
|
|
33
|
+
type: number
|
|
34
|
+
required: true
|
|
35
|
+
declaredIn: self
|
|
36
|
+
- name: media
|
|
37
|
+
type: "MediaItem[]"
|
|
38
|
+
required: true
|
|
39
|
+
declaredIn: self
|
|
40
|
+
- name: onClose
|
|
41
|
+
type: "() => void"
|
|
42
|
+
required: true
|
|
43
|
+
declaredIn: self
|
|
44
|
+
- name: onIndexChange
|
|
45
|
+
type: "(index: number) => void"
|
|
46
|
+
required: true
|
|
47
|
+
declaredIn: self
|
|
48
|
+
- name: title
|
|
49
|
+
type: string
|
|
50
|
+
required: false
|
|
51
|
+
declaredIn: self
|
|
52
|
+
MediaGallery:
|
|
53
|
+
- name: className
|
|
54
|
+
type: string
|
|
55
|
+
required: false
|
|
56
|
+
declaredIn: self
|
|
57
|
+
- name: media
|
|
58
|
+
type: "MediaItem[]"
|
|
59
|
+
required: true
|
|
60
|
+
declaredIn: self
|
|
61
|
+
doc: "Ordered media. The first item is the hero; the rest fill the thumbnails."
|
|
62
|
+
- name: thumbnailCount
|
|
63
|
+
type: number
|
|
64
|
+
required: false
|
|
65
|
+
declaredIn: self
|
|
66
|
+
doc: "Thumbnails shown beside the hero (defaults to 4)."
|
|
67
|
+
- name: title
|
|
68
|
+
type: string
|
|
69
|
+
required: false
|
|
70
|
+
declaredIn: self
|
|
71
|
+
doc: "Used for alt text and the lightbox's accessible title."
|
|
72
|
+
extendsProps: []
|
|
73
|
+
variants: {}
|
|
74
|
+
variantSource: none
|
|
75
|
+
compoundVariants: []
|
|
76
|
+
sizeMaps: []
|
|
77
|
+
dataSlots: []
|
|
78
|
+
dependsOn:
|
|
79
|
+
internal:
|
|
80
|
+
- button
|
|
81
|
+
lib:
|
|
82
|
+
- cn
|
|
83
|
+
hooks: []
|
|
84
|
+
external:
|
|
85
|
+
- "@radix-ui/react-dialog"
|
|
86
|
+
- lucide-react
|
|
87
|
+
- react
|
|
88
|
+
contexts: []
|
|
89
|
+
stories:
|
|
90
|
+
- exportName: Default
|
|
91
|
+
id: components-mediagallery--default
|
|
92
|
+
storybookTitle: Components/MediaGallery
|
|
93
|
+
docsId: components-mediagallery--documentation
|
|
94
|
+
argTypeOptions: {}
|
|
95
|
+
resolvedCleanly: true
|
|
96
|
+
contractHash: "8f72385ce536"
|
|
97
|
+
factsHash: "9e472898d4c7"
|
|
98
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
99
|
+
status: stable
|
|
100
|
+
summary: "A hero + thumbnail image/video grid that opens a fullscreen, keyboard-navigable lightbox with zoom/pan and inline video playback."
|
|
101
|
+
useWhen:
|
|
102
|
+
- "showing a browsable set of photos, and optionally video or walkthrough clips, for a single listing or item - a property, product, or unit"
|
|
103
|
+
- "the user should be able to open any thumbnail into a fullscreen, zoomable, swipeable viewer"
|
|
104
|
+
useInstead:
|
|
105
|
+
- id: slideshow
|
|
106
|
+
when: "the images should present one at a time in a single frame - a hero carousel, testimonial rotator - not a browsable grid with a separate fullscreen viewer"
|
|
107
|
+
related:
|
|
108
|
+
- slideshow
|
|
109
|
+
a11y:
|
|
110
|
+
notes:
|
|
111
|
+
- "Lightbox is built on Radix Dialog, so it inherits focus trapping, scroll lock, and Escape-to-close automatically, even though its dark immersive surface looks nothing like a typical dialog."
|
|
112
|
+
- "title is used for both the hero/thumbnail alt text and the lightbox's visually-hidden accessible title - pass a real, descriptive title (e.g. the property name), not a generic placeholder, since it is the only accessible name a screen reader gets for the whole gallery."
|
|
113
|
+
keyboard:
|
|
114
|
+
- "ArrowLeft/ArrowRight navigate between items while the lightbox is open; Escape closes it, inherited from Radix Dialog."
|
|
115
|
+
radixHandles: true
|
|
116
|
+
pitfalls:
|
|
117
|
+
- "media[0] is always the hero tile - reordering the array changes which image is large and which are thumbnails; there is no separate hero flag on a MediaItem."
|
|
118
|
+
- "Only one walkthrough item is surfaced specially: MediaGallery finds the first item with type=\"walkthrough\" and adds a dedicated Walkthrough button over the hero - a second walkthrough item still appears as a normal thumbnail, it does not get its own button."
|
|
119
|
+
- "thumbnailCount only controls how many thumbnails render beside the hero (default 4); it does not limit how many items are browsable in the lightbox - all of media is always reachable there via the thumbnail strip and arrow keys."
|
|
120
|
+
- "Lightbox is exported and can be used standalone, but MediaGallery already renders it internally when a thumbnail is clicked - rendering both in the same tree only makes sense when building a custom trigger for the lightbox that bypasses the grid entirely."
|
|
121
|
+
canonicalSnippet: |
|
|
122
|
+
import { MediaGallery } from "@adres/mgda-ui"
|
|
123
|
+
|
|
124
|
+
<MediaGallery
|
|
125
|
+
title="Unit 2304"
|
|
126
|
+
media={[
|
|
127
|
+
{ type: "image", src: "/photos/exterior.jpg" },
|
|
128
|
+
{ type: "image", src: "/photos/living-room.jpg" },
|
|
129
|
+
{ type: "walkthrough", src: "/videos/tour.mp4", poster: "/photos/tour-poster.jpg", label: "Walkthrough" },
|
|
130
|
+
]}
|
|
131
|
+
/>
|
|
132
|
+
reviewedAt: 2026-09-01
|
|
133
|
+
reviewedAgainstContractHash: "8f72385ce536"
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Usage
|
|
137
|
+
|
|
138
|
+
`MediaGallery` is for a browsable set of photos, and optionally video or
|
|
139
|
+
walkthrough clips, belonging to a single listing or item - a property unit, a
|
|
140
|
+
product, a place. Reach for `Slideshow` instead when the images should
|
|
141
|
+
present one at a time in a single frame, like a hero carousel or testimonial
|
|
142
|
+
rotator, rather than a grid the user browses into a fullscreen viewer.
|
|
143
|
+
|
|
144
|
+
`media[0]` is always the large hero tile; the rest fill the thumbnail grid up
|
|
145
|
+
to `thumbnailCount` (default 4), with a "+N Photos" overlay on the last
|
|
146
|
+
visible thumbnail when more remain. Every item in `media` stays reachable in
|
|
147
|
+
the fullscreen `Lightbox` regardless of `thumbnailCount`, via its thumbnail
|
|
148
|
+
strip and arrow-key navigation.
|
|
149
|
+
|
|
150
|
+
Give at most one item `type="walkthrough"` to get the dedicated "Walkthrough"
|
|
151
|
+
button over the hero - `MediaGallery` only looks for the first one.
|
|
152
|
+
|
|
153
|
+
## Anatomy
|
|
154
|
+
|
|
155
|
+
| Part | Role |
|
|
156
|
+
| --- | --- |
|
|
157
|
+
| `MediaGallery` | The hero + thumbnail grid. Opens `Lightbox` internally when a tile is clicked. |
|
|
158
|
+
| `Lightbox` | The fullscreen viewer. Built on Radix Dialog; handles zoom and pan for images, inline playback for video, and keyboard navigation. Exported separately for standalone use, though `MediaGallery` already renders it for you. |
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: message-actions
|
|
6
|
+
sourceFile: packages/design-system/src/components/message-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: MessageAction
|
|
14
|
+
kind: component
|
|
15
|
+
typeText: "ForwardRefExoticComponent<MessageActionProps & RefAttributes<HTMLButtonElement>>"
|
|
16
|
+
- name: MessageActionProps
|
|
17
|
+
kind: type
|
|
18
|
+
- name: MessageActions
|
|
19
|
+
kind: component
|
|
20
|
+
typeText: "ForwardRefExoticComponent<MessageActionsProps & RefAttributes<HTMLDivElement>>"
|
|
21
|
+
- name: MessageActionsProps
|
|
22
|
+
kind: type
|
|
23
|
+
- name: MessageRating
|
|
24
|
+
kind: type
|
|
25
|
+
primaryExport: MessageActions
|
|
26
|
+
subcomponents:
|
|
27
|
+
- MessageAction
|
|
28
|
+
props:
|
|
29
|
+
MessageAction:
|
|
30
|
+
- name: aurora
|
|
31
|
+
type: boolean
|
|
32
|
+
required: false
|
|
33
|
+
declaredIn: button
|
|
34
|
+
doc: "Decorative \"aurora\" - two soft, blurred orbs (primary + accent) drifting behind the label for a modern, glowing look. Designed for the `primary` variant. Ignored with `asChild` (it needs to inject its own children)."
|
|
35
|
+
- name: label
|
|
36
|
+
type: string
|
|
37
|
+
required: true
|
|
38
|
+
declaredIn: self
|
|
39
|
+
doc: "Accessible name and tooltip text."
|
|
40
|
+
- name: pressed
|
|
41
|
+
type: boolean
|
|
42
|
+
required: false
|
|
43
|
+
declaredIn: self
|
|
44
|
+
doc: "Renders as a toggle: sets `aria-pressed` and tints the icon."
|
|
45
|
+
MessageActions:
|
|
46
|
+
- name: copyText
|
|
47
|
+
type: string
|
|
48
|
+
required: false
|
|
49
|
+
declaredIn: self
|
|
50
|
+
doc: "Text the Copy action writes to the clipboard. Omit to hide Copy."
|
|
51
|
+
- name: onCopy
|
|
52
|
+
type: "(() => void)"
|
|
53
|
+
required: false
|
|
54
|
+
declaredIn: self
|
|
55
|
+
- name: onRate
|
|
56
|
+
type: "((rating: MessageRating) => void)"
|
|
57
|
+
required: false
|
|
58
|
+
declaredIn: self
|
|
59
|
+
doc: "Called with the clicked rating; the caller decides whether a second click clears it. Omit to hide rating."
|
|
60
|
+
- name: onRegenerate
|
|
61
|
+
type: "(() => void)"
|
|
62
|
+
required: false
|
|
63
|
+
declaredIn: self
|
|
64
|
+
doc: "Omit to hide Regenerate."
|
|
65
|
+
- name: rating
|
|
66
|
+
type: MessageRating
|
|
67
|
+
required: false
|
|
68
|
+
declaredIn: self
|
|
69
|
+
- name: regenerateDisabled
|
|
70
|
+
type: boolean
|
|
71
|
+
required: false
|
|
72
|
+
declaredIn: self
|
|
73
|
+
- name: regenerating
|
|
74
|
+
type: boolean
|
|
75
|
+
required: false
|
|
76
|
+
declaredIn: self
|
|
77
|
+
doc: "Spins the Regenerate icon and disables it."
|
|
78
|
+
- name: revealOnHover
|
|
79
|
+
type: boolean
|
|
80
|
+
required: false
|
|
81
|
+
declaredIn: self
|
|
82
|
+
doc: "Hides the row until the message is hovered or the row holds focus. Needs a `group/message` ancestor (ChatMessage sets one); touch screens always show it."
|
|
83
|
+
extendsProps:
|
|
84
|
+
- "React.HTMLAttributes<HTMLDivElement>"
|
|
85
|
+
variants:
|
|
86
|
+
rating:
|
|
87
|
+
kind: enum
|
|
88
|
+
options:
|
|
89
|
+
- up
|
|
90
|
+
- down
|
|
91
|
+
default: null
|
|
92
|
+
on: MessageActions
|
|
93
|
+
variantSource: prop-union
|
|
94
|
+
compoundVariants: []
|
|
95
|
+
sizeMaps: []
|
|
96
|
+
dataSlots:
|
|
97
|
+
- message-actions
|
|
98
|
+
dependsOn:
|
|
99
|
+
internal:
|
|
100
|
+
- button
|
|
101
|
+
- tooltip
|
|
102
|
+
lib:
|
|
103
|
+
- cn
|
|
104
|
+
hooks: []
|
|
105
|
+
external:
|
|
106
|
+
- lucide-react
|
|
107
|
+
- react
|
|
108
|
+
contexts: []
|
|
109
|
+
stories:
|
|
110
|
+
- exportName: Default
|
|
111
|
+
id: components-messageactions--default
|
|
112
|
+
- exportName: CopyOnly
|
|
113
|
+
id: components-messageactions--copy-only
|
|
114
|
+
- exportName: Regenerating
|
|
115
|
+
id: components-messageactions--regenerating
|
|
116
|
+
- exportName: WithExtraAction
|
|
117
|
+
id: components-messageactions--with-extra-action
|
|
118
|
+
storybookTitle: Components/MessageActions
|
|
119
|
+
docsId: components-messageactions--documentation
|
|
120
|
+
argTypeOptions: {}
|
|
121
|
+
resolvedCleanly: true
|
|
122
|
+
contractHash: "904203824709"
|
|
123
|
+
factsHash: "43769f63eb08"
|
|
124
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
125
|
+
status: beta
|
|
126
|
+
summary: "The row of icon actions under an assistant message: copy, rate up or down, and regenerate, with room for extra actions."
|
|
127
|
+
useWhen:
|
|
128
|
+
- "an assistant answer needs copy, thumbs up or down, or regenerate"
|
|
129
|
+
- "a chat or AI surface needs a consistent icon action with a tooltip under a message"
|
|
130
|
+
useInstead:
|
|
131
|
+
- id: button-group
|
|
132
|
+
when: "the actions are labelled buttons, not icon-only message actions"
|
|
133
|
+
related:
|
|
134
|
+
- tooltip
|
|
135
|
+
- button
|
|
136
|
+
a11y:
|
|
137
|
+
notes:
|
|
138
|
+
- "Every action is an icon-only button named by its label, which is also the tooltip text."
|
|
139
|
+
- "Ratings are toggles with aria-pressed; pass rating so the pressed state is announced."
|
|
140
|
+
- "Pass role=\"toolbar\" and an aria-label when the row is the main action bar of an answer."
|
|
141
|
+
- "With revealOnHover the row still takes keyboard focus and shows while focused; touch screens always show it."
|
|
142
|
+
radixHandles: true
|
|
143
|
+
pitfalls:
|
|
144
|
+
- "Tooltips need a TooltipProvider above the row; apps usually mount one in the root layout."
|
|
145
|
+
- "onRate gets the clicked value, not the next state. Clear the rating yourself when the same value is clicked twice."
|
|
146
|
+
- "revealOnHover needs a group/message ancestor; ChatMessage provides one. Leave it off on the latest answer so its actions stay visible."
|
|
147
|
+
canonicalSnippet: |
|
|
148
|
+
import { MessageActions } from "@adres/mgda-ui"
|
|
149
|
+
|
|
150
|
+
<MessageActions
|
|
151
|
+
copyText={answer}
|
|
152
|
+
rating={rating}
|
|
153
|
+
onRate={(next) => setRating(rating === next ? null : next)}
|
|
154
|
+
onRegenerate={regenerate}
|
|
155
|
+
/>
|
|
156
|
+
reviewedAt: 2026-10-06
|
|
157
|
+
reviewedAgainstContractHash: "904203824709"
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Usage
|
|
161
|
+
|
|
162
|
+
`MessageActions` sits under an assistant message. Each built-in action shows
|
|
163
|
+
only when its prop is set: `copyText` adds Copy (with a short "Copied"
|
|
164
|
+
confirmation), `onRate` adds thumbs up and down, `onRegenerate` adds
|
|
165
|
+
Regenerate. Rating is controlled: keep it in state and decide what a second
|
|
166
|
+
click on the same thumb does. Extra actions such as a version pager or a More
|
|
167
|
+
menu go in `children` after the built-in ones. Buttons are round ghost icons.
|
|
168
|
+
Set `revealOnHover` to hide the row until the message is hovered or the row
|
|
169
|
+
is focused, as on older turns in a long thread.
|
|
170
|
+
|
|
171
|
+
## Anatomy
|
|
172
|
+
|
|
173
|
+
- `MessageActions` - the row; renders the built-in actions, then `children`.
|
|
174
|
+
- `MessageAction` - one icon-only ghost button with a tooltip. Set `pressed`
|
|
175
|
+
to make it a toggle. Use it for extra actions so they match the row.
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: nav-sidebar
|
|
6
|
+
sourceFile: packages/design-system/src/components/nav-sidebar.tsx
|
|
7
|
+
client: true
|
|
8
|
+
category: web-app-layout-navigation
|
|
9
|
+
categoryFromBarrel: web-app-layout-navigation
|
|
10
|
+
barrelExported: true
|
|
11
|
+
importPath: "@adres/mgda-ui"
|
|
12
|
+
exports:
|
|
13
|
+
- name: NavItem
|
|
14
|
+
kind: type
|
|
15
|
+
- name: NavSection
|
|
16
|
+
kind: type
|
|
17
|
+
- name: NavSidebar
|
|
18
|
+
kind: component
|
|
19
|
+
typeText: "({ sections, currentPath, brand, footer, collapsed: collapsedProp, defaultCollapsed, onCollapsedChange, hideCollapseToggle, expandedItems: expandedProp, defaultExpandedItems, onExpandedItemsChange, LinkComponent, expandS...[truncated]"
|
|
20
|
+
- name: NavSidebarProps
|
|
21
|
+
kind: type
|
|
22
|
+
- name: NavSubItem
|
|
23
|
+
kind: type
|
|
24
|
+
primaryExport: NavSidebar
|
|
25
|
+
subcomponents: []
|
|
26
|
+
props:
|
|
27
|
+
NavSidebar:
|
|
28
|
+
- name: brand
|
|
29
|
+
type: ReactNode
|
|
30
|
+
required: false
|
|
31
|
+
declaredIn: self
|
|
32
|
+
doc: "Optional brand slot rendered in the sidebar header. Typically a logo with an optional sub-label. Hidden in collapsed mode (the collapse toggle takes the slot instead) - the consumer is responsible for rendering a compact mark separately if needed."
|
|
33
|
+
- name: collapsed
|
|
34
|
+
type: boolean
|
|
35
|
+
required: false
|
|
36
|
+
declaredIn: self
|
|
37
|
+
- name: collapseItemLabel
|
|
38
|
+
type: "((label: string) => string)"
|
|
39
|
+
required: false
|
|
40
|
+
declaredIn: self
|
|
41
|
+
- name: collapseSidebarLabel
|
|
42
|
+
type: string
|
|
43
|
+
required: false
|
|
44
|
+
declaredIn: self
|
|
45
|
+
- name: currentPath
|
|
46
|
+
type: string
|
|
47
|
+
required: true
|
|
48
|
+
declaredIn: self
|
|
49
|
+
doc: "The application's current pathname - used to compute active rows and to auto-open the active branch on first render. Pass `usePathname()` from your router."
|
|
50
|
+
- name: defaultCollapsed
|
|
51
|
+
type: boolean
|
|
52
|
+
required: false
|
|
53
|
+
declaredIn: self
|
|
54
|
+
- name: defaultExpandedItems
|
|
55
|
+
type: "Record<string, boolean>"
|
|
56
|
+
required: false
|
|
57
|
+
declaredIn: self
|
|
58
|
+
- name: expandedItems
|
|
59
|
+
type: "Record<string, boolean>"
|
|
60
|
+
required: false
|
|
61
|
+
declaredIn: self
|
|
62
|
+
doc: "Map of item href → explicit open state. Items not present in the map fall back to auto-open-when-active."
|
|
63
|
+
- name: expandItemLabel
|
|
64
|
+
type: "((label: string) => string)"
|
|
65
|
+
required: false
|
|
66
|
+
declaredIn: self
|
|
67
|
+
doc: "Called with `(label)` to format aria-labels for chevron toggle buttons. Defaults to `\"Expand {label}\"` / `\"Collapse {label}\"`."
|
|
68
|
+
- name: expandSidebarLabel
|
|
69
|
+
type: string
|
|
70
|
+
required: false
|
|
71
|
+
declaredIn: self
|
|
72
|
+
- name: footer
|
|
73
|
+
type: ReactNode
|
|
74
|
+
required: false
|
|
75
|
+
declaredIn: self
|
|
76
|
+
doc: "Optional footer slot, typically a `SidebarUserCard`."
|
|
77
|
+
- name: hideCollapseToggle
|
|
78
|
+
type: boolean
|
|
79
|
+
required: false
|
|
80
|
+
declaredIn: self
|
|
81
|
+
doc: "Hide the built-in collapse toggle. Useful when the consumer controls collapse from elsewhere (e.g. a media-query hook on mobile)."
|
|
82
|
+
- name: LinkComponent
|
|
83
|
+
type: "ElementType<any, keyof IntrinsicElements>"
|
|
84
|
+
required: false
|
|
85
|
+
declaredIn: self
|
|
86
|
+
doc: "Component used to render navigable rows. Defaults to a plain anchor; pass your router's link component (e.g. Next.js `<Link>`) to get client-side navigation. Receives standard anchor props."
|
|
87
|
+
- name: onCollapsedChange
|
|
88
|
+
type: "((collapsed: boolean) => void)"
|
|
89
|
+
required: false
|
|
90
|
+
declaredIn: self
|
|
91
|
+
- name: onExpandedItemsChange
|
|
92
|
+
type: "((next: Record<string, boolean>) => void)"
|
|
93
|
+
required: false
|
|
94
|
+
declaredIn: self
|
|
95
|
+
- name: sections
|
|
96
|
+
type: "NavSection[]"
|
|
97
|
+
required: true
|
|
98
|
+
declaredIn: self
|
|
99
|
+
extendsProps: []
|
|
100
|
+
variants: {}
|
|
101
|
+
variantSource: none
|
|
102
|
+
compoundVariants: []
|
|
103
|
+
sizeMaps: []
|
|
104
|
+
dataSlots: []
|
|
105
|
+
dependsOn:
|
|
106
|
+
internal:
|
|
107
|
+
- sidebar
|
|
108
|
+
- tooltip
|
|
109
|
+
lib:
|
|
110
|
+
- cn
|
|
111
|
+
hooks: []
|
|
112
|
+
external:
|
|
113
|
+
- lucide-react
|
|
114
|
+
- react
|
|
115
|
+
contexts: []
|
|
116
|
+
stories:
|
|
117
|
+
- exportName: Default
|
|
118
|
+
id: components-navsidebar--default
|
|
119
|
+
- exportName: WithCounts
|
|
120
|
+
id: components-navsidebar--with-counts
|
|
121
|
+
storybookTitle: Components/NavSidebar
|
|
122
|
+
docsId: components-navsidebar--documentation
|
|
123
|
+
argTypeOptions: {}
|
|
124
|
+
resolvedCleanly: true
|
|
125
|
+
contractHash: "5c27ead74713"
|
|
126
|
+
factsHash: "7380688639b1"
|
|
127
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
128
|
+
status: stable
|
|
129
|
+
summary: "Config-driven app sidebar navigation: active-state routing, nested items, and a collapse toggle, built on Sidebar."
|
|
130
|
+
useWhen:
|
|
131
|
+
- "the app's primary nav is a persistent left column driven by a route/pathname"
|
|
132
|
+
- "sections have nested sub-items that should expand under a parent"
|
|
133
|
+
- "you want a built-in collapse-to-icon-rail toggle instead of building one"
|
|
134
|
+
useInstead:
|
|
135
|
+
- id: sidebar
|
|
136
|
+
when: "the built-in routing/active-state/collapse behavior doesn't fit and you need to compose the raw structural pieces yourself"
|
|
137
|
+
- id: top-nav
|
|
138
|
+
when: "the app's primary navigation is horizontal, not a side column"
|
|
139
|
+
related:
|
|
140
|
+
- sidebar
|
|
141
|
+
- button
|
|
142
|
+
- tooltip
|
|
143
|
+
composesWith:
|
|
144
|
+
- sidebar
|
|
145
|
+
- button
|
|
146
|
+
tokens:
|
|
147
|
+
- "--card"
|
|
148
|
+
- "--border"
|
|
149
|
+
- "--foreground"
|
|
150
|
+
- "--primary-foreground"
|
|
151
|
+
- "--muted-foreground"
|
|
152
|
+
- "--accent"
|
|
153
|
+
- "--ring"
|
|
154
|
+
a11y:
|
|
155
|
+
notes:
|
|
156
|
+
- "Renders a Sidebar underneath, so it inherits the aria-label=\"Primary\" landmark - don't nest a second NavSidebar/Sidebar on the same page."
|
|
157
|
+
- "Each nav row sets aria-current=\"page\" when active, computed from currentPath, not from the browser's own navigation state."
|
|
158
|
+
- "The chevron toggle for items with children is a sibling <button>, not part of the link, so it has its own focus stop, aria-expanded, and an aria-label from expandItemLabel/collapseItemLabel."
|
|
159
|
+
- "In collapsed mode a row shows its label in a Tooltip and names the link with aria-label (label plus count, e.g. \"Drafts, 4 items\"), since the visible text is gone - keep item.label short."
|
|
160
|
+
requiredProps:
|
|
161
|
+
- "sections and currentPath are required; currentPath must come from the consumer's router (e.g. usePathname())"
|
|
162
|
+
keyboard:
|
|
163
|
+
- "Rows are rendered through LinkComponent (a plain <a> by default), so they take part in tab order and activate with Enter."
|
|
164
|
+
- "The children-toggle chevron is a real <button>, reachable and activatable with Enter/Space independently of the row's own link."
|
|
165
|
+
radixHandles: false
|
|
166
|
+
pitfalls:
|
|
167
|
+
- "currentPath must be supplied by the consumer (e.g. usePathname()) - NavSidebar does not read the URL itself, so a stale or hardcoded value freezes active-state and auto-open detection."
|
|
168
|
+
- "exact on a NavItem changes active-match from prefix (pathname.startsWith(href + \"/\")) to exact equality - a parent item covering /courses/* needs exact left unset, not exact: true."
|
|
169
|
+
- "expandedItems/onExpandedItemsChange only overrides items present in the map; items absent from it still fall back to auto-open-when-active, so partially controlling open state is intentional, not a bug."
|
|
170
|
+
- "dot on an item with children is silently not rendered - the chevron owns that trailing space, so a badge count belongs on the item's own row only when it has no children."
|
|
171
|
+
- "count follows the same rule: it renders on items without children, is hidden at 0, and moves into the tooltip (\"Drafts · 4\") when the sidebar is collapsed."
|
|
172
|
+
subcomponentNotes:
|
|
173
|
+
NavItem: "One top-level entry: href, label, icon, optional exact, dot, count, and children (NavSubItem[]) for a nested submenu."
|
|
174
|
+
NavSection: "A group of NavItems with an optional label, rendered as a small caption above the group while expanded and hidden when collapsed. Every section after the first also gets a divider."
|
|
175
|
+
NavSubItem: "A nested row under an item with children: href, label, and an optional trailing count."
|
|
176
|
+
rtl: "Inherits Sidebar's logical properties; the chevron's rotation includes an explicit rtl: variant (-rotate-90 rtl:rotate-90) so it points the correct direction when the layout mirrors."
|
|
177
|
+
canonicalSnippet: |
|
|
178
|
+
import { NavSidebar } from "@adres/mgda-ui"
|
|
179
|
+
import Link from "next/link"
|
|
180
|
+
import { usePathname } from "next/navigation"
|
|
181
|
+
import { Home, Book } from "lucide-react"
|
|
182
|
+
|
|
183
|
+
<NavSidebar
|
|
184
|
+
LinkComponent={Link}
|
|
185
|
+
currentPath={usePathname()}
|
|
186
|
+
brand={<img src="/logo.svg" alt="Acme" className="ax:h-6" />}
|
|
187
|
+
sections={[
|
|
188
|
+
{
|
|
189
|
+
items: [
|
|
190
|
+
{ href: "/dashboard", label: "Dashboard", icon: <Home /> },
|
|
191
|
+
{
|
|
192
|
+
href: "/courses",
|
|
193
|
+
label: "Courses",
|
|
194
|
+
icon: <Book />,
|
|
195
|
+
children: [
|
|
196
|
+
{ href: "/courses", label: "All courses" },
|
|
197
|
+
{ href: "/courses/categories", label: "Categories" },
|
|
198
|
+
],
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
},
|
|
202
|
+
]}
|
|
203
|
+
/>
|
|
204
|
+
reviewedAt: 2026-10-06
|
|
205
|
+
reviewedAgainstContractHash: "5c27ead74713"
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Usage
|
|
209
|
+
|
|
210
|
+
NavSidebar is the opinionated, route-aware layer on top of `Sidebar`: it takes
|
|
211
|
+
a declarative `sections`/`items` config plus the current pathname, and
|
|
212
|
+
computes active state, auto-opens the branch containing the active route, and
|
|
213
|
+
renders a chevron toggle for items with nested children. It also owns the
|
|
214
|
+
collapse-to-icon-rail toggle button that `Sidebar` itself leaves to the
|
|
215
|
+
consumer.
|
|
216
|
+
|
|
217
|
+
Collapse state and per-item open overrides can be either controlled (pass
|
|
218
|
+
`collapsed`/`expandedItems` plus their `onChange` callbacks) or left
|
|
219
|
+
uncontrolled (the component manages its own state, seeded from
|
|
220
|
+
`defaultCollapsed`/`defaultExpandedItems`). Reach for the controlled form only
|
|
221
|
+
when something outside the component needs to react to or drive that state -
|
|
222
|
+
for example, collapsing on a media query.
|
|
223
|
+
|
|
224
|
+
Pass a router's link component via `LinkComponent` (defaults to a plain `<a>`)
|
|
225
|
+
to get client-side navigation instead of full page loads.
|