@djangocfg/ui-core 2.1.382 → 2.1.384

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.
Files changed (61) hide show
  1. package/package.json +5 -12
  2. package/src/components/boundary/boundary.story.tsx +0 -191
  3. package/src/components/data/avatar/avatar.story.tsx +0 -115
  4. package/src/components/data/badge/badge.story.tsx +0 -56
  5. package/src/components/data/calendar/calendar.story.tsx +0 -127
  6. package/src/components/data/carousel/carousel.story.tsx +0 -122
  7. package/src/components/data/progress/progress.story.tsx +0 -97
  8. package/src/components/data/table/table.story.tsx +0 -148
  9. package/src/components/data/toggle/toggle.story.tsx +0 -104
  10. package/src/components/data/toggle-group/toggle-group.story.tsx +0 -118
  11. package/src/components/feedback/alert/alert.story.tsx +0 -77
  12. package/src/components/feedback/empty/empty.story.tsx +0 -115
  13. package/src/components/feedback/preloader/preloader.story.tsx +0 -86
  14. package/src/components/feedback/spinner/spinner.story.tsx +0 -66
  15. package/src/components/forms/button/button.story.tsx +0 -116
  16. package/src/components/forms/button-download/button-download.story.tsx +0 -112
  17. package/src/components/forms/button-group/button-group.story.tsx +0 -79
  18. package/src/components/forms/checkbox/checkbox.story.tsx +0 -89
  19. package/src/components/forms/input/input.story.tsx +0 -77
  20. package/src/components/forms/input-group/input-group.story.tsx +0 -119
  21. package/src/components/forms/input-otp/input-otp.story.tsx +0 -105
  22. package/src/components/forms/label/label.story.tsx +0 -52
  23. package/src/components/forms/radio-group/radio-group.story.tsx +0 -113
  24. package/src/components/forms/slider/slider.story.tsx +0 -134
  25. package/src/components/forms/switch/switch.story.tsx +0 -98
  26. package/src/components/forms/textarea/textarea.story.tsx +0 -94
  27. package/src/components/layout/aspect-ratio/aspect-ratio.story.tsx +0 -94
  28. package/src/components/layout/card/card.story.tsx +0 -105
  29. package/src/components/layout/resizable/resizable.story.tsx +0 -119
  30. package/src/components/layout/scroll-area/scroll-area.story.tsx +0 -172
  31. package/src/components/layout/separator/separator.story.tsx +0 -69
  32. package/src/components/layout/skeleton/skeleton.story.tsx +0 -101
  33. package/src/components/navigation/accordion/accordion.story.tsx +0 -110
  34. package/src/components/navigation/collapsible/collapsible.story.tsx +0 -133
  35. package/src/components/navigation/command/command.story.tsx +0 -121
  36. package/src/components/navigation/context-menu/context-menu.story.tsx +0 -125
  37. package/src/components/navigation/dropdown-menu/dropdown-menu.story.tsx +0 -208
  38. package/src/components/navigation/menubar/menubar.story.tsx +0 -152
  39. package/src/components/navigation/navigation-menu/navigation-menu.story.tsx +0 -154
  40. package/src/components/navigation/tabs/tabs.story.tsx +0 -98
  41. package/src/components/overlay/alert-dialog/alert-dialog.story.tsx +0 -104
  42. package/src/components/overlay/dialog/dialog.story.tsx +0 -212
  43. package/src/components/overlay/drawer/drawer.story.tsx +0 -359
  44. package/src/components/overlay/hover-card/hover-card.story.tsx +0 -102
  45. package/src/components/overlay/popover/popover.story.tsx +0 -127
  46. package/src/components/overlay/responsive-sheet/responsive-sheet.story.tsx +0 -117
  47. package/src/components/overlay/sheet/sheet.story.tsx +0 -148
  48. package/src/components/overlay/tooltip/tooltip.story.tsx +0 -139
  49. package/src/components/select/combobox-async.story.tsx +0 -215
  50. package/src/components/select/combobox.story.tsx +0 -226
  51. package/src/components/select/country-select.story.tsx +0 -261
  52. package/src/components/select/language-select.story.tsx +0 -264
  53. package/src/components/select/multi-select.story.tsx +0 -122
  54. package/src/components/select/select.story.tsx +0 -112
  55. package/src/components/specialized/copy/copy.story.tsx +0 -77
  56. package/src/components/specialized/flag/flag.story.tsx +0 -82
  57. package/src/components/specialized/image-with-fallback/image-with-fallback.story.tsx +0 -105
  58. package/src/components/specialized/kbd/kbd.story.tsx +0 -113
  59. package/src/lib/dialog-service/dialog-service.story.tsx +0 -263
  60. package/src/stories/index.ts +0 -28
  61. package/src/styles/theme/theme-tokens.story.tsx +0 -157
