@tulipfarm/sprout 0.0.0-stage → 0.2.0
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/LICENSE +21 -0
- package/README.md +183 -2
- package/dist/components/accordion.d.ts +28 -0
- package/dist/components/accordion.js +26 -0
- package/dist/components/alert-dialog.d.ts +60 -0
- package/dist/components/alert-dialog.js +69 -0
- package/dist/components/alert.d.ts +30 -0
- package/dist/components/alert.js +35 -0
- package/dist/components/aspect-ratio.d.ts +7 -0
- package/dist/components/aspect-ratio.js +6 -0
- package/dist/components/attachment.d.ts +118 -0
- package/dist/components/attachment.js +285 -0
- package/dist/components/avatar.d.ts +32 -0
- package/dist/components/avatar.js +73 -0
- package/dist/components/badge.d.ts +21 -0
- package/dist/components/badge.js +27 -0
- package/dist/components/brand-icon.d.ts +28 -0
- package/dist/components/brand-icon.js +82 -0
- package/dist/components/breadcrumb.d.ts +29 -0
- package/dist/components/breadcrumb.js +44 -0
- package/dist/components/button-group.d.ts +28 -0
- package/dist/components/button-group.js +36 -0
- package/dist/components/button.d.ts +79 -0
- package/dist/components/button.js +93 -0
- package/dist/components/calendar.d.ts +27 -0
- package/dist/components/calendar.js +107 -0
- package/dist/components/canvas.d.ts +78 -0
- package/dist/components/canvas.js +180 -0
- package/dist/components/card.d.ts +43 -0
- package/dist/components/card.js +42 -0
- package/dist/components/carousel.d.ts +57 -0
- package/dist/components/carousel.js +422 -0
- package/dist/components/chart.d.ts +112 -0
- package/dist/components/chart.js +172 -0
- package/dist/components/chat-confirmation.d.ts +42 -0
- package/dist/components/chat-confirmation.js +62 -0
- package/dist/components/chat-input.d.ts +94 -0
- package/dist/components/chat-input.js +279 -0
- package/dist/components/chat-plan.d.ts +21 -0
- package/dist/components/chat-plan.js +35 -0
- package/dist/components/chat-sources.d.ts +64 -0
- package/dist/components/chat-sources.js +66 -0
- package/dist/components/checkbox.d.ts +16 -0
- package/dist/components/checkbox.js +17 -0
- package/dist/components/choice-list.d.ts +53 -0
- package/dist/components/choice-list.js +36 -0
- package/dist/components/code-block.d.ts +35 -0
- package/dist/components/code-block.js +64 -0
- package/dist/components/collapsible.d.ts +24 -0
- package/dist/components/collapsible.js +27 -0
- package/dist/components/combobox.d.ts +95 -0
- package/dist/components/combobox.js +106 -0
- package/dist/components/command.d.ts +94 -0
- package/dist/components/command.js +414 -0
- package/dist/components/context-menu.d.ts +57 -0
- package/dist/components/context-menu.js +60 -0
- package/dist/components/dialog.d.ts +60 -0
- package/dist/components/dialog.js +79 -0
- package/dist/components/direction.d.ts +6 -0
- package/dist/components/direction.js +6 -0
- package/dist/components/dropdown-menu.d.ts +62 -0
- package/dist/components/dropdown-menu.js +59 -0
- package/dist/components/field.d.ts +117 -0
- package/dist/components/field.js +150 -0
- package/dist/components/file-explorer.d.ts +27 -0
- package/dist/components/file-explorer.js +300 -0
- package/dist/components/file-viewer.d.ts +137 -0
- package/dist/components/file-viewer.js +400 -0
- package/dist/components/form.d.ts +87 -0
- package/dist/components/form.js +55 -0
- package/dist/components/glass-banner.d.ts +27 -0
- package/dist/components/glass-banner.js +116 -0
- package/dist/components/gradient-banner.d.ts +37 -0
- package/dist/components/gradient-banner.js +43 -0
- package/dist/components/hover-card.d.ts +27 -0
- package/dist/components/hover-card.js +26 -0
- package/dist/components/input-group.d.ts +68 -0
- package/dist/components/input-group.js +88 -0
- package/dist/components/input-otp.d.ts +38 -0
- package/dist/components/input-otp.js +43 -0
- package/dist/components/input.d.ts +16 -0
- package/dist/components/input.js +18 -0
- package/dist/components/kbd.d.ts +12 -0
- package/dist/components/kbd.js +11 -0
- package/dist/components/label.d.ts +8 -0
- package/dist/components/label.js +10 -0
- package/dist/components/mention-list.d.ts +54 -0
- package/dist/components/mention-list.js +31 -0
- package/dist/components/menubar.d.ts +64 -0
- package/dist/components/menubar.js +68 -0
- package/dist/components/message-actions.d.ts +34 -0
- package/dist/components/message-actions.js +68 -0
- package/dist/components/message-response.d.ts +20 -0
- package/dist/components/message-response.js +46 -0
- package/dist/components/message-scroller.d.ts +71 -0
- package/dist/components/message-scroller.js +217 -0
- package/dist/components/message.d.ts +49 -0
- package/dist/components/message.js +59 -0
- package/dist/components/navigation-menu.d.ts +45 -0
- package/dist/components/navigation-menu.js +54 -0
- package/dist/components/notice-banner.d.ts +14 -0
- package/dist/components/notice-banner.js +11 -0
- package/dist/components/page-content.d.ts +7 -0
- package/dist/components/page-content.js +9 -0
- package/dist/components/page-header.d.ts +37 -0
- package/dist/components/page-header.js +53 -0
- package/dist/components/pagination.d.ts +29 -0
- package/dist/components/pagination.js +29 -0
- package/dist/components/plan-outline.d.ts +60 -0
- package/dist/components/plan-outline.js +108 -0
- package/dist/components/popover.d.ts +34 -0
- package/dist/components/popover.js +35 -0
- package/dist/components/progress.d.ts +27 -0
- package/dist/components/progress.js +35 -0
- package/dist/components/prompt-list.d.ts +23 -0
- package/dist/components/prompt-list.js +11 -0
- package/dist/components/questionnaire.d.ts +148 -0
- package/dist/components/questionnaire.js +1002 -0
- package/dist/components/radio-group.d.ts +16 -0
- package/dist/components/radio-group.js +21 -0
- package/dist/components/reasoning-effort.d.ts +24 -0
- package/dist/components/reasoning-effort.js +269 -0
- package/dist/components/resizable.d.ts +67 -0
- package/dist/components/resizable.js +536 -0
- package/dist/components/result-card.d.ts +58 -0
- package/dist/components/result-card.js +88 -0
- package/dist/components/review-card.d.ts +62 -0
- package/dist/components/review-card.js +49 -0
- package/dist/components/rich-text-editor.d.ts +51 -0
- package/dist/components/rich-text-editor.js +248 -0
- package/dist/components/schema-diagram.d.ts +52 -0
- package/dist/components/schema-diagram.js +226 -0
- package/dist/components/scroll-area.d.ts +22 -0
- package/dist/components/scroll-area.js +19 -0
- package/dist/components/search-dialog.d.ts +103 -0
- package/dist/components/search-dialog.js +65 -0
- package/dist/components/search-field.d.ts +17 -0
- package/dist/components/search-field.js +27 -0
- package/dist/components/select.d.ts +57 -0
- package/dist/components/select.js +57 -0
- package/dist/components/selection-slot.d.ts +18 -0
- package/dist/components/selection-slot.js +53 -0
- package/dist/components/separator.d.ts +48 -0
- package/dist/components/separator.js +54 -0
- package/dist/components/settings-list.d.ts +26 -0
- package/dist/components/settings-list.js +17 -0
- package/dist/components/sheet.d.ts +70 -0
- package/dist/components/sheet.js +77 -0
- package/dist/components/sidebar.d.ts +70 -0
- package/dist/components/sidebar.js +187 -0
- package/dist/components/skeleton.d.ts +31 -0
- package/dist/components/skeleton.js +32 -0
- package/dist/components/slider.d.ts +17 -0
- package/dist/components/slider.js +24 -0
- package/dist/components/spinner.d.ts +37 -0
- package/dist/components/spinner.js +43 -0
- package/dist/components/state-panel-samples.d.ts +25 -0
- package/dist/components/state-panel-samples.js +423 -0
- package/dist/components/state-panel.d.ts +35 -0
- package/dist/components/state-panel.js +29 -0
- package/dist/components/state-sample.d.ts +63 -0
- package/dist/components/state-sample.js +42 -0
- package/dist/components/switch.d.ts +12 -0
- package/dist/components/switch.js +14 -0
- package/dist/components/table-nuqs.d.ts +16 -0
- package/dist/components/table-nuqs.js +59 -0
- package/dist/components/table.d.ts +120 -0
- package/dist/components/table.js +663 -0
- package/dist/components/tabs.d.ts +37 -0
- package/dist/components/tabs.js +36 -0
- package/dist/components/textarea.d.ts +18 -0
- package/dist/components/textarea.js +19 -0
- package/dist/components/toast.d.ts +45 -0
- package/dist/components/toast.js +83 -0
- package/dist/components/toggle-group.d.ts +30 -0
- package/dist/components/toggle-group.js +39 -0
- package/dist/components/toggle.d.ts +27 -0
- package/dist/components/toggle.js +21 -0
- package/dist/components/tool-activity.d.ts +79 -0
- package/dist/components/tool-activity.js +226 -0
- package/dist/components/toolbar-status.d.ts +21 -0
- package/dist/components/toolbar-status.js +14 -0
- package/dist/components/tooltip.d.ts +31 -0
- package/dist/components/tooltip.js +99 -0
- package/dist/components/typed-text.d.ts +17 -0
- package/dist/components/typed-text.js +56 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.js +90 -0
- package/dist/internal/brand-glyphs.d.ts +370 -0
- package/dist/internal/brand-glyphs.js +262 -0
- package/dist/internal/classes.d.ts +3 -0
- package/dist/internal/classes.js +20 -0
- package/dist/internal/code-tokens.d.ts +4 -0
- package/dist/internal/code-tokens.js +34 -0
- package/dist/internal/fieldset.d.ts +6 -0
- package/dist/internal/fieldset.js +38 -0
- package/dist/internal/file-kind.d.ts +4 -0
- package/dist/internal/file-kind.js +62 -0
- package/dist/internal/languages.d.ts +7 -0
- package/dist/internal/languages.js +1010 -0
- package/dist/internal/message-scroller.d.ts +102 -0
- package/dist/internal/message-scroller.js +637 -0
- package/dist/internal/pressable.d.ts +2 -0
- package/dist/internal/pressable.js +29 -0
- package/dist/internal/syntax.d.ts +14 -0
- package/dist/internal/syntax.js +137 -0
- package/dist/styles/accordion.css +102 -0
- package/dist/styles/alert-dialog.css +198 -0
- package/dist/styles/alert.css +149 -0
- package/dist/styles/aspect-ratio.css +8 -0
- package/dist/styles/attachment.css +700 -0
- package/dist/styles/avatar.css +186 -0
- package/dist/styles/badge.css +178 -0
- package/dist/styles/brand-icon.css +104 -0
- package/dist/styles/breadcrumb.css +121 -0
- package/dist/styles/button-group.css +113 -0
- package/dist/styles/button.css +380 -0
- package/dist/styles/calendar.css +295 -0
- package/dist/styles/canvas.css +313 -0
- package/dist/styles/card.css +146 -0
- package/dist/styles/carousel.css +107 -0
- package/dist/styles/chart.css +227 -0
- package/dist/styles/chat-confirmation.css +29 -0
- package/dist/styles/chat-input.css +240 -0
- package/dist/styles/chat-plan.css +109 -0
- package/dist/styles/chat-sources.css +191 -0
- package/dist/styles/checkbox.css +122 -0
- package/dist/styles/choice-list.css +343 -0
- package/dist/styles/code-block.css +211 -0
- package/dist/styles/collapsible.css +72 -0
- package/dist/styles/combobox.css +347 -0
- package/dist/styles/command.css +233 -0
- package/dist/styles/context-menu.css +151 -0
- package/dist/styles/dialog.css +237 -0
- package/dist/styles/dropdown-menu.css +150 -0
- package/dist/styles/field.css +340 -0
- package/dist/styles/file-explorer.css +517 -0
- package/dist/styles/file-viewer.css +375 -0
- package/dist/styles/form.css +155 -0
- package/dist/styles/glass-banner.css +308 -0
- package/dist/styles/gradient-banner.css +256 -0
- package/dist/styles/hover-card.css +95 -0
- package/dist/styles/index.css +268 -0
- package/dist/styles/input-group.css +285 -0
- package/dist/styles/input-otp.css +138 -0
- package/dist/styles/input.css +98 -0
- package/dist/styles/kbd.css +59 -0
- package/dist/styles/label.css +89 -0
- package/dist/styles/mention-list.css +166 -0
- package/dist/styles/menubar.css +226 -0
- package/dist/styles/message-actions.css +83 -0
- package/dist/styles/message-response.css +176 -0
- package/dist/styles/message-scroller.css +136 -0
- package/dist/styles/message.css +310 -0
- package/dist/styles/navigation-menu.css +291 -0
- package/dist/styles/notice-banner.css +68 -0
- package/dist/styles/page-content.css +21 -0
- package/dist/styles/page-header.css +156 -0
- package/dist/styles/pagination.css +72 -0
- package/dist/styles/plan-outline.css +393 -0
- package/dist/styles/popover.css +140 -0
- package/dist/styles/progress.css +93 -0
- package/dist/styles/prompt-list.css +165 -0
- package/dist/styles/questionnaire.css +308 -0
- package/dist/styles/radio-group.css +119 -0
- package/dist/styles/reasoning-effort.css +157 -0
- package/dist/styles/resizable.css +108 -0
- package/dist/styles/result-card.css +215 -0
- package/dist/styles/review-card.css +235 -0
- package/dist/styles/rich-text-editor.css +169 -0
- package/dist/styles/schema-diagram.css +419 -0
- package/dist/styles/scroll-area.css +77 -0
- package/dist/styles/search-dialog.css +280 -0
- package/dist/styles/search-field.css +17 -0
- package/dist/styles/select.css +285 -0
- package/dist/styles/selection-slot.css +31 -0
- package/dist/styles/separator.css +206 -0
- package/dist/styles/settings-list.css +81 -0
- package/dist/styles/sheet.css +361 -0
- package/dist/styles/sidebar.css +363 -0
- package/dist/styles/skeleton.css +80 -0
- package/dist/styles/slider.css +142 -0
- package/dist/styles/spinner.css +39 -0
- package/dist/styles/state-panel-samples.css +41 -0
- package/dist/styles/state-panel.css +173 -0
- package/dist/styles/state-sample.css +285 -0
- package/dist/styles/switch.css +128 -0
- package/dist/styles/table.css +604 -0
- package/dist/styles/tabs.css +223 -0
- package/dist/styles/textarea.css +77 -0
- package/dist/styles/themes/chatgpt.css +125 -0
- package/dist/styles/themes/claude.css +125 -0
- package/dist/styles/themes/cloudflare.css +125 -0
- package/dist/styles/themes/discord.css +125 -0
- package/dist/styles/themes/github.css +125 -0
- package/dist/styles/themes/grok.css +125 -0
- package/dist/styles/themes/linear.css +126 -0
- package/dist/styles/themes/neutral.css +125 -0
- package/dist/styles/themes/notion.css +125 -0
- package/dist/styles/themes/perplexity.css +125 -0
- package/dist/styles/themes/raycast.css +125 -0
- package/dist/styles/themes/spotify.css +125 -0
- package/dist/styles/themes/stripe.css +125 -0
- package/dist/styles/themes/supabase.css +125 -0
- package/dist/styles/themes/tulipfarm.css +115 -0
- package/dist/styles/themes/vercel.css +126 -0
- package/dist/styles/toast.css +197 -0
- package/dist/styles/toggle-group.css +161 -0
- package/dist/styles/toggle.css +119 -0
- package/dist/styles/tool-activity.css +396 -0
- package/dist/styles/toolbar-status.css +52 -0
- package/dist/styles/tooltip.css +122 -0
- package/dist/styles/typed-text.css +17 -0
- package/package.json +452 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 TulipFarm
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,184 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# 🌱 Sprõut
|
|
4
|
+
|
|
5
|
+
**Thoughtful React controls, built with Base UI and Tailwind CSS.**
|
|
6
|
+
|
|
7
|
+
Every state planted, every edge case tended.
|
|
8
|
+
|
|
9
|
+
[](https://github.com/TulipFarm/sprout/actions/workflows/ci.yml)
|
|
10
|
+
[](https://www.npmjs.com/package/@tulipfarm/sprout)
|
|
11
|
+
[](https://github.com/TulipFarm/sprout/blob/main/LICENSE)
|
|
12
|
+
[](https://www.conventionalcommits.org)
|
|
13
|
+
|
|
14
|
+
[Install](#install) · [Components](#components) · [Theming](#theming) · [Develop](#develop) · [Contributing](#contributing)
|
|
15
|
+
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
Sprõut is a general-purpose component library from
|
|
21
|
+
[TulipFarm](https://tulipfarm.ai). It cares about the small things: busy,
|
|
22
|
+
blocked, invalid, empty, and loading states, keyboard paths, and screen reader
|
|
23
|
+
labels. The default theme is neutral, so it fits your product, not ours.
|
|
24
|
+
|
|
25
|
+
- **Accessible by default.** Built on [Base UI](https://base-ui.com) primitives.
|
|
26
|
+
- **Tailwind CSS 4 native.** One CSS import. No JavaScript theme object.
|
|
27
|
+
- **Tree-shakable.** Every component has its own import path.
|
|
28
|
+
- **Agent-ready.** Chat, plan, tool, and review components for AI products.
|
|
29
|
+
- **Light and dark.** A neutral default and 15 more CSS theme presets.
|
|
30
|
+
|
|
31
|
+
> [!NOTE]
|
|
32
|
+
> Sprõut is pre-1.0. APIs can change between minor versions.
|
|
33
|
+
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
Sprõut needs React 19 and Tailwind CSS 4.
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
pnpm add @tulipfarm/sprout
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
<details>
|
|
43
|
+
<summary>Install from GitHub instead of npm</summary>
|
|
44
|
+
|
|
45
|
+
Each [GitHub release](https://github.com/TulipFarm/sprout/releases) has the
|
|
46
|
+
package tarball attached. No login needed:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
pnpm add https://github.com/TulipFarm/sprout/releases/download/v0.1.0/tulipfarm-sprout-0.1.0.tgz
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The package is also on GitHub Packages. It needs a GitHub token with
|
|
53
|
+
`read:packages`. Add this to `.npmrc`:
|
|
54
|
+
|
|
55
|
+
```ini
|
|
56
|
+
@tulipfarm:registry=https://npm.pkg.github.com
|
|
57
|
+
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
</details>
|
|
61
|
+
|
|
62
|
+
Add the styles to your CSS entry:
|
|
63
|
+
|
|
64
|
+
```css
|
|
65
|
+
@import "tailwindcss";
|
|
66
|
+
@import "@tulipfarm/sprout/styles.css";
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Use a component:
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
import { Button } from "@tulipfarm/sprout/button";
|
|
73
|
+
import { Badge } from "@tulipfarm/sprout/badge";
|
|
74
|
+
|
|
75
|
+
export function Status() {
|
|
76
|
+
return (
|
|
77
|
+
<>
|
|
78
|
+
<Badge variant="success">Connected</Badge>
|
|
79
|
+
<Button state={{ kind: "busy" }} pendingLabel="Saving…">
|
|
80
|
+
Save
|
|
81
|
+
</Button>
|
|
82
|
+
</>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The CSS entry registers Sprõut's classes with Tailwind. It does not change your
|
|
88
|
+
body styles or generic shadcn tokens. Tailwind utility prefixes are not
|
|
89
|
+
supported yet.
|
|
90
|
+
|
|
91
|
+
## Components
|
|
92
|
+
|
|
93
|
+
Each component imports from `@tulipfarm/sprout/<name>`, for example
|
|
94
|
+
`@tulipfarm/sprout/dialog`. See the [component reference](https://github.com/TulipFarm/sprout/blob/main/docs/components.md)
|
|
95
|
+
for notes on each one.
|
|
96
|
+
|
|
97
|
+
| Group | Components |
|
|
98
|
+
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
99
|
+
| **Actions** | Button · Button Group · Toggle · Toggle Group · Toolbar Status · Kbd |
|
|
100
|
+
| **Forms** | Field · Form · Label · Input · Input Group · Input OTP · Textarea · Checkbox · Radio Group · Switch · Slider · Select · Combobox · Choice List · Calendar · Search Field · Rich Text Editor · Mention List · Questionnaire · Selection Slot · Reasoning Effort |
|
|
101
|
+
| **Overlays** | Dialog · Alert Dialog · Sheet · Popover · Hover Card · Tooltip · Dropdown Menu · Context Menu · Menubar · Command · Search Dialog · Toast |
|
|
102
|
+
| **Layout & navigation** | Sidebar · Navigation Menu · Breadcrumb · Pagination · Tabs · Accordion · Collapsible · Page Header · Page Content · Settings List · Card · Carousel · Resizable · Scroll Area · Separator · Aspect Ratio · Direction · Canvas |
|
|
103
|
+
| **Feedback** | Alert · Notice Banner · Badge · Progress · Spinner · Skeleton · State Panel · State Sample |
|
|
104
|
+
| **Data display** | Table · Chart · Code Block · File Viewer · Schema Diagram · Avatar · Brand Icon · Attachment · Typed Text · Gradient Banner · Glass Banner |
|
|
105
|
+
| **Agents & chat** | Message · Message Actions · Message Response · Message Scroller · Chat Confirmation · Chat Plan · Chat Sources · Plan Outline · Prompt List · Result Card · Review Card · Tool Activity |
|
|
106
|
+
|
|
107
|
+
## Theming
|
|
108
|
+
|
|
109
|
+
Themes are plain CSS. Override any `--sprout-*` token:
|
|
110
|
+
|
|
111
|
+
```css
|
|
112
|
+
:root {
|
|
113
|
+
--sprout-radius-control: 0.5rem;
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Presets live in `@tulipfarm/sprout/themes/*`: `neutral`, `tulipfarm`, `github`,
|
|
118
|
+
`linear`, `vercel`, `stripe`, `notion`, and more.
|
|
119
|
+
|
|
120
|
+
```css
|
|
121
|
+
@import "@tulipfarm/sprout/themes/tulipfarm.css";
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### shadcn
|
|
125
|
+
|
|
126
|
+
A shadcn registry item is at `apps/docs/public/r/sprout.json`. It works with
|
|
127
|
+
`shadcn add` (tested with shadcn 4.22.0). A public URL will come with the docs
|
|
128
|
+
release.
|
|
129
|
+
|
|
130
|
+
## Develop
|
|
131
|
+
|
|
132
|
+
You need Node 22.22+ and pnpm 11.5.3.
|
|
133
|
+
|
|
134
|
+
```sh
|
|
135
|
+
pnpm install
|
|
136
|
+
pnpm dev # docs and live examples at http://localhost:4321
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
After you change package code, run `pnpm --filter @tulipfarm/sprout build`.
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
pnpm build
|
|
143
|
+
pnpm typecheck
|
|
144
|
+
pnpm format:check
|
|
145
|
+
pnpm test
|
|
146
|
+
pnpm exec playwright install chromium
|
|
147
|
+
pnpm test:browser
|
|
148
|
+
pnpm test:install # packs the library and installs it in a fresh app
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Run test commands one at a time.
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
sprout/
|
|
155
|
+
├── packages/sprout the published package and CSS themes
|
|
156
|
+
├── apps/docs Astro docs, live examples, shadcn registry
|
|
157
|
+
├── tests unit, browser, and packed-consumer tests
|
|
158
|
+
└── docs ADRs, plans, component reference
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
The docs deploy to Cloudflare Pages: build with `pnpm build` and serve
|
|
162
|
+
`apps/docs/dist`.
|
|
163
|
+
|
|
164
|
+
## Contributing
|
|
165
|
+
|
|
166
|
+
Contributions are welcome. Read [CONTRIBUTING.md](https://github.com/TulipFarm/sprout/blob/main/CONTRIBUTING.md) and the
|
|
167
|
+
[Code of Conduct](https://github.com/TulipFarm/sprout/blob/main/CODE_OF_CONDUCT.md). Report security problems privately, as
|
|
168
|
+
described in [SECURITY.md](https://github.com/TulipFarm/sprout/blob/main/SECURITY.md).
|
|
169
|
+
|
|
170
|
+
## License
|
|
171
|
+
|
|
172
|
+
[MIT](https://github.com/TulipFarm/sprout/blob/main/LICENSE) © TulipFarm
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
<div align="center">
|
|
177
|
+
<a href="https://tulipfarm.ai">
|
|
178
|
+
<img src="https://tulipfarm.ai/brand/v1/mark-green.svg" alt="TulipFarm" width="40" height="40">
|
|
179
|
+
</a>
|
|
180
|
+
<p>
|
|
181
|
+
Grown at <a href="https://tulipfarm.ai"><b>TulipFarm</b></a>,<br>
|
|
182
|
+
one farm for every team's records, docs, agents, and workflows.
|
|
183
|
+
</p>
|
|
184
|
+
</div>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Accordion as BaseAccordion } from "@base-ui/react/accordion";
|
|
2
|
+
export declare const accordionTriggerVariantNames: readonly ["default", "quiet"];
|
|
3
|
+
export type AccordionTriggerVariant = (typeof accordionTriggerVariantNames)[number];
|
|
4
|
+
export type AccordionProps<Value = any> = BaseAccordion.Root.Props<Value>;
|
|
5
|
+
/**
|
|
6
|
+
* A stack of sections that open in place. One section opens at a time unless
|
|
7
|
+
* you pass `multiple`. Pass `value` and `onValueChange` to control which
|
|
8
|
+
* sections are open, or `defaultValue` to let it manage itself.
|
|
9
|
+
*/
|
|
10
|
+
export declare function Accordion<Value = any>({ className, ...props }: AccordionProps<Value>): import("react").JSX.Element;
|
|
11
|
+
export type AccordionItemProps = BaseAccordion.Item.Props;
|
|
12
|
+
/** One section. Give it a `value` to open it by default or to control it. */
|
|
13
|
+
export declare function AccordionItem({ className, ...props }: AccordionItemProps): import("react").JSX.Element;
|
|
14
|
+
export interface AccordionTriggerProps extends BaseAccordion.Trigger.Props {
|
|
15
|
+
/**
|
|
16
|
+
* `default` underlines its label on hover. `quiet` stays still, for
|
|
17
|
+
* triggers that hold a title and a summary line.
|
|
18
|
+
*/
|
|
19
|
+
variant?: AccordionTriggerVariant;
|
|
20
|
+
}
|
|
21
|
+
/** The heading button that opens and closes its section. */
|
|
22
|
+
export declare function AccordionTrigger({ className, children, variant, ...props }: AccordionTriggerProps): import("react").JSX.Element;
|
|
23
|
+
export interface AccordionContentProps extends Omit<BaseAccordion.Panel.Props, "className"> {
|
|
24
|
+
/** Classes for the padded inner box that holds the content. */
|
|
25
|
+
className?: string;
|
|
26
|
+
}
|
|
27
|
+
/** The section body. It grows open and shrinks closed. */
|
|
28
|
+
export declare function AccordionContent({ className, children, ...props }: AccordionContentProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Accordion as BaseAccordion } from "@base-ui/react/accordion";
|
|
4
|
+
import { ChevronDown } from "reicon-react/icons/ChevronDown";
|
|
5
|
+
import { cn, stateClassName } from "../internal/classes.js";
|
|
6
|
+
export const accordionTriggerVariantNames = ["default", "quiet"];
|
|
7
|
+
/**
|
|
8
|
+
* A stack of sections that open in place. One section opens at a time unless
|
|
9
|
+
* you pass `multiple`. Pass `value` and `onValueChange` to control which
|
|
10
|
+
* sections are open, or `defaultValue` to let it manage itself.
|
|
11
|
+
*/
|
|
12
|
+
export function Accordion({ className, ...props }) {
|
|
13
|
+
return (_jsx(BaseAccordion.Root, { "data-slot": "accordion", ...props, className: stateClassName("sprout-accordion", className) }));
|
|
14
|
+
}
|
|
15
|
+
/** One section. Give it a `value` to open it by default or to control it. */
|
|
16
|
+
export function AccordionItem({ className, ...props }) {
|
|
17
|
+
return (_jsx(BaseAccordion.Item, { "data-slot": "accordion-item", ...props, className: stateClassName("sprout-accordion-item", className) }));
|
|
18
|
+
}
|
|
19
|
+
/** The heading button that opens and closes its section. */
|
|
20
|
+
export function AccordionTrigger({ className, children, variant = "default", ...props }) {
|
|
21
|
+
return (_jsx(BaseAccordion.Header, { "data-slot": "accordion-header", className: "sprout-accordion-header", children: _jsxs(BaseAccordion.Trigger, { "data-slot": "accordion-trigger", "data-variant": variant, ...props, className: stateClassName(`sprout-accordion-trigger sprout-accordion-trigger-${variant}`, className), children: [children, _jsx(ChevronDown, { size: 16, "aria-hidden": "true", "data-slot": "accordion-trigger-icon", className: "sprout-accordion-trigger-icon" })] }) }));
|
|
22
|
+
}
|
|
23
|
+
/** The section body. It grows open and shrinks closed. */
|
|
24
|
+
export function AccordionContent({ className, children, ...props }) {
|
|
25
|
+
return (_jsx(BaseAccordion.Panel, { "data-slot": "accordion-content", ...props, className: "sprout-accordion-content", children: _jsx("div", { className: cn("sprout-accordion-content-inner", className), children: children }) }));
|
|
26
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { AlertDialog as AlertDialogPrimitive } from "@base-ui/react/alert-dialog";
|
|
2
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
3
|
+
import { type ButtonProps, type ButtonSize, type ButtonVariant } from "./button.js";
|
|
4
|
+
export declare const alertDialogSizeNames: readonly ["default", "sm"];
|
|
5
|
+
export type AlertDialogSize = (typeof alertDialogSizeNames)[number];
|
|
6
|
+
export type AlertDialogProps = AlertDialogPrimitive.Root.Props;
|
|
7
|
+
export declare function AlertDialog(props: AlertDialogProps): import("react").JSX.Element;
|
|
8
|
+
export type AlertDialogTriggerProps = AlertDialogPrimitive.Trigger.Props;
|
|
9
|
+
export declare function AlertDialogTrigger(props: AlertDialogTriggerProps): import("react").JSX.Element;
|
|
10
|
+
export type AlertDialogPortalProps = AlertDialogPrimitive.Portal.Props;
|
|
11
|
+
export declare function AlertDialogPortal(props: AlertDialogPortalProps): import("react").JSX.Element;
|
|
12
|
+
export type AlertDialogOverlayProps = AlertDialogPrimitive.Backdrop.Props;
|
|
13
|
+
export declare function AlertDialogOverlay({ className, ...props }: AlertDialogOverlayProps): import("react").JSX.Element;
|
|
14
|
+
export interface AlertDialogContentProps extends AlertDialogPrimitive.Popup.Props {
|
|
15
|
+
/** `sm` centers the header and splits the footer into two equal buttons. */
|
|
16
|
+
size?: AlertDialogSize;
|
|
17
|
+
/** Where the portal renders. Defaults to `document.body`. */
|
|
18
|
+
container?: AlertDialogPrimitive.Portal.Props["container"];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The alert dialog surface. It renders its own portal and overlay, so place
|
|
22
|
+
* it directly inside `AlertDialog`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function AlertDialogContent({ className, size, container, ...props }: AlertDialogContentProps): import("react").JSX.Element;
|
|
25
|
+
type PartSlot = "alert-dialog-header" | "alert-dialog-footer" | "alert-dialog-media";
|
|
26
|
+
export interface AlertDialogPartState extends Record<string, unknown> {
|
|
27
|
+
slot: PartSlot;
|
|
28
|
+
}
|
|
29
|
+
export type AlertDialogPartProps = useRender.ComponentProps<"div", AlertDialogPartState>;
|
|
30
|
+
/**
|
|
31
|
+
* Groups media, title, and description. Centered on narrow screens and in
|
|
32
|
+
* `sm` dialogs; from 640px a `default` dialog aligns it to the start with the
|
|
33
|
+
* media beside the text.
|
|
34
|
+
*/
|
|
35
|
+
export declare const AlertDialogHeader: ({ className, render, ref, ...props }: AlertDialogPartProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
36
|
+
/**
|
|
37
|
+
* A tinted action bar pinned to the bottom edge. Actions stack in reverse
|
|
38
|
+
* order on narrow screens and align right from 640px; `sm` dialogs always
|
|
39
|
+
* split it into two equal columns.
|
|
40
|
+
*/
|
|
41
|
+
export declare const AlertDialogFooter: ({ className, render, ref, ...props }: AlertDialogPartProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
42
|
+
/** A 40px tile for an icon above or beside the title. */
|
|
43
|
+
export declare const AlertDialogMedia: ({ className, render, ref, ...props }: AlertDialogPartProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
44
|
+
export type AlertDialogTitleProps = AlertDialogPrimitive.Title.Props;
|
|
45
|
+
export declare function AlertDialogTitle({ className, ...props }: AlertDialogTitleProps): import("react").JSX.Element;
|
|
46
|
+
export type AlertDialogDescriptionProps = AlertDialogPrimitive.Description.Props;
|
|
47
|
+
export declare function AlertDialogDescription({ className, ...props }: AlertDialogDescriptionProps): import("react").JSX.Element;
|
|
48
|
+
export type AlertDialogActionProps = ButtonProps;
|
|
49
|
+
/**
|
|
50
|
+
* The confirming button. It does not close the dialog by itself, so the
|
|
51
|
+
* caller can keep it open while work is pending and close it on success.
|
|
52
|
+
*/
|
|
53
|
+
export declare function AlertDialogAction(props: AlertDialogActionProps): import("react").JSX.Element;
|
|
54
|
+
export interface AlertDialogCancelProps extends AlertDialogPrimitive.Close.Props {
|
|
55
|
+
variant?: ButtonVariant | null;
|
|
56
|
+
size?: ButtonSize | null;
|
|
57
|
+
}
|
|
58
|
+
/** Closes the dialog. An outline button unless `variant` says otherwise. */
|
|
59
|
+
export declare function AlertDialogCancel({ variant, size, ...props }: AlertDialogCancelProps): import("react").JSX.Element;
|
|
60
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { AlertDialog as AlertDialogPrimitive } from "@base-ui/react/alert-dialog";
|
|
4
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
5
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
6
|
+
import { cn, stateClassName } from "../internal/classes.js";
|
|
7
|
+
import { Button, } from "./button.js";
|
|
8
|
+
export const alertDialogSizeNames = ["default", "sm"];
|
|
9
|
+
export function AlertDialog(props) {
|
|
10
|
+
return _jsx(AlertDialogPrimitive.Root, { "data-slot": "alert-dialog", ...props });
|
|
11
|
+
}
|
|
12
|
+
export function AlertDialogTrigger(props) {
|
|
13
|
+
return (_jsx(AlertDialogPrimitive.Trigger, { "data-slot": "alert-dialog-trigger", ...props }));
|
|
14
|
+
}
|
|
15
|
+
export function AlertDialogPortal(props) {
|
|
16
|
+
return (_jsx(AlertDialogPrimitive.Portal, { "data-slot": "alert-dialog-portal", ...props }));
|
|
17
|
+
}
|
|
18
|
+
export function AlertDialogOverlay({ className, ...props }) {
|
|
19
|
+
return (_jsx(AlertDialogPrimitive.Backdrop, { "data-slot": "alert-dialog-overlay", ...props, className: stateClassName("sprout-alert-dialog-overlay", className) }));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The alert dialog surface. It renders its own portal and overlay, so place
|
|
23
|
+
* it directly inside `AlertDialog`.
|
|
24
|
+
*/
|
|
25
|
+
export function AlertDialogContent({ className, size = "default", container, ...props }) {
|
|
26
|
+
return (_jsxs(AlertDialogPortal, { container: container, children: [_jsx(AlertDialogOverlay, {}), _jsx(AlertDialogPrimitive.Popup, { "data-slot": "alert-dialog-content", "data-size": size, ...props, className: stateClassName("sprout-alert-dialog-content", className) })] }));
|
|
27
|
+
}
|
|
28
|
+
function part(slot, base) {
|
|
29
|
+
return function AlertDialogPart({ className, render, ref, ...props }) {
|
|
30
|
+
return useRender({
|
|
31
|
+
defaultTagName: "div",
|
|
32
|
+
ref,
|
|
33
|
+
render,
|
|
34
|
+
props: mergeProps({ "data-slot": slot, className: cn(base, className) }, props),
|
|
35
|
+
state: { slot },
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Groups media, title, and description. Centered on narrow screens and in
|
|
41
|
+
* `sm` dialogs; from 640px a `default` dialog aligns it to the start with the
|
|
42
|
+
* media beside the text.
|
|
43
|
+
*/
|
|
44
|
+
export const AlertDialogHeader = part("alert-dialog-header", "sprout-alert-dialog-header");
|
|
45
|
+
/**
|
|
46
|
+
* A tinted action bar pinned to the bottom edge. Actions stack in reverse
|
|
47
|
+
* order on narrow screens and align right from 640px; `sm` dialogs always
|
|
48
|
+
* split it into two equal columns.
|
|
49
|
+
*/
|
|
50
|
+
export const AlertDialogFooter = part("alert-dialog-footer", "sprout-alert-dialog-footer");
|
|
51
|
+
/** A 40px tile for an icon above or beside the title. */
|
|
52
|
+
export const AlertDialogMedia = part("alert-dialog-media", "sprout-alert-dialog-media");
|
|
53
|
+
export function AlertDialogTitle({ className, ...props }) {
|
|
54
|
+
return (_jsx(AlertDialogPrimitive.Title, { "data-slot": "alert-dialog-title", ...props, className: stateClassName("sprout-alert-dialog-title", className) }));
|
|
55
|
+
}
|
|
56
|
+
export function AlertDialogDescription({ className, ...props }) {
|
|
57
|
+
return (_jsx(AlertDialogPrimitive.Description, { "data-slot": "alert-dialog-description", ...props, className: stateClassName("sprout-alert-dialog-description", className) }));
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The confirming button. It does not close the dialog by itself, so the
|
|
61
|
+
* caller can keep it open while work is pending and close it on success.
|
|
62
|
+
*/
|
|
63
|
+
export function AlertDialogAction(props) {
|
|
64
|
+
return _jsx(Button, { "data-slot": "alert-dialog-action", ...props });
|
|
65
|
+
}
|
|
66
|
+
/** Closes the dialog. An outline button unless `variant` says otherwise. */
|
|
67
|
+
export function AlertDialogCancel({ variant = "outline", size = "default", ...props }) {
|
|
68
|
+
return (_jsx(AlertDialogPrimitive.Close, { "data-slot": "alert-dialog-cancel", render: _jsx(Button, { variant: variant, size: size }), ...props }));
|
|
69
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
2
|
+
export declare const alertVariantNames: readonly ["default", "destructive"];
|
|
3
|
+
export type AlertVariant = (typeof alertVariantNames)[number];
|
|
4
|
+
export interface AlertVariantOptions {
|
|
5
|
+
variant?: AlertVariant | null;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function alertVariants({ variant, className, }?: AlertVariantOptions): string;
|
|
9
|
+
export interface AlertState extends Record<string, unknown> {
|
|
10
|
+
slot: "alert";
|
|
11
|
+
variant: AlertVariant;
|
|
12
|
+
}
|
|
13
|
+
export interface AlertProps extends useRender.ComponentProps<"div", AlertState> {
|
|
14
|
+
variant?: AlertVariant;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A static message block. It announces itself with `role="alert"` by default;
|
|
18
|
+
* pass `role="status"` or `role="note"` for messages that should not interrupt.
|
|
19
|
+
*/
|
|
20
|
+
export declare function Alert({ className, variant, render, ref, role, ...props }: AlertProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
21
|
+
type PartSlot = "alert-title" | "alert-description" | "alert-action";
|
|
22
|
+
export interface AlertPartState extends Record<string, unknown> {
|
|
23
|
+
slot: PartSlot;
|
|
24
|
+
}
|
|
25
|
+
export type AlertPartProps = useRender.ComponentProps<"div", AlertPartState>;
|
|
26
|
+
export declare const AlertTitle: ({ className, render, ref, ...props }: AlertPartProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
27
|
+
export declare const AlertDescription: ({ className, render, ref, ...props }: AlertPartProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
28
|
+
/** Pins a compact control, such as an Undo button, to the top-right corner. */
|
|
29
|
+
export declare const AlertAction: ({ className, render, ref, ...props }: AlertPartProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
2
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
3
|
+
import { cn } from "../internal/classes.js";
|
|
4
|
+
export const alertVariantNames = ["default", "destructive"];
|
|
5
|
+
export function alertVariants({ variant, className, } = {}) {
|
|
6
|
+
return cn("sprout-alert", `sprout-alert-${variant ?? "default"}`, className);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A static message block. It announces itself with `role="alert"` by default;
|
|
10
|
+
* pass `role="status"` or `role="note"` for messages that should not interrupt.
|
|
11
|
+
*/
|
|
12
|
+
export function Alert({ className, variant = "default", render, ref, role = "alert", ...props }) {
|
|
13
|
+
return useRender({
|
|
14
|
+
defaultTagName: "div",
|
|
15
|
+
ref,
|
|
16
|
+
render,
|
|
17
|
+
props: mergeProps({ role, className: alertVariants({ variant, className }) }, props),
|
|
18
|
+
state: { slot: "alert", variant },
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function part(slot, base) {
|
|
22
|
+
return function AlertPart({ className, render, ref, ...props }) {
|
|
23
|
+
return useRender({
|
|
24
|
+
defaultTagName: "div",
|
|
25
|
+
ref,
|
|
26
|
+
render,
|
|
27
|
+
props: mergeProps({ className: cn(base, className) }, props),
|
|
28
|
+
state: { slot },
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export const AlertTitle = part("alert-title", "sprout-alert-title");
|
|
33
|
+
export const AlertDescription = part("alert-description", "sprout-alert-description");
|
|
34
|
+
/** Pins a compact control, such as an Undo button, to the top-right corner. */
|
|
35
|
+
export const AlertAction = part("alert-action", "sprout-alert-action");
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ComponentProps } from "react";
|
|
2
|
+
export interface AspectRatioProps extends ComponentProps<"div"> {
|
|
3
|
+
/** Width divided by height, such as `16 / 9`, `4 / 3`, or `1`. */
|
|
4
|
+
ratio: number;
|
|
5
|
+
}
|
|
6
|
+
/** Keeps its content at a fixed width-to-height ratio as its width changes. */
|
|
7
|
+
export declare function AspectRatio({ ratio, className, style, ...props }: AspectRatioProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../internal/classes.js";
|
|
3
|
+
/** Keeps its content at a fixed width-to-height ratio as its width changes. */
|
|
4
|
+
export function AspectRatio({ ratio, className, style, ...props }) {
|
|
5
|
+
return (_jsx("div", { "data-slot": "aspect-ratio", className: cn("sprout-aspect-ratio", className), style: { ...style, "--sprout-aspect-ratio": ratio }, ...props }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { type ComponentProps, type ReactElement } from "react";
|
|
2
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
3
|
+
import { type FileKind } from "../internal/file-kind.js";
|
|
4
|
+
import { type ButtonProps } from "./button.js";
|
|
5
|
+
export declare const attachmentStateNames: readonly ["idle", "uploading", "processing", "error", "done"];
|
|
6
|
+
export declare const attachmentSizeNames: readonly ["default", "sm", "xs"];
|
|
7
|
+
export declare const attachmentOrientationNames: readonly ["horizontal", "vertical"];
|
|
8
|
+
export declare const attachmentMediaVariantNames: readonly ["icon", "image"];
|
|
9
|
+
export declare const attachmentGroupVariantNames: readonly ["carousel", "grid", "inline", "list"];
|
|
10
|
+
export declare const fileAttachmentVariantNames: readonly ["list", "grid", "inline", "chip"];
|
|
11
|
+
export declare const fileAttachmentStateNames: readonly ["ready", "uploading", "processing", "error"];
|
|
12
|
+
export declare const fileTypeIconSizeNames: readonly ["sm", "lg"];
|
|
13
|
+
export type AttachmentState = (typeof attachmentStateNames)[number];
|
|
14
|
+
export type AttachmentSize = (typeof attachmentSizeNames)[number];
|
|
15
|
+
export type AttachmentOrientation = (typeof attachmentOrientationNames)[number];
|
|
16
|
+
export type AttachmentMediaVariant = (typeof attachmentMediaVariantNames)[number];
|
|
17
|
+
export type AttachmentGroupVariant = (typeof attachmentGroupVariantNames)[number];
|
|
18
|
+
export type FileAttachmentVariant = (typeof fileAttachmentVariantNames)[number];
|
|
19
|
+
export type FileAttachmentState = (typeof fileAttachmentStateNames)[number];
|
|
20
|
+
export type FileTypeIconSize = (typeof fileTypeIconSizeNames)[number];
|
|
21
|
+
export type { FileKind };
|
|
22
|
+
export interface AttachmentProps extends ComponentProps<"div"> {
|
|
23
|
+
/** `idle` dashes the border, `uploading` and `processing` shimmer the title and dim image media, `error` turns it red. */
|
|
24
|
+
state?: AttachmentState | undefined;
|
|
25
|
+
size?: AttachmentSize | undefined;
|
|
26
|
+
orientation?: AttachmentOrientation | undefined;
|
|
27
|
+
}
|
|
28
|
+
/** A file card built from media, content, and actions. */
|
|
29
|
+
export declare function Attachment({ className, state, size, orientation, ...props }: AttachmentProps): import("react").JSX.Element;
|
|
30
|
+
export interface AttachmentMediaProps extends ComponentProps<"div"> {
|
|
31
|
+
/** `icon` centers an icon or spinner; `image` crops an `img` to the square. */
|
|
32
|
+
variant?: AttachmentMediaVariant | undefined;
|
|
33
|
+
}
|
|
34
|
+
export declare function AttachmentMedia({ className, variant, ...props }: AttachmentMediaProps): import("react").JSX.Element;
|
|
35
|
+
export declare function AttachmentContent({ className, ...props }: ComponentProps<"div">): import("react").JSX.Element;
|
|
36
|
+
/** A single-line name. It shimmers while the attachment uploads or processes. */
|
|
37
|
+
export declare function AttachmentTitle({ className, ...props }: ComponentProps<"span">): import("react").JSX.Element;
|
|
38
|
+
export declare function AttachmentDescription({ className, ...props }: ComponentProps<"span">): import("react").JSX.Element;
|
|
39
|
+
/** Sits above the trigger. Vertical attachments float it over the media corner. */
|
|
40
|
+
export declare function AttachmentActions({ className, ...props }: ComponentProps<"div">): import("react").JSX.Element;
|
|
41
|
+
/** A ghost `icon-xs` Button. Give icon-only actions an `aria-label`. */
|
|
42
|
+
export declare function AttachmentAction({ variant, size, ...props }: ButtonProps): import("react").JSX.Element;
|
|
43
|
+
export type AttachmentTriggerProps = useRender.ComponentProps<"button">;
|
|
44
|
+
/** Stretches over the whole attachment so a click anywhere opens it. Name it with `aria-label`. */
|
|
45
|
+
export declare function AttachmentTrigger({ className, render, type, ...props }: AttachmentTriggerProps): ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
46
|
+
export interface AttachmentGroupProps extends ComponentProps<"div"> {
|
|
47
|
+
/**
|
|
48
|
+
* `carousel` scrolls one row sideways with edge arrows, `grid` makes two
|
|
49
|
+
* columns (three from 640px), `inline` wraps, and `list` stacks.
|
|
50
|
+
*/
|
|
51
|
+
variant?: AttachmentGroupVariant | undefined;
|
|
52
|
+
}
|
|
53
|
+
export declare function AttachmentGroup(props: AttachmentGroupProps): import("react").JSX.Element;
|
|
54
|
+
export interface FileTypeIconProps extends Omit<ComponentProps<"svg">, "children"> {
|
|
55
|
+
name: string;
|
|
56
|
+
mediaType: string;
|
|
57
|
+
/** `sm` is 20 × 24px for rows and chips; `lg` is 30 × 36px for grid previews. */
|
|
58
|
+
size?: FileTypeIconSize | undefined;
|
|
59
|
+
}
|
|
60
|
+
/** A paper glyph with a colored extension badge, such as PDF or XLSX. Decorative. */
|
|
61
|
+
export declare function FileTypeIcon({ name, mediaType, size, className, ...props }: FileTypeIconProps): import("react").JSX.Element;
|
|
62
|
+
export type AttachmentFileSource = {
|
|
63
|
+
kind: "local";
|
|
64
|
+
file: File;
|
|
65
|
+
} | {
|
|
66
|
+
kind: "remote";
|
|
67
|
+
url: string;
|
|
68
|
+
};
|
|
69
|
+
export interface AttachmentFile {
|
|
70
|
+
id: string;
|
|
71
|
+
name: string;
|
|
72
|
+
mediaType: string;
|
|
73
|
+
/** A formatted size or a short source line, such as “48 KB” or “Google Drive”. */
|
|
74
|
+
size: string;
|
|
75
|
+
/** An image preview URL. */
|
|
76
|
+
url?: string | undefined;
|
|
77
|
+
source?: AttachmentFileSource | undefined;
|
|
78
|
+
state: FileAttachmentState;
|
|
79
|
+
}
|
|
80
|
+
export interface FileAttachmentProps {
|
|
81
|
+
file: AttachmentFile;
|
|
82
|
+
variant?: FileAttachmentVariant | undefined;
|
|
83
|
+
onRemove?: (() => void) | undefined;
|
|
84
|
+
onRetry?: (() => void) | undefined;
|
|
85
|
+
/** Opens the file your own way, instead of `viewable`. Disabled while the file uploads or processes. */
|
|
86
|
+
onOpen?: (() => void) | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Opens the file in the full-screen `FileViewer` on click. Needs a
|
|
89
|
+
* `source` or `url`. Wrap the app in `FileRenderersProvider` to view
|
|
90
|
+
* sheets, Office files, and formatted Markdown.
|
|
91
|
+
*/
|
|
92
|
+
viewable?: boolean | undefined;
|
|
93
|
+
/** Peeks at images, text, code, JSON, and Markdown in a card on hover or focus. Needs a `source` or `url`. */
|
|
94
|
+
preview?: boolean | undefined;
|
|
95
|
+
/** The verb in the open button's name, such as “Download report.pdf”. */
|
|
96
|
+
actionLabel?: "Inspect" | "Download" | undefined;
|
|
97
|
+
className?: string | undefined;
|
|
98
|
+
}
|
|
99
|
+
/** A ready-made file row, card, inline mention, or chip with upload states, retry, and remove. */
|
|
100
|
+
export declare function FileAttachment({ file, variant, onRemove, onRetry, onOpen, viewable, preview, actionLabel, className, }: FileAttachmentProps): import("react").JSX.Element;
|
|
101
|
+
export interface AttachmentDropzoneProps {
|
|
102
|
+
onFiles: (files: File[]) => void;
|
|
103
|
+
disabled?: boolean | undefined;
|
|
104
|
+
/** File types the picker offers. Defaults to documents, sheets, slides, PDF, text, Google shortcuts, and images. */
|
|
105
|
+
accept?: string | undefined;
|
|
106
|
+
className?: string | undefined;
|
|
107
|
+
}
|
|
108
|
+
/** A dashed drop target with a “Choose files” button. Files are handed to `onFiles`; nothing is uploaded. */
|
|
109
|
+
export declare function AttachmentDropzone({ onFiles, disabled, accept, className, }: AttachmentDropzoneProps): import("react").JSX.Element;
|
|
110
|
+
export interface LocalFileAttachmentProps {
|
|
111
|
+
file: File;
|
|
112
|
+
onRemove?: (() => void) | undefined;
|
|
113
|
+
onOpen?: (() => void) | undefined;
|
|
114
|
+
viewable?: boolean | undefined;
|
|
115
|
+
preview?: boolean | undefined;
|
|
116
|
+
}
|
|
117
|
+
/** A chip for a `File` still in browser memory, with a live image preview. */
|
|
118
|
+
export declare function LocalFileAttachment({ file, onRemove, onOpen, viewable, preview, }: LocalFileAttachmentProps): import("react").JSX.Element;
|