@latte-macchiat-io/latte-vanilla-components 0.0.185 → 0.0.187
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/README.md +286 -10
- package/package.json +8 -11
- package/src/components/Button/stories.tsx +261 -0
- package/src/components/Footer/stories.tsx +1 -1
- package/src/components/Header/stories.tsx +1 -1
- package/src/components/Logo/stories.tsx +2 -1
- package/src/components/Modal/stories.tsx +409 -0
- package/src/components/Nav/stories.tsx +1 -1
- package/src/components/NavLegal/stories.tsx +1 -1
- package/src/components/Section/stories.tsx +345 -0
- package/src/index.ts +10 -10
- package/src/components/Actions/stories.tsx +0 -34
- package/src/components/ConsentCookie/stories.tsx +0 -28
- package/src/components/Form/Row/stories.tsx +0 -41
- package/src/components/Form/TextField/Textarea/stories.tsx +0 -44
- package/src/components/NavSocial/stories.tsx +0 -33
- package/src/themes/default.css.ts +0 -20
- package/src/utils/createCustomTheme.ts +0 -52
- package/src/utils/themeOverrides.ts +0 -10
package/README.md
CHANGED
@@ -1,22 +1,298 @@
|
|
1
|
-
#
|
1
|
+
# 🥤 Latte Vanilla Components
|
2
2
|
|
3
|
-
Beautiful components
|
3
|
+
Beautiful, type-safe React components powered by Vanilla Extract CSS. Build modern interfaces with a professional design system that's both powerful and easy to use.
|
4
4
|
|
5
|
-
##
|
5
|
+
## ✨ Features
|
6
6
|
|
7
|
-
|
7
|
+
- 🎨 **Professional Theme System** - Light/dark themes with full customization
|
8
|
+
- 🚀 **Zero Runtime CSS-in-JS** - Vanilla Extract for optimal performance
|
9
|
+
- 📱 **Responsive Design** - Mobile-first, accessible components
|
10
|
+
- 🔒 **Type Safety** - Full TypeScript support throughout
|
11
|
+
- ⚡ **Developer Experience** - Hot reloading, IntelliSense, great docs
|
12
|
+
- 🎯 **Production Ready** - Optimized builds, minimal bundle size
|
8
13
|
|
9
|
-
##
|
14
|
+
## 📦 Installation
|
10
15
|
|
11
16
|
```bash
|
12
|
-
|
17
|
+
npm install @latte-macchiat-io/latte-vanilla-components
|
18
|
+
# or
|
19
|
+
pnpm add @latte-macchiat-io/latte-vanilla-components
|
20
|
+
# or
|
21
|
+
yarn add @latte-macchiat-io/latte-vanilla-components
|
22
|
+
```
|
23
|
+
|
24
|
+
## 🚀 Quick Start
|
25
|
+
|
26
|
+
### 1. Set up your theme (choose one approach):
|
27
|
+
|
28
|
+
**Option A: Zero Config (Quickest)**
|
29
|
+
|
30
|
+
```typescript
|
31
|
+
// src/styles/theme.css.ts
|
32
|
+
import { quickTheme } from '@latte-macchiat-io/latte-vanilla-components';
|
33
|
+
export { quickTheme };
|
34
|
+
```
|
35
|
+
|
36
|
+
**Option B: Brand Colors**
|
37
|
+
|
38
|
+
```typescript
|
39
|
+
// src/styles/theme.css.ts
|
40
|
+
import { createQuickTheme } from '@latte-macchiat-io/latte-vanilla-components';
|
41
|
+
|
42
|
+
export const myTheme = createQuickTheme({
|
43
|
+
colors: {
|
44
|
+
primary: '#FF7377', // Your brand color
|
45
|
+
secondary: '#FCEFE6', // Secondary brand color
|
46
|
+
},
|
47
|
+
});
|
48
|
+
```
|
49
|
+
|
50
|
+
**Option C: Professional Custom Theme**
|
51
|
+
|
52
|
+
```typescript
|
53
|
+
// src/styles/theme.css.ts
|
54
|
+
import { createGlobalTheme } from '@vanilla-extract/css';
|
55
|
+
import { themeContract } from '@latte-macchiat-io/latte-vanilla-components';
|
56
|
+
|
57
|
+
export const lightTheme = createGlobalTheme(':root', themeContract, {
|
58
|
+
colors: {
|
59
|
+
primary: '#FF7377',
|
60
|
+
background: '#ffffff',
|
61
|
+
text: '#000000',
|
62
|
+
// ... define all colors
|
63
|
+
},
|
64
|
+
space: {
|
65
|
+
xs: '4px',
|
66
|
+
sm: '8px',
|
67
|
+
md: '16px',
|
68
|
+
// ... define all spacing
|
69
|
+
},
|
70
|
+
// ... define all theme properties
|
71
|
+
});
|
72
|
+
|
73
|
+
export const darkTheme = createGlobalTheme('html[data-theme="dark"]', themeContract, {
|
74
|
+
colors: {
|
75
|
+
primary: '#FF7377',
|
76
|
+
background: '#1a1a1a',
|
77
|
+
text: '#ffffff',
|
78
|
+
// ... dark theme colors
|
79
|
+
},
|
80
|
+
// ... same structure as light theme
|
81
|
+
});
|
82
|
+
```
|
83
|
+
|
84
|
+
### 2. Import your theme:
|
85
|
+
|
86
|
+
```typescript
|
87
|
+
// src/app/layout.tsx (Next.js)
|
88
|
+
import '../styles/theme.css';
|
89
|
+
|
90
|
+
// src/main.tsx (Vite)
|
91
|
+
import './styles/theme.css';
|
92
|
+
```
|
93
|
+
|
94
|
+
### 3. Start using components:
|
95
|
+
|
96
|
+
```tsx
|
97
|
+
import { Button, Section, Header, Modal } from '@latte-macchiat-io/latte-vanilla-components';
|
98
|
+
|
99
|
+
export default function App() {
|
100
|
+
return (
|
101
|
+
<Section>
|
102
|
+
<Header>
|
103
|
+
<h1>My App</h1>
|
104
|
+
</Header>
|
105
|
+
|
106
|
+
<Button variant="primary" size="large">
|
107
|
+
Get Started
|
108
|
+
</Button>
|
109
|
+
|
110
|
+
<Modal>
|
111
|
+
<p>Beautiful, accessible modal content!</p>
|
112
|
+
</Modal>
|
113
|
+
</Section>
|
114
|
+
);
|
115
|
+
}
|
116
|
+
```
|
117
|
+
|
118
|
+
## 🎨 Theme Customization
|
119
|
+
|
120
|
+
### Available Theme Properties
|
121
|
+
|
122
|
+
```typescript
|
123
|
+
{
|
124
|
+
colors: {
|
125
|
+
primary, secondary, accent, background, surface, text,
|
126
|
+
textSecondary, textLight, border, error, warning, success, info
|
127
|
+
},
|
128
|
+
space: { none, xs, sm, md, lg, xl, '2xl' }, // 0px to 128px
|
129
|
+
radii: { none, sm, md, lg, xl, full }, // Border radius
|
130
|
+
fonts: { body, heading, mono }, // Font families
|
131
|
+
fontSizes: { xs, sm, md, lg, xl, '2xl', '3xl', '4xl' }, // 12px to 40px
|
132
|
+
fontWeights: { light, normal, medium, semibold, bold },
|
133
|
+
lineHeights: { tight, normal, relaxed },
|
134
|
+
shadows: { none, sm, md, lg, xl }, // Box shadows
|
135
|
+
maxWidth: string, // Container width
|
136
|
+
section: { paddingTop, paddingBottom }, // Section spacing
|
137
|
+
header: { height }, // Header height
|
138
|
+
footer: { height }, // Footer height
|
139
|
+
}
|
140
|
+
```
|
141
|
+
|
142
|
+
### Theme Switching
|
143
|
+
|
144
|
+
Add dark mode support:
|
145
|
+
|
146
|
+
```tsx
|
147
|
+
import { setTheme, toggleTheme } from '@latte-macchiat-io/latte-vanilla-components';
|
148
|
+
|
149
|
+
function ThemeToggle() {
|
150
|
+
return <button onClick={() => toggleTheme()}>Toggle Dark Mode</button>;
|
151
|
+
}
|
152
|
+
|
153
|
+
// Or set specific theme
|
154
|
+
setTheme('dark'); // Switch to dark
|
155
|
+
setTheme('light'); // Switch to light
|
156
|
+
```
|
157
|
+
|
158
|
+
## 🧩 Available Components
|
159
|
+
|
160
|
+
### Layout Components
|
161
|
+
|
162
|
+
- **Section** - Content sections with consistent spacing
|
163
|
+
- **Header** - App headers with navigation support
|
164
|
+
- **Footer** - App footers with links and info
|
165
|
+
- **Main** - Main content areas
|
166
|
+
- **Columns** - Responsive column layouts
|
167
|
+
|
168
|
+
### Interactive Components
|
169
|
+
|
170
|
+
- **Button** - Primary, secondary, and variant buttons
|
171
|
+
- **Modal** - Accessible modals with animations
|
172
|
+
- **Form** - Complete form system with validation
|
173
|
+
- **TextField** - Text inputs with labels and validation
|
174
|
+
- **Carousel** - Image and content carousels
|
175
|
+
|
176
|
+
### Content Components
|
177
|
+
|
178
|
+
- **Video** - Responsive video players
|
179
|
+
- **VideoFullWidth** - Full-width video backgrounds
|
180
|
+
- **Logo** - Responsive logo display
|
181
|
+
- **Icon** - Icon system with multiple sizes
|
182
|
+
- **KeyNumber** - Highlight important numbers/stats
|
183
|
+
|
184
|
+
### Navigation Components
|
185
|
+
|
186
|
+
- **Nav** - Primary navigation
|
187
|
+
- **NavSocial** - Social media links
|
188
|
+
- **NavLegal** - Legal/policy links
|
189
|
+
- **LanguageSwitcher** - Multi-language support
|
190
|
+
|
191
|
+
### Utility Components
|
192
|
+
|
193
|
+
- **Actions** - Action button groups
|
194
|
+
- **ConsentCookie** - GDPR cookie consent
|
195
|
+
|
196
|
+
## 📱 Responsive Design
|
197
|
+
|
198
|
+
All components are mobile-first and responsive:
|
199
|
+
|
200
|
+
```tsx
|
201
|
+
// Responsive spacing using sprinkles
|
202
|
+
<Section className={sprinkles({
|
203
|
+
padding: { mobile: 'md', desktop: 'xl' }
|
204
|
+
})}>
|
205
|
+
Content adapts to screen size
|
206
|
+
</Section>
|
207
|
+
|
208
|
+
// Built-in responsive variants
|
209
|
+
<Button size={{ mobile: 'small', desktop: 'large' }}>
|
210
|
+
Responsive Button
|
211
|
+
</Button>
|
212
|
+
```
|
213
|
+
|
214
|
+
## 🛠 Development
|
215
|
+
|
216
|
+
### Using with Next.js
|
217
|
+
|
218
|
+
```typescript
|
219
|
+
// next.config.js
|
220
|
+
const { createVanillaExtractPlugin } = require('@vanilla-extract/next-plugin');
|
221
|
+
const withVanillaExtract = createVanillaExtractPlugin();
|
222
|
+
|
223
|
+
module.exports = withVanillaExtract({
|
224
|
+
// your config
|
225
|
+
});
|
226
|
+
```
|
227
|
+
|
228
|
+
### Using with Vite
|
229
|
+
|
230
|
+
```typescript
|
231
|
+
// vite.config.ts
|
232
|
+
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
|
233
|
+
|
234
|
+
export default {
|
235
|
+
plugins: [vanillaExtractPlugin()],
|
236
|
+
};
|
237
|
+
```
|
238
|
+
|
239
|
+
## 📚 Advanced Usage
|
240
|
+
|
241
|
+
### Custom Component Styling
|
242
|
+
|
243
|
+
```tsx
|
244
|
+
import { sprinkles } from '@latte-macchiat-io/latte-vanilla-components';
|
245
|
+
|
246
|
+
// Use the sprinkles utility for custom styling
|
247
|
+
<div
|
248
|
+
className={sprinkles({
|
249
|
+
padding: 'lg',
|
250
|
+
backgroundColor: 'primary',
|
251
|
+
borderRadius: 'md',
|
252
|
+
color: 'white',
|
253
|
+
})}>
|
254
|
+
Custom styled element
|
255
|
+
</div>;
|
256
|
+
```
|
257
|
+
|
258
|
+
### Extending Components
|
259
|
+
|
260
|
+
```tsx
|
261
|
+
// Create your own component using the theme
|
262
|
+
import { style } from '@vanilla-extract/css';
|
263
|
+
import { themeContract } from '@latte-macchiat-io/latte-vanilla-components';
|
264
|
+
|
265
|
+
const customButton = style({
|
266
|
+
backgroundColor: themeContract.colors.primary,
|
267
|
+
color: themeContract.colors.background,
|
268
|
+
padding: `${themeContract.space.md} ${themeContract.space.lg}`,
|
269
|
+
borderRadius: themeContract.radii.full,
|
270
|
+
});
|
13
271
|
```
|
14
|
-
Then open [http://localhost:6006](http://localhost:6006) in your browser.
|
15
272
|
|
16
|
-
|
273
|
+
## 🎯 Performance
|
274
|
+
|
275
|
+
- **Zero Runtime CSS-in-JS** - All styles compiled at build time
|
276
|
+
- **Atomic CSS** - Reusable utility classes reduce bundle size
|
277
|
+
- **Tree Shaking** - Only import components you use
|
278
|
+
- **Optimized Builds** - Minimal CSS output in production
|
279
|
+
|
280
|
+
---
|
281
|
+
|
282
|
+
## 🛠 Development & Contributing
|
283
|
+
|
284
|
+
### Run Storybook
|
17
285
|
|
18
286
|
```bash
|
19
|
-
pnpm
|
287
|
+
pnpm run storybook
|
20
288
|
```
|
21
289
|
|
22
|
-
|
290
|
+
Then open [http://localhost:6006](http://localhost:6006) to explore components.
|
291
|
+
|
292
|
+
### Publishing
|
293
|
+
|
294
|
+
Push changes to `main` branch and GitHub Actions will automatically publish to NPM.
|
295
|
+
|
296
|
+
---
|
297
|
+
|
298
|
+
Made with ☕ by the Latte team. Build beautiful interfaces! ✨
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@latte-macchiat-io/latte-vanilla-components",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.187",
|
4
4
|
"description": "Beautiful components for amazing projects, with a touch of Vanilla 🥤",
|
5
5
|
"type": "module",
|
6
6
|
"main": "./src/index.ts",
|
@@ -30,15 +30,11 @@
|
|
30
30
|
"react-intersection-observer": "^9.16.0"
|
31
31
|
},
|
32
32
|
"devDependencies": {
|
33
|
-
"@chromatic-com/storybook": "^
|
33
|
+
"@chromatic-com/storybook": "^4.1.1",
|
34
34
|
"@playwright/test": "^1.50.0",
|
35
|
-
"@storybook/addon-
|
36
|
-
"@storybook/addon-
|
37
|
-
"@storybook/
|
38
|
-
"@storybook/blocks": "^8.5.2",
|
39
|
-
"@storybook/react": "^8.5.2",
|
40
|
-
"@storybook/react-vite": "^8.5.2",
|
41
|
-
"@storybook/test": "^8.5.2",
|
35
|
+
"@storybook/addon-docs": "^9.1.5",
|
36
|
+
"@storybook/addon-onboarding": "^9.1.5",
|
37
|
+
"@storybook/react-vite": "^9.1.5",
|
42
38
|
"@types/node": "^20",
|
43
39
|
"@types/react": "^19",
|
44
40
|
"@types/react-dom": "^19",
|
@@ -47,14 +43,15 @@
|
|
47
43
|
"@vanilla-extract/dynamic": "^2.1.5",
|
48
44
|
"@vanilla-extract/recipes": "^0.5.7",
|
49
45
|
"@vanilla-extract/sprinkles": "^1.6.5",
|
46
|
+
"@vanilla-extract/vite-plugin": "^5.1.1",
|
50
47
|
"clsx": "^2.1.1",
|
51
48
|
"eslint": "^9.15.0",
|
52
49
|
"eslint-config-prettier": "^10.0.1",
|
53
50
|
"eslint-plugin-import": "^2.31.0",
|
54
51
|
"eslint-plugin-jsx-a11y": "^6.6.1",
|
55
|
-
"eslint-plugin-storybook": "^
|
52
|
+
"eslint-plugin-storybook": "^9.1.5",
|
56
53
|
"prettier": "^3.4.2",
|
57
|
-
"storybook": "^
|
54
|
+
"storybook": "^9.1.5",
|
58
55
|
"typescript": "5.6.3",
|
59
56
|
"typescript-eslint": "^8.21.0"
|
60
57
|
},
|
@@ -0,0 +1,261 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
3
|
+
import { Button } from './Button';
|
4
|
+
import { Section } from '../Section/Section';
|
5
|
+
|
6
|
+
const meta: Meta<typeof Button> = {
|
7
|
+
title: 'Interactive Components/Button',
|
8
|
+
component: Button,
|
9
|
+
parameters: {
|
10
|
+
layout: 'centered',
|
11
|
+
docs: {
|
12
|
+
description: {
|
13
|
+
component: `
|
14
|
+
The Button component is a versatile, accessible button that supports multiple variants, sizes, and states.
|
15
|
+
|
16
|
+
## Features
|
17
|
+
- Multiple variants (primary, secondary, ghost, destructive)
|
18
|
+
- Different sizes (small, medium, large)
|
19
|
+
- Full width option
|
20
|
+
- Loading/pending state
|
21
|
+
- Fully accessible (ARIA compliant)
|
22
|
+
- Theme-aware colors
|
23
|
+
- TypeScript support
|
24
|
+
`,
|
25
|
+
},
|
26
|
+
},
|
27
|
+
},
|
28
|
+
tags: ['autodocs'],
|
29
|
+
argTypes: {
|
30
|
+
variant: {
|
31
|
+
control: 'select',
|
32
|
+
options: ['primary', 'secondary', 'ghost', 'destructive'],
|
33
|
+
description: 'Visual style of the button',
|
34
|
+
},
|
35
|
+
size: {
|
36
|
+
control: 'select',
|
37
|
+
options: ['small', 'medium', 'large'],
|
38
|
+
description: 'Size of the button',
|
39
|
+
},
|
40
|
+
fullWidth: {
|
41
|
+
control: 'boolean',
|
42
|
+
description: 'Whether the button should take full width of its container',
|
43
|
+
},
|
44
|
+
isPending: {
|
45
|
+
control: 'boolean',
|
46
|
+
description: 'Shows loading state',
|
47
|
+
},
|
48
|
+
disabled: {
|
49
|
+
control: 'boolean',
|
50
|
+
description: 'Disables the button',
|
51
|
+
},
|
52
|
+
children: {
|
53
|
+
control: 'text',
|
54
|
+
description: 'Button content',
|
55
|
+
},
|
56
|
+
},
|
57
|
+
};
|
58
|
+
|
59
|
+
export default meta;
|
60
|
+
type Story = StoryObj<typeof Button>;
|
61
|
+
|
62
|
+
// Basic Stories
|
63
|
+
export const Primary: Story = {
|
64
|
+
args: {
|
65
|
+
variant: 'primary',
|
66
|
+
children: 'Primary Button',
|
67
|
+
},
|
68
|
+
};
|
69
|
+
|
70
|
+
export const Secondary: Story = {
|
71
|
+
args: {
|
72
|
+
variant: 'secondary',
|
73
|
+
children: 'Secondary Button',
|
74
|
+
},
|
75
|
+
};
|
76
|
+
|
77
|
+
export const Ghost: Story = {
|
78
|
+
args: {
|
79
|
+
variant: 'ghost',
|
80
|
+
children: 'Ghost Button',
|
81
|
+
},
|
82
|
+
};
|
83
|
+
|
84
|
+
export const Destructive: Story = {
|
85
|
+
args: {
|
86
|
+
variant: 'destructive',
|
87
|
+
children: 'Destructive Button',
|
88
|
+
},
|
89
|
+
};
|
90
|
+
|
91
|
+
// Size Variants
|
92
|
+
export const Small: Story = {
|
93
|
+
args: {
|
94
|
+
variant: 'primary',
|
95
|
+
size: 'small',
|
96
|
+
children: 'Small Button',
|
97
|
+
},
|
98
|
+
};
|
99
|
+
|
100
|
+
export const Medium: Story = {
|
101
|
+
args: {
|
102
|
+
variant: 'primary',
|
103
|
+
size: 'medium',
|
104
|
+
children: 'Medium Button',
|
105
|
+
},
|
106
|
+
};
|
107
|
+
|
108
|
+
export const Large: Story = {
|
109
|
+
args: {
|
110
|
+
variant: 'primary',
|
111
|
+
size: 'large',
|
112
|
+
children: 'Large Button',
|
113
|
+
},
|
114
|
+
};
|
115
|
+
|
116
|
+
// States
|
117
|
+
export const Loading: Story = {
|
118
|
+
args: {
|
119
|
+
variant: 'primary',
|
120
|
+
children: 'Loading Button',
|
121
|
+
isPending: true,
|
122
|
+
},
|
123
|
+
};
|
124
|
+
|
125
|
+
export const Disabled: Story = {
|
126
|
+
args: {
|
127
|
+
variant: 'primary',
|
128
|
+
children: 'Disabled Button',
|
129
|
+
disabled: true,
|
130
|
+
},
|
131
|
+
};
|
132
|
+
|
133
|
+
export const FullWidth: Story = {
|
134
|
+
args: {
|
135
|
+
variant: 'primary',
|
136
|
+
children: 'Full Width Button',
|
137
|
+
fullWidth: true,
|
138
|
+
},
|
139
|
+
parameters: {
|
140
|
+
layout: 'padded',
|
141
|
+
},
|
142
|
+
};
|
143
|
+
|
144
|
+
// All Variants Showcase
|
145
|
+
export const AllVariants: Story = {
|
146
|
+
render: () => (
|
147
|
+
<Section>
|
148
|
+
<div style={{ display: 'flex', gap: '1rem', flexWrap: 'wrap', alignItems: 'center' }}>
|
149
|
+
<Button variant="primary">Primary</Button>
|
150
|
+
<Button variant="secondary">Secondary</Button>
|
151
|
+
<Button variant="ghost">Ghost</Button>
|
152
|
+
<Button variant="destructive">Destructive</Button>
|
153
|
+
</div>
|
154
|
+
</Section>
|
155
|
+
),
|
156
|
+
parameters: {
|
157
|
+
docs: {
|
158
|
+
description: {
|
159
|
+
story: 'All available button variants displayed together.',
|
160
|
+
},
|
161
|
+
},
|
162
|
+
},
|
163
|
+
};
|
164
|
+
|
165
|
+
// All Sizes Showcase
|
166
|
+
export const AllSizes: Story = {
|
167
|
+
render: () => (
|
168
|
+
<Section>
|
169
|
+
<div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
|
170
|
+
<Button variant="primary" size="small">
|
171
|
+
Small
|
172
|
+
</Button>
|
173
|
+
<Button variant="primary" size="medium">
|
174
|
+
Medium
|
175
|
+
</Button>
|
176
|
+
<Button variant="primary" size="large">
|
177
|
+
Large
|
178
|
+
</Button>
|
179
|
+
</div>
|
180
|
+
</Section>
|
181
|
+
),
|
182
|
+
parameters: {
|
183
|
+
docs: {
|
184
|
+
description: {
|
185
|
+
story: 'All available button sizes displayed together.',
|
186
|
+
},
|
187
|
+
},
|
188
|
+
},
|
189
|
+
};
|
190
|
+
|
191
|
+
// Interactive Example
|
192
|
+
export const InteractiveExample: Story = {
|
193
|
+
render: () => (
|
194
|
+
<Section>
|
195
|
+
<div style={{ display: 'grid', gap: '2rem' }}>
|
196
|
+
<div>
|
197
|
+
<h3>Call to Action</h3>
|
198
|
+
<div style={{ display: 'flex', gap: '1rem' }}>
|
199
|
+
<Button variant="primary" size="large">
|
200
|
+
Get Started
|
201
|
+
</Button>
|
202
|
+
<Button variant="secondary" size="large">
|
203
|
+
Learn More
|
204
|
+
</Button>
|
205
|
+
</div>
|
206
|
+
</div>
|
207
|
+
|
208
|
+
<div>
|
209
|
+
<h3>Form Actions</h3>
|
210
|
+
<div style={{ display: 'flex', gap: '0.5rem' }}>
|
211
|
+
<Button variant="primary">Save</Button>
|
212
|
+
<Button variant="secondary">Cancel</Button>
|
213
|
+
<Button variant="destructive">Delete</Button>
|
214
|
+
</div>
|
215
|
+
</div>
|
216
|
+
|
217
|
+
<div>
|
218
|
+
<h3>Navigation</h3>
|
219
|
+
<div style={{ display: 'flex', gap: '0.5rem' }}>
|
220
|
+
<Button variant="ghost">← Back</Button>
|
221
|
+
<Button variant="ghost">Skip</Button>
|
222
|
+
<Button variant="primary">Next →</Button>
|
223
|
+
</div>
|
224
|
+
</div>
|
225
|
+
</div>
|
226
|
+
</Section>
|
227
|
+
),
|
228
|
+
parameters: {
|
229
|
+
docs: {
|
230
|
+
description: {
|
231
|
+
story: 'Real-world usage examples showing different button combinations.',
|
232
|
+
},
|
233
|
+
},
|
234
|
+
},
|
235
|
+
};
|
236
|
+
|
237
|
+
// With Custom Styling
|
238
|
+
export const WithCustomStyling: Story = {
|
239
|
+
render: () => (
|
240
|
+
<Section>
|
241
|
+
<div style={{ display: 'flex', gap: '1rem', flexDirection: 'column' }}>
|
242
|
+
<Button variant="primary" borderRadius="full" padding="lg">
|
243
|
+
Rounded Button
|
244
|
+
</Button>
|
245
|
+
<Button variant="secondary" fontSize="lg" fontWeight="bold">
|
246
|
+
Large Text Button
|
247
|
+
</Button>
|
248
|
+
<Button variant="ghost" boxShadow="lg">
|
249
|
+
Shadow Button
|
250
|
+
</Button>
|
251
|
+
</div>
|
252
|
+
</Section>
|
253
|
+
),
|
254
|
+
parameters: {
|
255
|
+
docs: {
|
256
|
+
description: {
|
257
|
+
story: 'Buttons with custom styling using sprinkles utilities.',
|
258
|
+
},
|
259
|
+
},
|
260
|
+
},
|
261
|
+
};
|