@@ -1,105 +0,0 @@
1
- import { defineStory, useSelect } from '@djangocfg/playground';
2
- import { ImageWithFallback } from '.';
3
-
4
- export default defineStory({
5
- title: 'Core/ImageWithFallback',
6
- component: ImageWithFallback,
7
- description: 'Image component with loading states and fallbacks.',
8
- });
9
-
10
- export const Interactive = () => {
11
- const [fallbackIcon] = useSelect('fallbackIcon', {
12
- options: ['car', 'image', 'user', 'package', 'location'] as const,
13
- defaultValue: 'image',
14
- label: 'Fallback Icon',
15
- description: 'Icon shown on error or missing src',
16
- });
17
-
18
- return (
19
- <ImageWithFallback
20
- src="https://images.unsplash.com/photo-1494976388531-d1058494cdd8?w=400"
21
- alt="Car"
22
- fallbackIcon={fallbackIcon}
23
- className="h-48 w-72 rounded-lg"
24
- />
25
- );
26
- };
27
-
28
- export const Default = () => (
29
- <ImageWithFallback
30
- src="https://images.unsplash.com/photo-1494976388531-d1058494cdd8?w=400"
31
- alt="Car"
32
- className="h-48 w-72 rounded-lg"
33
- />
34
- );
35
-
36
- export const WithFallbackCar = () => (
37
- <ImageWithFallback
38
- src=""
39
- alt="Missing car image"
40
- fallbackIcon="car"
41
- className="h-48 w-72 rounded-lg"
42
- />
43
- );
44
-
45
- export const WithFallbackUser = () => (
46
- <ImageWithFallback
47
- src=""
48
- alt="Missing user avatar"
49
- fallbackIcon="user"
50
- className="h-24 w-24 rounded-full"
51
- />
52
- );
53
-
54
- export const WithFallbackLocation = () => (
55
- <ImageWithFallback
56
- src=""
57
- alt="Missing location"
58
- fallbackIcon="location"
59
- className="h-32 w-32 rounded-lg"
60
- />
61
- );
62
-
63
- export const BrokenImage = () => (
64
- <ImageWithFallback
65
- src="https://invalid-url-that-does-not-exist.com/image.jpg"
66
- alt="Broken image"
67
- fallbackIcon="image"
68
- className="h-48 w-72 rounded-lg"
69
- />
70
- );
71
-
72
- export const CustomFallback = () => (
73
- <ImageWithFallback
74
- src=""
75
- alt="Custom fallback"
76
- fallbackContent={
77
- <div className="flex flex-col items-center gap-2 text-muted-foreground">
78
- <span className="text-4xl">🚗</span>
79
- <span className="text-sm">No image available</span>
80
- </div>
81
- }
82
- className="h-48 w-72 rounded-lg border bg-muted/20"
83
- />
84
- );
85
-
86
- export const Gallery = () => (
87
- <div className="grid grid-cols-3 gap-4">
88
- <ImageWithFallback
89
- src="https://images.unsplash.com/photo-1494976388531-d1058494cdd8?w=200"
90
- alt="Car 1"
91
- className="h-32 w-full rounded-lg"
92
- />
93
- <ImageWithFallback
94
- src=""
95
- alt="Missing"
96
- fallbackIcon="car"
97
- className="h-32 w-full rounded-lg"
98
- />
99
- <ImageWithFallback
100
- src="https://images.unsplash.com/photo-1503376780353-7e6692767b70?w=200"
101
- alt="Car 2"
102
- className="h-32 w-full rounded-lg"
103
- />
104
- </div>
105
- );
@@ -1,113 +0,0 @@
1
- import { defineStory, useSelect } from '@djangocfg/playground';
2
- import { Kbd, KbdGroup } from '.';
3
-
4
- export default defineStory({
5
- title: 'Core/Kbd',
6
- component: Kbd,
7
- description: 'Keyboard key indicator for shortcuts.',
8
- });
9
-
10
- export const Interactive = () => {
11
- const [size] = useSelect('size', {
12
- options: ['xs', 'sm', 'default', 'lg'] as const,
13
- defaultValue: 'default',
14
- label: 'Size',
15
- description: 'Kbd size',
16
- });
17
-
18
- return <Kbd size={size}>⌘</Kbd>;
19
- };
20
-
21
- export const Default = () => <Kbd>⌘</Kbd>;
22
-
23
- export const Sizes = () => (
24
- <div className="flex items-center gap-4">
25
- <Kbd size="xs">⌘</Kbd>
26
- <Kbd size="sm">⌘</Kbd>
27
- <Kbd size="default">⌘</Kbd>
28
- <Kbd size="lg">⌘</Kbd>
29
- </div>
30
- );
31
-
32
- export const Shortcuts = () => (
33
- <div className="space-y-4">
34
- <div className="flex items-center gap-2">
35
- <span className="text-sm w-32">Copy</span>
36
- <KbdGroup>
37
- <Kbd>⌘</Kbd>
38
- <Kbd>C</Kbd>
39
- </KbdGroup>
40
- </div>
41
- <div className="flex items-center gap-2">
42
- <span className="text-sm w-32">Paste</span>
43
- <KbdGroup>
44
- <Kbd>⌘</Kbd>
45
- <Kbd>V</Kbd>
46
- </KbdGroup>
47
- </div>
48
- <div className="flex items-center gap-2">
49
- <span className="text-sm w-32">Undo</span>
50
- <KbdGroup>
51
- <Kbd>⌘</Kbd>
52
- <Kbd>Z</Kbd>
53
- </KbdGroup>
54
- </div>
55
- <div className="flex items-center gap-2">
56
- <span className="text-sm w-32">Save</span>
57
- <KbdGroup>
58
- <Kbd>⌘</Kbd>
59
- <Kbd>S</Kbd>
60
- </KbdGroup>
61
- </div>
62
- </div>
63
- );
64
-
65
- export const ComplexShortcuts = () => (
66
- <div className="space-y-4">
67
- <div className="flex items-center gap-2">
68
- <span className="text-sm w-40">Command Palette</span>
69
- <KbdGroup>
70
- <Kbd>⌘</Kbd>
71
- <Kbd>⇧</Kbd>
72
- <Kbd>P</Kbd>
73
- </KbdGroup>
74
- </div>
75
- <div className="flex items-center gap-2">
76
- <span className="text-sm w-40">Go to Definition</span>
77
- <KbdGroup>
78
- <Kbd>⌘</Kbd>
79
- <Kbd>Click</Kbd>
80
- </KbdGroup>
81
- </div>
82
- <div className="flex items-center gap-2">
83
- <span className="text-sm w-40">Toggle Sidebar</span>
84
- <KbdGroup>
85
- <Kbd>⌘</Kbd>
86
- <Kbd>B</Kbd>
87
- </KbdGroup>
88
- </div>
89
- </div>
90
- );
91
-
92
- export const Keys = () => (
93
- <div className="flex flex-wrap gap-2">
94
- <Kbd>⌘</Kbd>
95
- <Kbd>⌥</Kbd>
96
- <Kbd>⇧</Kbd>
97
- <Kbd>⌃</Kbd>
98
- <Kbd>⏎</Kbd>
99
- <Kbd>⌫</Kbd>
100
- <Kbd>⇥</Kbd>
101
- <Kbd>⎋</Kbd>
102
- <Kbd>↑</Kbd>
103
- <Kbd>↓</Kbd>
104
- <Kbd>←</Kbd>
105
- <Kbd>→</Kbd>
106
- </div>
107
- );
108
-
109
- export const InText = () => (
110
- <p className="text-sm text-muted-foreground">
111
- Press <Kbd size="sm">⌘</Kbd> + <Kbd size="sm">K</Kbd> to open the command palette.
112
- </p>
113
- );
@@ -1,263 +0,0 @@
1
- import { useCallback } from 'react';
2
- import { defineStory } from '@djangocfg/playground';
3
- import { Button } from '../../components/forms/button';
4
- import { DialogProvider } from './DialogProvider';
5
- import { useDialog } from './hooks';
6
-
7
- export default defineStory({
8
- title: 'Lib/DialogService',
9
- component: DialogProvider,
10
- description: 'Global dialog service for alert, confirm, and prompt dialogs. Uses CustomEvents to work from anywhere in the app. Supports i18n and keyboard shortcuts.',
11
- });
12
-
13
- // Wrapper component to provide DialogProvider context
14
- function StoryWrapper({ children }: { children: React.ReactNode }) {
15
- return <DialogProvider>{children}</DialogProvider>;
16
- }
17
-
18
- // Demo component using the hook
19
- function AlertDemo() {
20
- const { alert } = useDialog();
21
-
22
- const handleSimpleAlert = useCallback(async () => {
23
- await alert('This is a simple alert message!');
24
- console.log('Alert closed');
25
- }, [alert]);
26
-
27
- const handleAlertWithTitle = useCallback(async () => {
28
- await alert({
29
- title: 'Success!',
30
- message: 'Your changes have been saved successfully.',
31
- });
32
- console.log('Alert with title closed');
33
- }, [alert]);
34
-
35
- return (
36
- <div className="flex gap-2">
37
- <Button onClick={handleSimpleAlert}>Simple Alert</Button>
38
- <Button variant="outline" onClick={handleAlertWithTitle}>
39
- Alert with Title
40
- </Button>
41
- </div>
42
- );
43
- }
44
-
45
- export const Alert = () => (
46
- <StoryWrapper>
47
- <AlertDemo />
48
- </StoryWrapper>
49
- );
50
-
51
- // Confirm demo
52
- function ConfirmDemo() {
53
- const { confirm, alert } = useDialog();
54
-
55
- const handleSimpleConfirm = useCallback(async () => {
56
- const result = await confirm('Are you sure you want to proceed?');
57
- await alert(`You clicked: ${result ? 'Confirm' : 'Cancel'}`);
58
- }, [confirm, alert]);
59
-
60
- const handleDestructiveConfirm = useCallback(async () => {
61
- const result = await confirm({
62
- title: 'Delete Item',
63
- message: 'This action cannot be undone. Are you sure you want to delete this item?',
64
- confirmText: 'Yes, Delete',
65
- cancelText: 'Keep It',
66
- variant: 'destructive',
67
- });
68
- await alert(`You clicked: ${result ? 'Delete' : 'Keep'}`);
69
- }, [confirm, alert]);
70
-
71
- return (
72
- <div className="flex gap-2">
73
- <Button onClick={handleSimpleConfirm}>Simple Confirm</Button>
74
- <Button variant="destructive" onClick={handleDestructiveConfirm}>
75
- Destructive Confirm
76
- </Button>
77
- </div>
78
- );
79
- }
80
-
81
- export const Confirm = () => (
82
- <StoryWrapper>
83
- <ConfirmDemo />
84
- </StoryWrapper>
85
- );
86
-
87
- // Prompt demo
88
- function PromptDemo() {
89
- const { prompt, alert } = useDialog();
90
-
91
- const handleSimplePrompt = useCallback(async () => {
92
- const result = await prompt('What is your name?');
93
- if (result) {
94
- await alert(`Hello, ${result}!`);
95
- } else {
96
- await alert('You cancelled the prompt.');
97
- }
98
- }, [prompt, alert]);
99
-
100
- const handlePromptWithDefault = useCallback(async () => {
101
- const result = await prompt({
102
- title: 'Edit Name',
103
- message: 'Enter your display name:',
104
- defaultValue: 'John Doe',
105
- placeholder: 'Enter name...',
106
- confirmText: 'Save',
107
- cancelText: 'Cancel',
108
- });
109
- if (result) {
110
- await alert(`Name updated to: ${result}`);
111
- }
112
- }, [prompt, alert]);
113
-
114
- const handleEmailPrompt = useCallback(async () => {
115
- const result = await prompt({
116
- title: 'Subscribe',
117
- message: 'Enter your email to subscribe to our newsletter:',
118
- placeholder: 'email@example.com',
119
- inputType: 'email',
120
- confirmText: 'Subscribe',
121
- });
122
- if (result) {
123
- await alert(`Subscribed with: ${result}`);
124
- }
125
- }, [prompt, alert]);
126
-
127
- return (
128
- <div className="flex gap-2 flex-wrap">
129
- <Button onClick={handleSimplePrompt}>Simple Prompt</Button>
130
- <Button variant="outline" onClick={handlePromptWithDefault}>
131
- Prompt with Default
132
- </Button>
133
- <Button variant="secondary" onClick={handleEmailPrompt}>
134
- Email Prompt
135
- </Button>
136
- </div>
137
- );
138
- }
139
-
140
- export const Prompt = () => (
141
- <StoryWrapper>
142
- <PromptDemo />
143
- </StoryWrapper>
144
- );
145
-
146
- // Queue demo - multiple dialogs in sequence
147
- function QueueDemo() {
148
- const { alert, confirm, prompt } = useDialog();
149
-
150
- const handleQueue = useCallback(async () => {
151
- await alert('This is step 1 of 3');
152
- const proceed = await confirm('Do you want to continue to step 2?');
153
- if (!proceed) {
154
- await alert('You cancelled the sequence.');
155
- return;
156
- }
157
- const name = await prompt({
158
- title: 'Step 3',
159
- message: 'Enter your name to complete:',
160
- });
161
- if (name) {
162
- await alert(`Sequence complete! Hello, ${name}!`);
163
- } else {
164
- await alert('Sequence cancelled at step 3.');
165
- }
166
- }, [alert, confirm, prompt]);
167
-
168
- return (
169
- <Button onClick={handleQueue}>
170
- Start Dialog Sequence
171
- </Button>
172
- );
173
- }
174
-
175
- export const Queue = () => (
176
- <StoryWrapper>
177
- <QueueDemo />
178
- </StoryWrapper>
179
- );
180
-
181
- // Window.dialog API demo (vanilla JS style)
182
- function WindowDialogDemo() {
183
- const handleWindowAlert = useCallback(() => {
184
- window.dialog.alert('Called via window.dialog.alert()');
185
- }, []);
186
-
187
- const handleWindowConfirm = useCallback(async () => {
188
- const result = await window.dialog.confirm('Called via window.dialog.confirm()');
189
- window.dialog.alert(`Result: ${result}`);
190
- }, []);
191
-
192
- const handleWindowPrompt = useCallback(async () => {
193
- const result = await window.dialog.prompt({
194
- title: 'window.dialog.prompt()',
195
- message: 'This works from vanilla JS too!',
196
- defaultValue: 'Hello',
197
- });
198
- if (result) {
199
- window.dialog.alert(`You entered: ${result}`);
200
- }
201
- }, []);
202
-
203
- return (
204
- <div className="space-y-4">
205
- <p className="text-sm text-muted-foreground">
206
- These buttons use <code>window.dialog.*</code> directly - works from any JS code!
207
- </p>
208
- <div className="flex gap-2">
209
- <Button variant="outline" onClick={handleWindowAlert}>
210
- window.dialog.alert()
211
- </Button>
212
- <Button variant="outline" onClick={handleWindowConfirm}>
213
- window.dialog.confirm()
214
- </Button>
215
- <Button variant="outline" onClick={handleWindowPrompt}>
216
- window.dialog.prompt()
217
- </Button>
218
- </div>
219
- </div>
220
- );
221
- }
222
-
223
- export const WindowDialogAPI = () => (
224
- <StoryWrapper>
225
- <WindowDialogDemo />
226
- </StoryWrapper>
227
- );
228
-
229
- // Keyboard shortcuts demo
230
- function HotkeysDemo() {
231
- const { alert, confirm } = useDialog();
232
-
233
- const handleHotkeysDemo = useCallback(async () => {
234
- await alert({
235
- title: 'Keyboard Shortcuts',
236
- message: 'Press Enter to close this alert, or wait and click OK.',
237
- });
238
-
239
- const result = await confirm({
240
- title: 'Confirm with Keyboard',
241
- message: 'Press Enter to confirm, Escape to cancel.',
242
- });
243
-
244
- await alert(`You pressed: ${result ? 'Enter (Confirm)' : 'Escape (Cancel)'}`);
245
- }, [alert, confirm]);
246
-
247
- return (
248
- <div className="space-y-4">
249
- <p className="text-sm text-muted-foreground">
250
- Dialogs support keyboard shortcuts: <kbd className="px-1.5 py-0.5 bg-muted rounded text-xs">Enter</kbd> to confirm, <kbd className="px-1.5 py-0.5 bg-muted rounded text-xs">Escape</kbd> to cancel.
251
- </p>
252
- <Button onClick={handleHotkeysDemo}>
253
- Test Keyboard Shortcuts
254
- </Button>
255
- </div>
256
- );
257
- }
258
-
259
- export const KeyboardShortcuts = () => (
260
- <StoryWrapper>
261
- <HotkeysDemo />
262
- </StoryWrapper>
263
- );
@@ -1,28 +0,0 @@
1
- /**
2
- * UI-Core story modules registry.
3
- *
4
- * Re-export stories through a package subpath instead of deep importing files from apps.
5
- */
6
-
7
- import type { StoryModule } from '@djangocfg/playground';
8
-
9
- import * as Button from '../components/forms/button/button.story';
10
- import * as Input from '../components/forms/input/input.story';
11
- import * as Select from '../components/select/select.story';
12
- import * as Slider from '../components/forms/slider/slider.story';
13
- import * as Dialog from '../components/overlay/dialog/dialog.story';
14
- import * as Tabs from '../components/navigation/tabs/tabs.story';
15
- import * as Popover from '../components/overlay/popover/popover.story';
16
- import * as Tooltip from '../components/overlay/tooltip/tooltip.story';
17
-
18
- export const uiCoreStoryModules: Record<string, StoryModule> = {
19
- 'button.story.tsx': Button,
20
- 'input.story.tsx': Input,
21
- 'select.story.tsx': Select,
22
- 'slider.story.tsx': Slider,
23
- 'dialog.story.tsx': Dialog,
24
- 'tabs.story.tsx': Tabs,
25
- 'popover.story.tsx': Popover,
26
- 'tooltip.story.tsx': Tooltip,
27
- };
28
-
@@ -1,157 +0,0 @@
1
- import { defineStory } from '@djangocfg/playground';
2
-
3
- export default defineStory({
4
- title: 'Theme/Tokens',
5
- description: 'Visual reference for all semantic CSS color tokens. Use these classes — never raw Tailwind color-scale classes (amber-500 etc).',
6
- });
7
-
8
- // ─── Helpers ──────────────────────────────────────────────────────────────────
9
-
10
- function TokenRow({ label, bg, text, border }: { label: string; bg: string; text: string; border: string }) {
11
- return (
12
- <div className={`flex items-center justify-between rounded-md border px-4 py-3 ${bg} ${border}`}>
13
- <span className={`text-sm font-medium ${text}`}>{label}</span>
14
- <div className="flex gap-2 font-mono text-xs opacity-70">
15
- <code className={text}>{bg}</code>
16
- <code className={text}>{text}</code>
17
- <code className={text}>{border}</code>
18
- </div>
19
- </div>
20
- );
21
- }
22
-
23
- function Section({ title, children }: { title: string; children: React.ReactNode }) {
24
- return (
25
- <div className="space-y-2">
26
- <h3 className="text-xs font-semibold uppercase tracking-widest text-muted-foreground">{title}</h3>
27
- <div className="space-y-2">{children}</div>
28
- </div>
29
- );
30
- }
31
-
32
- function SwatchRow({ name, bgClass }: { name: string; bgClass: string }) {
33
- return (
34
- <div className="flex items-center gap-3">
35
- <div className={`h-8 w-16 rounded border border-border ${bgClass}`} />
36
- <code className="text-xs text-foreground">{name}</code>
37
- </div>
38
- );
39
- }
40
-
41
- // ─── Stories ──────────────────────────────────────────────────────────────────
42
-
43
- export const StatusSurfaces = () => (
44
- <div className="space-y-6 max-w-2xl">
45
- <p className="text-sm text-muted-foreground">
46
- Status banners — use <code className="text-xs bg-code text-code-foreground rounded px-1">bg-*-background</code>,{' '}
47
- <code className="text-xs bg-code text-code-foreground rounded px-1">text-*-foreground</code>,{' '}
48
- <code className="text-xs bg-code text-code-foreground rounded px-1">border-*-border</code>
49
- </p>
50
-
51
- <Section title="Warning">
52
- <TokenRow
53
- label="⚠ You're seeing a preview. Subscribe for full access."
54
- bg="bg-warning-background"
55
- text="text-warning-foreground"
56
- border="border border-warning-border/50"
57
- />
58
- </Section>
59
-
60
- <Section title="Success">
61
- <TokenRow
62
- label="✓ Operation completed successfully."
63
- bg="bg-success-background"
64
- text="text-success-foreground"
65
- border="border border-success-border/50"
66
- />
67
- </Section>
68
-
69
- <Section title="Destructive">
70
- <TokenRow
71
- label="✕ Something went wrong. Please try again."
72
- bg="bg-destructive-background"
73
- text="text-destructive"
74
- border="border border-destructive-border/50"
75
- />
76
- </Section>
77
-
78
- <Section title="Info">
79
- <TokenRow
80
- label="ℹ New features are available in your plan."
81
- bg="bg-info-background"
82
- text="text-info-foreground"
83
- border="border border-info-border/50"
84
- />
85
- </Section>
86
- </div>
87
- );
88
-
89
- export const BaseColors = () => (
90
- <div className="space-y-6 max-w-xl">
91
- <Section title="Base">
92
- <div className="grid grid-cols-2 gap-3">
93
- <SwatchRow name="bg-background" bgClass="bg-background" />
94
- <SwatchRow name="bg-foreground" bgClass="bg-foreground" />
95
- <SwatchRow name="bg-card" bgClass="bg-card" />
96
- <SwatchRow name="bg-muted" bgClass="bg-muted" />
97
- <SwatchRow name="bg-accent" bgClass="bg-accent" />
98
- <SwatchRow name="bg-border" bgClass="bg-border" />
99
- </div>
100
- </Section>
101
-
102
- <Section title="Brand">
103
- <div className="grid grid-cols-2 gap-3">
104
- <SwatchRow name="bg-primary" bgClass="bg-primary" />
105
- <SwatchRow name="bg-secondary" bgClass="bg-secondary" />
106
- </div>
107
- </Section>
108
-
109
- <Section title="Status accents (icon color)">
110
- <div className="grid grid-cols-2 gap-3">
111
- <SwatchRow name="bg-warning" bgClass="bg-warning" />
112
- <SwatchRow name="bg-success" bgClass="bg-success" />
113
- <SwatchRow name="bg-destructive" bgClass="bg-destructive" />
114
- <SwatchRow name="bg-info" bgClass="bg-info" />
115
- </div>
116
- </Section>
117
- </div>
118
- );
119
-
120
- export const CodeSurface = () => (
121
- <div className="space-y-4 max-w-xl">
122
- <Section title="Code tokens">
123
- <div className="rounded-md border border-code-border bg-code text-code-foreground p-4 font-mono text-sm">
124
- <div>bg-code / text-code-foreground / border-code-border</div>
125
- <div className="mt-2 text-xs opacity-60">Used by PrettyCode, MarkdownMessage code fences</div>
126
- </div>
127
- <div className="text-sm">
128
- Inline:{' '}
129
- <code className="rounded bg-code-inline px-1.5 py-0.5 text-code-inline-foreground text-xs">
130
- const x = 42
131
- </code>
132
- </div>
133
- </Section>
134
-
135
- <Section title="Sidebar tokens">
136
- <div className="rounded-md border border-sidebar-border bg-sidebar p-4 space-y-1 text-sidebar-foreground text-sm">
137
- <div className="font-semibold">bg-sidebar / text-sidebar-foreground</div>
138
- <div className="text-xs opacity-60">Used by the app sidebar chrome</div>
139
- <div className="mt-2 rounded bg-sidebar-accent px-2 py-1 text-sidebar-accent-foreground text-xs">
140
- bg-sidebar-accent — hover state
141
- </div>
142
- </div>
143
- </Section>
144
- </div>
145
- );
146
-
147
- export const TypographyTokens = () => (
148
- <div className="space-y-3 max-w-md">
149
- <p className="text-foreground text-sm font-medium">text-foreground — primary body</p>
150
- <p className="text-muted-foreground text-sm">text-muted-foreground — secondary / hints</p>
151
- <p className="text-primary text-sm">text-primary — brand links / accents</p>
152
- <p className="text-destructive text-sm">text-destructive — error messages</p>
153
- <p className="text-warning text-sm">text-warning — warning labels</p>
154
- <p className="text-success text-sm">text-success — success labels</p>
155
- <p className="text-info text-sm">text-info — info labels</p>
156
- </div>
157
- );