@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,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: pricing
|
|
6
|
+
sourceFile: packages/design-system/src/components/pricing.tsx
|
|
7
|
+
client: true
|
|
8
|
+
category: marketing
|
|
9
|
+
categoryFromBarrel: marketing
|
|
10
|
+
barrelExported: true
|
|
11
|
+
importPath: "@adres/mgda-ui"
|
|
12
|
+
exports:
|
|
13
|
+
- name: Pricing
|
|
14
|
+
kind: component
|
|
15
|
+
typeText: "({ className, eyebrow, title, description, tiers, ...props }: PricingProps) => Element"
|
|
16
|
+
- name: PricingProps
|
|
17
|
+
kind: type
|
|
18
|
+
- name: PricingTier
|
|
19
|
+
kind: type
|
|
20
|
+
primaryExport: Pricing
|
|
21
|
+
subcomponents: []
|
|
22
|
+
props:
|
|
23
|
+
Pricing:
|
|
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: tiers
|
|
33
|
+
type: "PricingTier[]"
|
|
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
|
+
- lucide-react
|
|
56
|
+
- motion/react
|
|
57
|
+
- react
|
|
58
|
+
contexts: []
|
|
59
|
+
stories:
|
|
60
|
+
- exportName: Default
|
|
61
|
+
id: components-pricing--default
|
|
62
|
+
storybookTitle: Components/Pricing
|
|
63
|
+
docsId: components-pricing--documentation
|
|
64
|
+
argTypeOptions: {}
|
|
65
|
+
resolvedCleanly: true
|
|
66
|
+
contractHash: bd27f89d7eb9
|
|
67
|
+
factsHash: c49d11237576
|
|
68
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
69
|
+
status: stable
|
|
70
|
+
summary: "A pricing tier grid - name, price, optional period/badge/description, a feature checklist, and a CTA per tier, with one tier optionally highlighted as the recommended plan."
|
|
71
|
+
useWhen:
|
|
72
|
+
- "presenting 2 or more pricing plans side by side with a feature comparison checklist and a per-tier CTA"
|
|
73
|
+
useInstead:
|
|
74
|
+
- id: feature-grid
|
|
75
|
+
when: "showcasing product capabilities generally, not comparing purchasable plans"
|
|
76
|
+
related:
|
|
77
|
+
- feature-grid
|
|
78
|
+
a11y:
|
|
79
|
+
notes:
|
|
80
|
+
- "cta is untyped ReactNode per tier - the component adds no button semantics itself, so each tier's cta needs to be a real interactive element, typically a Button, with its own accessible name, not styled text."
|
|
81
|
+
- "highlighted only changes visual styling, a filled primary card versus a bordered neutral one - it carries no semantic recommended announcement to assistive tech; if that distinction matters, say so in the tier's badge or description text, which are read normally."
|
|
82
|
+
radixHandles: false
|
|
83
|
+
pitfalls:
|
|
84
|
+
- "features is a flat string array per tier - there is no way to mark an item as excluded or unavailable; every listed feature renders identically with the same checkmark, so an excluded-features design needs a workaround string or a different component."
|
|
85
|
+
- "The grid layout branches on tiers.length - 2 tiers get a narrower, centered layout while 3 or more span the full section width, so adding or removing a tier can change the overall section width, not just the column count."
|
|
86
|
+
- "highlighted is a plain boolean with no built-in guard against multiple tiers being highlighted at once - passing it true on more than one tier renders more than one filled primary card, which undermines the single-recommended-plan pattern the styling implies."
|
|
87
|
+
- "badge only renders when tier.badge is set, and its color inverts opposite the tier's own highlighted state - a highlighted tier's badge does not just look the same as a non-highlighted one's, its colors are intentionally swapped for contrast."
|
|
88
|
+
canonicalSnippet: |
|
|
89
|
+
import { Button, Pricing } from "@adres/mgda-ui"
|
|
90
|
+
|
|
91
|
+
const heading = "Simple, transparent pricing"
|
|
92
|
+
const tiers = [
|
|
93
|
+
{
|
|
94
|
+
name: "Starter",
|
|
95
|
+
price: "$9",
|
|
96
|
+
period: "mo",
|
|
97
|
+
features: ["1 project", "Community support"],
|
|
98
|
+
cta: <Button variant="outline">Choose Starter</Button>,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: "Pro",
|
|
102
|
+
price: "$29",
|
|
103
|
+
period: "mo",
|
|
104
|
+
features: ["Unlimited projects", "Priority support"],
|
|
105
|
+
cta: <Button>Choose Pro</Button>,
|
|
106
|
+
highlighted: true,
|
|
107
|
+
badge: "Most popular",
|
|
108
|
+
},
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
<Pricing title={heading} tiers={tiers} />
|
|
112
|
+
reviewedAt: 2026-09-01
|
|
113
|
+
reviewedAgainstContractHash: bd27f89d7eb9
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Usage
|
|
117
|
+
|
|
118
|
+
`Pricing` presents pricing tiers side by side - each with a name, price, an
|
|
119
|
+
optional billing period and badge, a feature checklist, and a CTA. Reach for
|
|
120
|
+
`FeatureGrid` instead when showcasing product capabilities generally rather
|
|
121
|
+
than comparing purchasable plans.
|
|
122
|
+
|
|
123
|
+
Set `highlighted: true` on at most one tier to mark it as the recommended
|
|
124
|
+
plan - it swaps to a filled primary card and inverts the badge's coloring
|
|
125
|
+
for contrast. The component does not guard against multiple highlighted
|
|
126
|
+
tiers; that is a call-site discipline, not something enforced.
|
|
127
|
+
|
|
128
|
+
`features` is a flat list of strings, all rendered with the same checkmark -
|
|
129
|
+
there is no way to mark a feature as excluded or unavailable on a given tier
|
|
130
|
+
within this component. The grid layout itself branches on how many `tiers`
|
|
131
|
+
are passed: 2 tiers get a narrower, centered layout, while 3 or more span
|
|
132
|
+
the full section width.
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: progress
|
|
6
|
+
sourceFile: packages/design-system/src/components/progress.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: Progress
|
|
14
|
+
kind: component
|
|
15
|
+
typeText: "ForwardRefExoticComponent<ProgressProps & RefAttributes<HTMLDivElement>>"
|
|
16
|
+
- name: ProgressProps
|
|
17
|
+
kind: type
|
|
18
|
+
- name: ProgressShape
|
|
19
|
+
kind: type
|
|
20
|
+
- name: ProgressSize
|
|
21
|
+
kind: type
|
|
22
|
+
- name: ProgressVariant
|
|
23
|
+
kind: type
|
|
24
|
+
primaryExport: Progress
|
|
25
|
+
subcomponents: []
|
|
26
|
+
props:
|
|
27
|
+
Progress:
|
|
28
|
+
- name: max
|
|
29
|
+
type: number
|
|
30
|
+
required: false
|
|
31
|
+
declaredIn: self
|
|
32
|
+
doc: "Maximum value. Defaults to 100."
|
|
33
|
+
- name: ringSize
|
|
34
|
+
type: number
|
|
35
|
+
required: false
|
|
36
|
+
declaredIn: self
|
|
37
|
+
doc: "Ring-only: override the pixel diameter (takes precedence over `size`)."
|
|
38
|
+
- name: shape
|
|
39
|
+
type: ProgressShape
|
|
40
|
+
required: false
|
|
41
|
+
declaredIn: self
|
|
42
|
+
doc: "Visual shape - horizontal `bar` (default) or circular `ring`."
|
|
43
|
+
- name: size
|
|
44
|
+
type: ProgressSize
|
|
45
|
+
required: false
|
|
46
|
+
declaredIn: self
|
|
47
|
+
doc: "Size - applies to both shapes: bar → height (h-1 / h-2 / h-4) ring → pixel diameter (32 / 48 / 64)"
|
|
48
|
+
variantKey: true
|
|
49
|
+
- name: strokeWidth
|
|
50
|
+
type: number
|
|
51
|
+
required: false
|
|
52
|
+
declaredIn: self
|
|
53
|
+
doc: "Ring-only: override the stroke width in pixels."
|
|
54
|
+
- name: value
|
|
55
|
+
type: number
|
|
56
|
+
required: false
|
|
57
|
+
declaredIn: self
|
|
58
|
+
doc: "Current value, 0-max."
|
|
59
|
+
- name: variant
|
|
60
|
+
type: ProgressVariant
|
|
61
|
+
required: false
|
|
62
|
+
declaredIn: self
|
|
63
|
+
doc: "Colour treatment. The track stays neutral; this drives the indicator."
|
|
64
|
+
extendsProps:
|
|
65
|
+
- "React.HTMLAttributes<HTMLDivElement>"
|
|
66
|
+
variants:
|
|
67
|
+
size:
|
|
68
|
+
kind: enum
|
|
69
|
+
options:
|
|
70
|
+
- sm
|
|
71
|
+
- md
|
|
72
|
+
- lg
|
|
73
|
+
default: md
|
|
74
|
+
on: Progress
|
|
75
|
+
variantSource: cva
|
|
76
|
+
compoundVariants: []
|
|
77
|
+
sizeMaps:
|
|
78
|
+
- RING_DEFAULT_PX
|
|
79
|
+
- RING_DEFAULT_STROKE
|
|
80
|
+
- RING_STROKE_CLASS
|
|
81
|
+
dataSlots: []
|
|
82
|
+
dependsOn:
|
|
83
|
+
internal: []
|
|
84
|
+
lib:
|
|
85
|
+
- cn
|
|
86
|
+
hooks: []
|
|
87
|
+
external:
|
|
88
|
+
- class-variance-authority
|
|
89
|
+
- react
|
|
90
|
+
contexts: []
|
|
91
|
+
stories:
|
|
92
|
+
- exportName: Default
|
|
93
|
+
id: components-progress--default
|
|
94
|
+
- exportName: Ring
|
|
95
|
+
id: components-progress--ring
|
|
96
|
+
storybookTitle: Components/Progress
|
|
97
|
+
docsId: components-progress--documentation
|
|
98
|
+
argTypeOptions: {}
|
|
99
|
+
resolvedCleanly: true
|
|
100
|
+
contractHash: "81975d7fc639"
|
|
101
|
+
factsHash: d13c34778748
|
|
102
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
103
|
+
status: stable
|
|
104
|
+
summary: "A determinate progress indicator with a known value - horizontal bar or circular ring shape, both driven by the same props."
|
|
105
|
+
useWhen:
|
|
106
|
+
- "showing progress toward a known total - an upload, a multi-step wizard, a quota, anything with a real percentage"
|
|
107
|
+
useInstead:
|
|
108
|
+
- id: spinner
|
|
109
|
+
when: "the duration is unknown - there is no value to show, just an indication that something is happening"
|
|
110
|
+
- id: quota-bar
|
|
111
|
+
when: "showing usage against a limit with its own labeling conventions, not a generic progress value"
|
|
112
|
+
- id: step-indicator
|
|
113
|
+
when: "the progress is a fixed sequence of discrete, named steps rather than a continuous percentage"
|
|
114
|
+
related:
|
|
115
|
+
- spinner
|
|
116
|
+
- quota-bar
|
|
117
|
+
- step-indicator
|
|
118
|
+
tokens:
|
|
119
|
+
- "--muted"
|
|
120
|
+
- "--primary"
|
|
121
|
+
- "--success"
|
|
122
|
+
- "--warning"
|
|
123
|
+
- "--destructive"
|
|
124
|
+
a11y:
|
|
125
|
+
notes:
|
|
126
|
+
- "Sets role=\"progressbar\" plus aria-valuemin/max/now automatically from value/max - no extra ARIA is needed for either shape."
|
|
127
|
+
- "Neither shape renders a visible label - pair Progress with your own visible text (e.g. \"64% uploaded\") when the percentage itself matters to sighted users, since aria-valuenow alone only reaches assistive tech."
|
|
128
|
+
radixHandles: false
|
|
129
|
+
pitfalls:
|
|
130
|
+
- "size means different things per shape: for shape=\"bar\" it sets the bar's height (h-1/h-2/h-4); for shape=\"ring\" it sets the ring's pixel diameter (32/48/64) instead. Switching shape without reconsidering size can produce an unexpectedly tiny or huge ring."
|
|
131
|
+
- "ringSize and strokeWidth are ring-only and silently do nothing on shape=\"bar\" - they do not throw or warn if passed to a bar."
|
|
132
|
+
- "value is not clamped to max by the component's props themselves, only by the rendered percentage - aria-valuenow still reports the raw, unclamped value, so passing a value greater than max reports an out-of-range value to assistive tech even though the visual fill stops at 100%."
|
|
133
|
+
canonicalSnippet: |
|
|
134
|
+
import { Progress } from "@adres/mgda-ui"
|
|
135
|
+
|
|
136
|
+
<Progress value={64} variant="default" />
|
|
137
|
+
reviewedAt: 2026-09-01
|
|
138
|
+
reviewedAgainstContractHash: "81975d7fc639"
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Usage
|
|
142
|
+
|
|
143
|
+
`Progress` shows progress toward a known total - reach for it whenever there
|
|
144
|
+
is a real percentage to display (an upload, a wizard step count, a quota).
|
|
145
|
+
Reach for `Spinner` instead when the duration is unknown and there is no
|
|
146
|
+
value to show at all.
|
|
147
|
+
|
|
148
|
+
`shape="bar"` (default) is a horizontal track; `shape="ring"` is a circular
|
|
149
|
+
one - both read `value`/`max`/`variant` the same way, but `size` means
|
|
150
|
+
something different for each: bar height for `bar`, pixel diameter for
|
|
151
|
+
`ring`. Override a ring's exact dimensions with `ringSize`/`strokeWidth`,
|
|
152
|
+
which have no effect on the bar shape.
|
|
153
|
+
|
|
154
|
+
`variant` (`default`/`success`/`warning`/`error`) only recolors the
|
|
155
|
+
indicator - the track stays neutral in both shapes, so the color always
|
|
156
|
+
reads as how the progress is going, not the base fill.
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
---
|
|
2
|
+
# >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
|
|
3
|
+
derived:
|
|
4
|
+
schemaVersion: 1
|
|
5
|
+
id: prompt-input
|
|
6
|
+
sourceFile: packages/design-system/src/components/prompt-input.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: AttachmentChip
|
|
14
|
+
kind: component
|
|
15
|
+
typeText: "ForwardRefExoticComponent<AttachmentChipProps & RefAttributes<HTMLDivElement>>"
|
|
16
|
+
- name: AttachmentChipProps
|
|
17
|
+
kind: type
|
|
18
|
+
- name: characterCountTone
|
|
19
|
+
kind: function
|
|
20
|
+
typeText: "(length: number, max: number) => CharacterCountTone"
|
|
21
|
+
- name: CharacterCountTone
|
|
22
|
+
kind: type
|
|
23
|
+
- name: formatFileSize
|
|
24
|
+
kind: function
|
|
25
|
+
typeText: "(bytes: number) => string"
|
|
26
|
+
- name: isFileDrag
|
|
27
|
+
kind: function
|
|
28
|
+
typeText: "(types: readonly string[]) => boolean"
|
|
29
|
+
- name: PromptInput
|
|
30
|
+
kind: component
|
|
31
|
+
typeText: "ForwardRefExoticComponent<PromptInputProps & RefAttributes<HTMLDivElement>>"
|
|
32
|
+
- name: PromptInputAction
|
|
33
|
+
kind: component
|
|
34
|
+
typeText: "ForwardRefExoticComponent<PromptInputActionProps & RefAttributes<HTMLButtonElement>>"
|
|
35
|
+
- name: PromptInputActionProps
|
|
36
|
+
kind: type
|
|
37
|
+
- name: PromptInputProps
|
|
38
|
+
kind: type
|
|
39
|
+
- name: PromptInputSize
|
|
40
|
+
kind: type
|
|
41
|
+
primaryExport: PromptInput
|
|
42
|
+
subcomponents:
|
|
43
|
+
- AttachmentChip
|
|
44
|
+
- PromptInputAction
|
|
45
|
+
props:
|
|
46
|
+
AttachmentChip:
|
|
47
|
+
- name: error
|
|
48
|
+
type: string
|
|
49
|
+
required: false
|
|
50
|
+
declaredIn: self
|
|
51
|
+
doc: "Replaces size and progress, and tints the chip."
|
|
52
|
+
- name: kind
|
|
53
|
+
type: "\"file\" | \"image\""
|
|
54
|
+
required: false
|
|
55
|
+
declaredIn: self
|
|
56
|
+
- name: name
|
|
57
|
+
type: string
|
|
58
|
+
required: true
|
|
59
|
+
declaredIn: self
|
|
60
|
+
- name: onRemove
|
|
61
|
+
type: "() => void"
|
|
62
|
+
required: true
|
|
63
|
+
declaredIn: self
|
|
64
|
+
- name: previewUrl
|
|
65
|
+
type: string
|
|
66
|
+
required: false
|
|
67
|
+
declaredIn: self
|
|
68
|
+
doc: "Thumbnail for images."
|
|
69
|
+
- name: progress
|
|
70
|
+
type: number
|
|
71
|
+
required: false
|
|
72
|
+
declaredIn: self
|
|
73
|
+
doc: "0-100 while uploading; omit or 100 when done."
|
|
74
|
+
- name: size
|
|
75
|
+
type: number
|
|
76
|
+
required: true
|
|
77
|
+
declaredIn: self
|
|
78
|
+
doc: "Bytes; shown once the upload finishes."
|
|
79
|
+
PromptInput:
|
|
80
|
+
- name: attachments
|
|
81
|
+
type: ReactNode
|
|
82
|
+
required: false
|
|
83
|
+
declaredIn: self
|
|
84
|
+
doc: "Above the field: usually a list of `AttachmentChip`s."
|
|
85
|
+
- name: busy
|
|
86
|
+
type: boolean
|
|
87
|
+
required: false
|
|
88
|
+
declaredIn: self
|
|
89
|
+
doc: "True while the assistant answers; Send becomes Stop."
|
|
90
|
+
- name: canSubmit
|
|
91
|
+
type: boolean
|
|
92
|
+
required: false
|
|
93
|
+
declaredIn: self
|
|
94
|
+
doc: "Extra gate on sending, e.g. false while uploads are in progress."
|
|
95
|
+
- name: defaultValue
|
|
96
|
+
type: string
|
|
97
|
+
required: false
|
|
98
|
+
declaredIn: self
|
|
99
|
+
- name: disabled
|
|
100
|
+
type: boolean
|
|
101
|
+
required: false
|
|
102
|
+
declaredIn: self
|
|
103
|
+
- name: disabledReason
|
|
104
|
+
type: string
|
|
105
|
+
required: false
|
|
106
|
+
declaredIn: self
|
|
107
|
+
doc: "Shown under the field when `disabled`, e.g. why the assistant is unavailable."
|
|
108
|
+
- name: dropHint
|
|
109
|
+
type: ReactNode
|
|
110
|
+
required: false
|
|
111
|
+
declaredIn: self
|
|
112
|
+
doc: "Extra line in the drop overlay, e.g. accepted types and size limit."
|
|
113
|
+
- name: endActions
|
|
114
|
+
type: ReactNode
|
|
115
|
+
required: false
|
|
116
|
+
declaredIn: self
|
|
117
|
+
doc: "End of the action row, before Send: voice input, status badges."
|
|
118
|
+
- name: hasAttachments
|
|
119
|
+
type: boolean
|
|
120
|
+
required: false
|
|
121
|
+
declaredIn: self
|
|
122
|
+
doc: "Lets an empty field send, e.g. when files are attached."
|
|
123
|
+
- name: hint
|
|
124
|
+
type: ReactNode
|
|
125
|
+
required: false
|
|
126
|
+
declaredIn: self
|
|
127
|
+
doc: "Muted note under the field when nothing more urgent applies, e.g. \"Waiting for uploads to finish.\""
|
|
128
|
+
- name: label
|
|
129
|
+
type: string
|
|
130
|
+
required: false
|
|
131
|
+
declaredIn: self
|
|
132
|
+
doc: "Accessible name of the field."
|
|
133
|
+
- name: maxLength
|
|
134
|
+
type: number
|
|
135
|
+
required: false
|
|
136
|
+
declaredIn: self
|
|
137
|
+
doc: "Characters allowed; the counter appears from 80% and sending is blocked when over."
|
|
138
|
+
- name: onFilesDrop
|
|
139
|
+
type: "((files: File[]) => void)"
|
|
140
|
+
required: false
|
|
141
|
+
declaredIn: self
|
|
142
|
+
doc: "Receives files dropped on the composer, which shows a drop overlay while dragging. Ignored while `disabled`."
|
|
143
|
+
- name: onFilesPaste
|
|
144
|
+
type: "((files: File[]) => void)"
|
|
145
|
+
required: false
|
|
146
|
+
declaredIn: self
|
|
147
|
+
doc: "Receives files pasted into the field; without it, pasting files does nothing special."
|
|
148
|
+
- name: onStop
|
|
149
|
+
type: "(() => void)"
|
|
150
|
+
required: false
|
|
151
|
+
declaredIn: self
|
|
152
|
+
- name: onSubmit
|
|
153
|
+
type: "(text: string) => void"
|
|
154
|
+
required: true
|
|
155
|
+
declaredIn: self
|
|
156
|
+
doc: "Called with the trimmed text on Enter or Send. The field then clears and keeps focus."
|
|
157
|
+
- name: onValueChange
|
|
158
|
+
type: "((value: string) => void)"
|
|
159
|
+
required: false
|
|
160
|
+
declaredIn: self
|
|
161
|
+
- name: placeholder
|
|
162
|
+
type: string
|
|
163
|
+
required: false
|
|
164
|
+
declaredIn: self
|
|
165
|
+
- name: size
|
|
166
|
+
type: PromptInputSize
|
|
167
|
+
required: false
|
|
168
|
+
declaredIn: self
|
|
169
|
+
doc: "`sm` is a tighter composer for narrow chat columns and side panels."
|
|
170
|
+
- name: toolbar
|
|
171
|
+
type: ReactNode
|
|
172
|
+
required: false
|
|
173
|
+
declaredIn: self
|
|
174
|
+
doc: "Start of the action row: attach, tools. Use `PromptInputAction` for icon buttons."
|
|
175
|
+
- name: value
|
|
176
|
+
type: string
|
|
177
|
+
required: false
|
|
178
|
+
declaredIn: self
|
|
179
|
+
PromptInputAction:
|
|
180
|
+
- name: aurora
|
|
181
|
+
type: boolean
|
|
182
|
+
required: false
|
|
183
|
+
declaredIn: button
|
|
184
|
+
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)."
|
|
185
|
+
- name: label
|
|
186
|
+
type: string
|
|
187
|
+
required: true
|
|
188
|
+
declaredIn: self
|
|
189
|
+
doc: "Accessible name, and the tooltip unless `tooltip` is set."
|
|
190
|
+
- name: pressed
|
|
191
|
+
type: boolean
|
|
192
|
+
required: false
|
|
193
|
+
declaredIn: self
|
|
194
|
+
doc: "Renders as a toggle: sets `aria-pressed`."
|
|
195
|
+
- name: tooltip
|
|
196
|
+
type: ReactNode
|
|
197
|
+
required: false
|
|
198
|
+
declaredIn: self
|
|
199
|
+
doc: "Longer tooltip text, e.g. accepted file types."
|
|
200
|
+
extendsProps:
|
|
201
|
+
- "Omit<React.HTMLAttributes<HTMLDivElement>, \"onSubmit\" | \"defaultValue\">"
|
|
202
|
+
variants:
|
|
203
|
+
size:
|
|
204
|
+
kind: enum
|
|
205
|
+
options:
|
|
206
|
+
- sm
|
|
207
|
+
- md
|
|
208
|
+
default: md
|
|
209
|
+
on: PromptInput
|
|
210
|
+
kind:
|
|
211
|
+
kind: enum
|
|
212
|
+
options:
|
|
213
|
+
- image
|
|
214
|
+
- file
|
|
215
|
+
default: file
|
|
216
|
+
on: AttachmentChip
|
|
217
|
+
variantSource: prop-union
|
|
218
|
+
compoundVariants: []
|
|
219
|
+
sizeMaps: []
|
|
220
|
+
dataSlots:
|
|
221
|
+
- attachment-chip
|
|
222
|
+
- prompt-input
|
|
223
|
+
dependsOn:
|
|
224
|
+
internal:
|
|
225
|
+
- button
|
|
226
|
+
- input
|
|
227
|
+
- progress
|
|
228
|
+
- text
|
|
229
|
+
- tooltip
|
|
230
|
+
lib:
|
|
231
|
+
- cn
|
|
232
|
+
hooks: []
|
|
233
|
+
external:
|
|
234
|
+
- lucide-react
|
|
235
|
+
- react
|
|
236
|
+
contexts:
|
|
237
|
+
- name: PromptInputSizeContext
|
|
238
|
+
type: PromptInputSize
|
|
239
|
+
default: md
|
|
240
|
+
stories:
|
|
241
|
+
- exportName: Default
|
|
242
|
+
id: components-promptinput--default
|
|
243
|
+
- exportName: Busy
|
|
244
|
+
id: components-promptinput--busy
|
|
245
|
+
- exportName: NearTheLimit
|
|
246
|
+
id: components-promptinput--near-the-limit
|
|
247
|
+
- exportName: OverTheLimit
|
|
248
|
+
id: components-promptinput--over-the-limit
|
|
249
|
+
- exportName: Disabled
|
|
250
|
+
id: components-promptinput--disabled
|
|
251
|
+
- exportName: WithAttachments
|
|
252
|
+
id: components-promptinput--with-attachments
|
|
253
|
+
- exportName: Small
|
|
254
|
+
id: components-promptinput--small
|
|
255
|
+
- exportName: FileDrop
|
|
256
|
+
id: components-promptinput--file-drop
|
|
257
|
+
storybookTitle: Components/PromptInput
|
|
258
|
+
docsId: components-promptinput--documentation
|
|
259
|
+
argTypeOptions: {}
|
|
260
|
+
resolvedCleanly: true
|
|
261
|
+
contractHash: c19fe6810c55
|
|
262
|
+
factsHash: "197ba009f45f"
|
|
263
|
+
# >>> AUTHORED - humans own everything below this line. <<<
|
|
264
|
+
status: beta
|
|
265
|
+
summary: "The prompt composer for an AI feature: an auto-growing field with Enter to send, Send or Stop, a character limit, and slots for attachments, tools and voice."
|
|
266
|
+
useWhen:
|
|
267
|
+
- "people type a prompt to an assistant, with or without attachments"
|
|
268
|
+
- "the composer must switch to Stop while the assistant answers"
|
|
269
|
+
- "the assistant is unavailable and the composer should say why instead of disappearing"
|
|
270
|
+
useInstead:
|
|
271
|
+
- id: input
|
|
272
|
+
when: "a plain text field that is not a prompt to an assistant; for a one-line question scoped to the page use PromptInput size=\"sm\""
|
|
273
|
+
- id: search
|
|
274
|
+
when: "people search or filter rather than ask an assistant"
|
|
275
|
+
related:
|
|
276
|
+
- chat-message
|
|
277
|
+
- prompt-suggestions
|
|
278
|
+
- dropzone
|
|
279
|
+
a11y:
|
|
280
|
+
notes:
|
|
281
|
+
- "The field is named by label (default \"Prompt\"); the hint line is linked with aria-describedby."
|
|
282
|
+
- "Over the limit the field is aria-invalid and the hint says how many characters to cut; the counter is a polite live region."
|
|
283
|
+
- "Send and Stop are icon buttons named \"Send message\" and \"Stop generating\"."
|
|
284
|
+
- "PromptInputAction is named by label; pass tooltip for longer help text and pressed for toggles such as voice input."
|
|
285
|
+
- "Wrap AttachmentChips in role=\"list\" with a label; each chip's remove button names the file."
|
|
286
|
+
radixHandles: false
|
|
287
|
+
pitfalls:
|
|
288
|
+
- "onSubmit receives trimmed text and the field clears itself; in controlled mode it calls onValueChange(\"\") so keep value in sync."
|
|
289
|
+
- "Set hasAttachments so attachments alone can be sent, and canSubmit={false} while uploads run."
|
|
290
|
+
- "Pass onFilesDrop to accept dropped files; the composer shows its own drop overlay (add dropHint for limits) and ignores drags without files. Validate type and size in the handler."
|
|
291
|
+
- "Without onFilesPaste, pasted files are ignored and only text pastes."
|
|
292
|
+
- "Use PromptInputAction for icon buttons in toolbar and endActions so they match the round 36px Send button; it needs a TooltipProvider."
|
|
293
|
+
canonicalSnippet: |
|
|
294
|
+
import { PromptInput } from "@adres/mgda-ui"
|
|
295
|
+
|
|
296
|
+
<PromptInput
|
|
297
|
+
onSubmit={send}
|
|
298
|
+
busy={replying}
|
|
299
|
+
onStop={stop}
|
|
300
|
+
placeholder="Ask about properties, prices or communities"
|
|
301
|
+
/>
|
|
302
|
+
reviewedAt: 2026-10-07
|
|
303
|
+
reviewedAgainstContractHash: "c19fe6810c55"
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Usage
|
|
307
|
+
|
|
308
|
+
`PromptInput` is the composer. The field grows to about eight lines then
|
|
309
|
+
scrolls; Enter sends and Shift+Enter adds a line. `onSubmit` gets the trimmed
|
|
310
|
+
text, after which the field clears and keeps focus. Leave it uncontrolled
|
|
311
|
+
with `defaultValue`, or control it with `value` and `onValueChange` when
|
|
312
|
+
something else writes into the field (voice input, a template chip).
|
|
313
|
+
|
|
314
|
+
While `busy`, Send becomes Stop (`onStop`). The counter appears at 80% of
|
|
315
|
+
`maxLength` (default 2000), turns amber at 90%, and over the limit the field
|
|
316
|
+
turns invalid and sending is blocked. `disabled` with `disabledReason` keeps
|
|
317
|
+
the composer visible and explains why. Put an attach button and tools menu in
|
|
318
|
+
`toolbar`, voice input or status badges in `endActions`, and a list of
|
|
319
|
+
`AttachmentChip`s in `attachments`; `hasAttachments`, `canSubmit` and `hint`
|
|
320
|
+
tie sending to their state. `onFilesDrop` accepts files dropped anywhere on
|
|
321
|
+
the composer and shows a dashed drop overlay while dragging, with `dropHint`
|
|
322
|
+
for accepted types and limits; drags without files pass through. The container is a 24px rounded card with a
|
|
323
|
+
borderless field and the action row underneath; `PromptInputAction` gives
|
|
324
|
+
toolbar icons the same round 36px shape as Send.
|
|
325
|
+
|
|
326
|
+
`size="sm"` is a tighter composer for narrow chat columns and side panels:
|
|
327
|
+
smaller corners and padding, a 36px field, a close action row, 32px Send and
|
|
328
|
+
Stop, and about six lines before scrolling. `PromptInputAction`s in the
|
|
329
|
+
toolbar follow the composer's size.
|
|
330
|
+
|
|
331
|
+
`characterCountTone` and `formatFileSize` are exported for custom composers.
|
|
332
|
+
|
|
333
|
+
## Anatomy
|
|
334
|
+
|
|
335
|
+
- `PromptInput` - rounded container with attachments, field, action row (toolbar, counter, end actions, Send or Stop) and hint.
|
|
336
|
+
- `PromptInputAction` - round 36px outline icon button with a tooltip for the action row.
|
|
337
|
+
- `AttachmentChip` - one file: thumbnail or icon, name, then upload progress, size or error, and a remove button.
|