@shohojdhara/atomix 0.3.13 → 0.3.14

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 (151) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +2 -0
  3. package/dist/atomix.css +95 -77
  4. package/dist/atomix.css.map +1 -1
  5. package/dist/atomix.min.css +2 -2
  6. package/dist/atomix.min.css.map +1 -1
  7. package/dist/charts.d.ts +1 -1
  8. package/dist/charts.js +1 -1
  9. package/dist/core.d.ts +41 -11
  10. package/dist/core.js +39 -23
  11. package/dist/core.js.map +1 -1
  12. package/dist/forms.d.ts +28 -11
  13. package/dist/forms.js +8 -5
  14. package/dist/forms.js.map +1 -1
  15. package/dist/heavy.d.ts +1 -1
  16. package/dist/heavy.js +15 -6
  17. package/dist/heavy.js.map +1 -1
  18. package/dist/index.d.ts +122 -46
  19. package/dist/index.esm.js +849 -182
  20. package/dist/index.esm.js.map +1 -1
  21. package/dist/index.js +854 -186
  22. package/dist/index.js.map +1 -1
  23. package/dist/index.min.js +1 -1
  24. package/dist/index.min.js.map +1 -1
  25. package/dist/theme.d.ts +27 -2
  26. package/dist/theme.js +721 -108
  27. package/dist/theme.js.map +1 -1
  28. package/package.json +1 -1
  29. package/scripts/atomix-cli.js +610 -1111
  30. package/scripts/cli/component-generator.js +610 -0
  31. package/scripts/cli/documentation-sync.js +542 -0
  32. package/scripts/cli/interactive-init.js +84 -288
  33. package/scripts/cli/mappings.js +211 -0
  34. package/scripts/cli/migration-tools.js +95 -288
  35. package/scripts/cli/template-manager.js +107 -0
  36. package/scripts/cli/templates/README.md +123 -0
  37. package/scripts/cli/templates/composable-templates.js +149 -0
  38. package/scripts/cli/templates/config-templates.js +126 -0
  39. package/scripts/cli/templates/index.js +95 -0
  40. package/scripts/cli/templates/project-templates.js +214 -0
  41. package/scripts/cli/templates/react-templates.js +261 -0
  42. package/scripts/cli/templates/scss-templates.js +156 -0
  43. package/scripts/cli/templates/storybook-templates.js +236 -0
  44. package/scripts/cli/templates/testing-templates.js +45 -0
  45. package/scripts/cli/templates/token-templates.js +447 -0
  46. package/scripts/cli/templates/types-templates.js +133 -0
  47. package/scripts/cli/templates-original-backup.js +1655 -0
  48. package/scripts/cli/templates.js +35 -0
  49. package/scripts/cli/templates_backup.js +684 -0
  50. package/scripts/cli/theme-bridge.js +20 -14
  51. package/scripts/cli/token-manager.js +150 -77
  52. package/scripts/cli/utils.js +37 -25
  53. package/src/components/Accordion/Accordion.stories.tsx +5 -5
  54. package/src/components/Accordion/Accordion.test.tsx +57 -0
  55. package/src/components/Accordion/Accordion.tsx +4 -0
  56. package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +1 -1
  57. package/src/components/AtomixGlass/stories/Examples.stories.tsx +37 -37
  58. package/src/components/AtomixGlass/stories/Playground.stories.tsx +50 -51
  59. package/src/components/Avatar/Avatar.stories.tsx +26 -26
  60. package/src/components/Badge/Badge.stories.tsx +31 -31
  61. package/src/components/Badge/Badge.test.tsx +51 -0
  62. package/src/components/Badge/Badge.tsx +20 -1
  63. package/src/components/Block/Block.stories.tsx +5 -5
  64. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +1 -1
  65. package/src/components/Breadcrumb/Breadcrumb.tsx +2 -2
  66. package/src/components/Button/Button.stories.tsx +13 -13
  67. package/src/components/Button/Button.tsx +4 -4
  68. package/src/components/Button/ButtonGroup.stories.tsx +2 -2
  69. package/src/components/Button/README.md +5 -0
  70. package/src/components/Callout/Callout.stories.tsx +11 -11
  71. package/src/components/Callout/Callout.test.tsx +10 -10
  72. package/src/components/Callout/Callout.tsx +7 -7
  73. package/src/components/Callout/README.md +9 -8
  74. package/src/components/Card/Card.tsx +2 -2
  75. package/src/components/Chart/Chart.stories.tsx +6 -6
  76. package/src/components/Chart/Chart.tsx +1 -1
  77. package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +1 -1
  78. package/src/components/DataTable/DataTable.tsx +14 -12
  79. package/src/components/DatePicker/DatePicker.stories.tsx +6 -6
  80. package/src/components/Dropdown/Dropdown.stories.tsx +4 -4
  81. package/src/components/Form/Checkbox.stories.tsx +3 -3
  82. package/src/components/Form/Checkbox.tsx +4 -2
  83. package/src/components/Form/Form.stories.tsx +3 -3
  84. package/src/components/Form/FormGroup.stories.tsx +1 -1
  85. package/src/components/Form/Input.stories.tsx +28 -16
  86. package/src/components/Form/Input.test.tsx +59 -0
  87. package/src/components/Form/Input.tsx +97 -95
  88. package/src/components/Form/Radio.stories.tsx +94 -94
  89. package/src/components/Form/Radio.tsx +2 -2
  90. package/src/components/Form/Select.stories.tsx +4 -4
  91. package/src/components/Form/Select.tsx +2 -2
  92. package/src/components/Form/Textarea.stories.tsx +22 -7
  93. package/src/components/Form/Textarea.test.tsx +45 -0
  94. package/src/components/Form/Textarea.tsx +88 -86
  95. package/src/components/List/List.stories.tsx +2 -2
  96. package/src/components/Modal/Modal.stories.tsx +4 -4
  97. package/src/components/Navigation/Navbar/Navbar.stories.tsx +5 -5
  98. package/src/components/Navigation/Navbar/Navbar.tsx +1 -1
  99. package/src/components/Navigation/README.md +1 -1
  100. package/src/components/Pagination/Pagination.stories.tsx +5 -2
  101. package/src/components/Pagination/Pagination.tsx +1 -1
  102. package/src/components/PhotoViewer/PhotoViewer.stories.tsx +10 -10
  103. package/src/components/Popover/Popover.stories.tsx +1 -1
  104. package/src/components/ProductReview/ProductReview.tsx +1 -1
  105. package/src/components/Progress/Progress.tsx +46 -46
  106. package/src/components/Rating/Rating.stories.tsx +4 -4
  107. package/src/components/Rating/Rating.tsx +8 -8
  108. package/src/components/Slider/Slider.stories.tsx +63 -63
  109. package/src/components/Spinner/Spinner.stories.tsx +2 -2
  110. package/src/components/Spinner/Spinner.test.tsx +35 -0
  111. package/src/components/Spinner/Spinner.tsx +9 -2
  112. package/src/components/Testimonial/Testimonial.stories.tsx +1 -1
  113. package/src/components/Toggle/Toggle.stories.tsx +32 -9
  114. package/src/components/Toggle/Toggle.test.tsx +91 -0
  115. package/src/components/Toggle/Toggle.tsx +44 -27
  116. package/src/components/Tooltip/Tooltip.tsx +1 -1
  117. package/src/layouts/Grid/Grid.stories.tsx +49 -49
  118. package/src/layouts/MasonryGrid/MasonryGrid.stories.tsx +2 -2
  119. package/src/lib/composables/useAccordion.ts +12 -3
  120. package/src/lib/composables/useBreadcrumb.ts +2 -2
  121. package/src/lib/composables/useCallout.ts +7 -7
  122. package/src/lib/composables/useNavbar.ts +1 -1
  123. package/src/lib/constants/components.ts +1 -1
  124. package/src/lib/storybook/InteractiveDemo.tsx +113 -0
  125. package/src/lib/storybook/PreviewContainer.tsx +36 -0
  126. package/src/lib/storybook/VariantsGrid.tsx +21 -0
  127. package/src/lib/storybook/index.ts +3 -0
  128. package/src/lib/theme/core/createThemeObject.ts +9 -5
  129. package/src/lib/theme/devtools/CLI.ts +155 -0
  130. package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +213 -0
  131. package/src/lib/theme/devtools/DesignTokensCustomizer.tsx +566 -0
  132. package/src/lib/theme/devtools/LiveEditor.tsx +2 -1
  133. package/src/lib/theme/devtools/index.ts +3 -0
  134. package/src/lib/theme/errors/errors.ts +8 -0
  135. package/src/lib/theme/runtime/ThemeProvider.tsx +117 -57
  136. package/src/lib/theme/runtime/__tests__/ThemeProvider.integration.test.tsx +305 -0
  137. package/src/lib/theme/runtime/__tests__/ThemeProvider.test.tsx +588 -0
  138. package/src/lib/theme/utils/__tests__/themeValidation.test.ts +264 -0
  139. package/src/lib/theme/utils/index.ts +1 -0
  140. package/src/lib/theme/utils/themeValidation.ts +501 -0
  141. package/src/lib/theme-tools.ts +32 -3
  142. package/src/lib/types/components.ts +81 -26
  143. package/src/lib/utils/themeNaming.ts +1 -1
  144. package/src/styles/06-components/_components.callout.scss +29 -33
  145. package/src/styles/06-components/_index.scss +1 -1
  146. package/src/styles/99-utilities/_utilities.display.scss +14 -3
  147. package/src/styles/99-utilities/_utilities.flex.scss +10 -10
  148. package/src/styles/99-utilities/_utilities.text.scss +28 -8
  149. package/scripts/cli/__tests__/cli-commands.test.js +0 -204
  150. package/scripts/cli/__tests__/utils.test.js +0 -201
  151. package/scripts/cli/__tests__/vitest.config.js +0 -26
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+
3
+ interface PreviewContainerProps {
4
+ title: string;
5
+ description: string;
6
+ backgroundImage?: string;
7
+ children: React.ReactNode;
8
+ }
9
+
10
+ export const PreviewContainer: React.FC<PreviewContainerProps> = ({
11
+ title,
12
+ description,
13
+ backgroundImage,
14
+ children,
15
+ }) => {
16
+ const containerStyle = backgroundImage
17
+ ? {
18
+ backgroundImage: `url(${backgroundImage})`,
19
+ backgroundSize: 'cover',
20
+ backgroundPosition: 'center',
21
+ minHeight: '100vh',
22
+ }
23
+ : {};
24
+
25
+ return (
26
+ <div style={containerStyle} className="w-full">
27
+ <div className="max-w-7xl mx-auto p-6">
28
+ <div className="mb-8">
29
+ <h1 className="text-3xl font-bold text-gray-900 mb-2">{title}</h1>
30
+ <p className="text-gray-600">{description}</p>
31
+ </div>
32
+ {children}
33
+ </div>
34
+ </div>
35
+ );
36
+ };
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+
3
+ interface VariantsGridProps {
4
+ children: React.ReactNode;
5
+ columns?: number;
6
+ gap?: string;
7
+ }
8
+
9
+ export const VariantsGrid: React.FC<VariantsGridProps> = ({
10
+ children,
11
+ columns = 4,
12
+ gap = 'gap-4',
13
+ }) => {
14
+ const gridClass = `grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-${columns} ${gap}`;
15
+
16
+ return (
17
+ <div className={gridClass}>
18
+ {children}
19
+ </div>
20
+ );
21
+ };
@@ -0,0 +1,3 @@
1
+ export { PreviewContainer } from './PreviewContainer';
2
+ export { VariantsGrid } from './VariantsGrid';
3
+ export { InteractiveDemo } from './InteractiveDemo';
@@ -296,8 +296,12 @@ function createBreakpoints(breakpointsInput?: BreakpointsOptions): Theme['breakp
296
296
  * @returns Complete theme object
297
297
  */
298
298
  export function createThemeObject(...options: ThemeOptions[]): Theme {
299
- // Merge all options
300
- const mergedOptions = options.reduce((acc, option) => deepMerge(acc, option), {} as ThemeOptions);
299
+ // Merge all options by spreading them into a single object
300
+ const mergedOptions = options.reduce((acc, option) => {
301
+ // Cast option to any to avoid strict typing during merge
302
+ const opt = option as any;
303
+ return deepMerge(acc, opt || {}) as any;
304
+ }, {} as any);
301
305
 
302
306
  // Create palette
303
307
  const palette: Theme['palette'] = {
@@ -342,9 +346,9 @@ export function createThemeObject(...options: ThemeOptions[]): Theme {
342
346
 
343
347
  // Create transitions
344
348
  const transitions: Theme['transitions'] = deepMerge(
345
- { ...DEFAULT_TRANSITIONS },
346
- mergedOptions.transitions || {}
347
- );
349
+ { ...DEFAULT_TRANSITIONS } as Partial<Theme['transitions']>,
350
+ (mergedOptions.transitions || {}) as Partial<Theme['transitions']>
351
+ ) as Theme['transitions'];
348
352
 
349
353
  // Create z-index
350
354
  const zIndex: Theme['zIndex'] = deepMerge({ ...DEFAULT_ZINDEX }, mergedOptions.zIndex || {});
@@ -0,0 +1,155 @@
1
+ #!/usr/bin/env ts-node
2
+
3
+ /**
4
+ * Atomix Theme DevTools CLI
5
+ *
6
+ * Internal CLI for theme validation and management.
7
+ * This is called by the main atomix-cli.js via theme-bridge.js.
8
+ */
9
+
10
+ import { Command } from 'commander';
11
+ import chalk from 'chalk';
12
+ import * as fs from 'fs';
13
+ import * as path from 'path';
14
+ // import { ThemeValidator } from './ThemeValidator.js';
15
+ import boxen from 'boxen';
16
+
17
+ // Stub validator for now to avoid ESM resolution issues in CLI
18
+ // TODO: Fix ESM module resolution for ThemeValidator in CLI context
19
+ class ThemeValidator {
20
+ validate() {
21
+ return { valid: true, errors: [], warnings: [], a11yIssues: [] };
22
+ }
23
+ }
24
+
25
+ const program = new Command();
26
+
27
+ program
28
+ .name('atomix-theme')
29
+ .description('Atomix Theme DevTools')
30
+ .version('0.1.0');
31
+
32
+ // Utils
33
+ const getThemesDir = () => {
34
+ const possiblePaths = [
35
+ path.join(process.cwd(), 'themes'),
36
+ path.join(process.cwd(), 'src', 'themes'),
37
+ path.join(process.cwd(), 'src', 'styles', 'themes')
38
+ ];
39
+
40
+ for (const p of possiblePaths) {
41
+ if (fs.existsSync(p)) return p;
42
+ }
43
+ return path.join(process.cwd(), 'themes');
44
+ };
45
+
46
+ // Validate Command
47
+ program
48
+ .command('validate')
49
+ .description('Validate theme configuration')
50
+ .option('-c, --config <path>', 'Path to theme config')
51
+ .option('--strict', 'Enable strict validation')
52
+ .action(async (options) => {
53
+ console.log(chalk.cyan('Validating theme configuration...'));
54
+
55
+ // In a real implementation this would load the theme object
56
+ // For now we'll do basic file checks if a file is provided
57
+
58
+ if (options.config) {
59
+ const configPath = path.resolve(process.cwd(), options.config);
60
+ if (!fs.existsSync(configPath)) {
61
+ console.error(chalk.red(`❌ Config file not found: ${options.config}`));
62
+ process.exit(1);
63
+ }
64
+
65
+ // Attempt to validate structure if it's JSON
66
+ if (configPath.endsWith('.json')) {
67
+ try {
68
+ const content = JSON.parse(fs.readFileSync(configPath, 'utf8'));
69
+ const validator = new ThemeValidator();
70
+ // Mocking validation for now as we don't have a full loader
71
+ console.log(chalk.green('✓ JSON structure is valid'));
72
+ } catch (e) {
73
+ console.error(chalk.red(`❌ Invalid JSON: ${(e as Error).message}`));
74
+ process.exit(1);
75
+ }
76
+ }
77
+ }
78
+
79
+ // Output success for now to verify connectivity
80
+ console.log(chalk.green('✓ Validation completed'));
81
+ });
82
+
83
+ // List Command
84
+ program
85
+ .command('list')
86
+ .description('List available themes')
87
+ .action(async () => {
88
+ const themesDir = getThemesDir();
89
+
90
+ if (!fs.existsSync(themesDir)) {
91
+ console.log(chalk.yellow(`No themes directory found at ${themesDir}`));
92
+ return;
93
+ }
94
+
95
+ const themes = fs.readdirSync(themesDir).filter(f => {
96
+ const stat = fs.statSync(path.join(themesDir, f));
97
+ return stat.isDirectory() || f.endsWith('.json') || f.endsWith('.ts');
98
+ });
99
+
100
+ console.log(chalk.bold.cyan(`\nFound ${themes.length} themes in ${themesDir}:\n`));
101
+
102
+ themes.forEach(theme => {
103
+ console.log(` • ${theme}`);
104
+ });
105
+ console.log('');
106
+ });
107
+
108
+ // Inspect Command
109
+ program
110
+ .command('inspect <theme>')
111
+ .description('Inspect specific theme')
112
+ .option('--json', 'Output as JSON')
113
+ .action(async (themeName, options) => {
114
+ const themesDir = getThemesDir();
115
+ const themePath = path.join(themesDir, themeName);
116
+
117
+ if (!fs.existsSync(themePath) && !fs.existsSync(`${themePath}.json`) && !fs.existsSync(`${themePath}.ts`)) {
118
+ console.error(chalk.red(`❌ Theme not found: ${themeName}`));
119
+ process.exit(1);
120
+ }
121
+
122
+ if (options.json) {
123
+ console.log(JSON.stringify({ name: themeName, path: themePath }, null, 2));
124
+ } else {
125
+ console.log(boxen(
126
+ chalk.bold(themeName) + '\n' +
127
+ chalk.gray(`Path: ${themePath}`),
128
+ { padding: 1, borderStyle: 'round' }
129
+ ));
130
+ }
131
+ });
132
+
133
+ // Compare Command (Stub)
134
+ program
135
+ .command('compare <theme1> <theme2>')
136
+ .description('Compare two themes')
137
+ .action(async (theme1, theme2) => {
138
+ console.log(chalk.cyan(`Comparing ${theme1} with ${theme2}...`));
139
+ // Stub
140
+ console.log(chalk.yellow('Comparison feature not yet fully implemented.'));
141
+ });
142
+
143
+ // Export Command (Stub)
144
+ program
145
+ .command('export <theme>')
146
+ .description('Export theme')
147
+ .option('-o, --output <path>', 'Output path')
148
+ .action(async (theme, options) => {
149
+ console.log(chalk.cyan(`Exporting ${theme}...`));
150
+ if (options.output) {
151
+ console.log(chalk.green(`✓ Exported to ${options.output}`));
152
+ }
153
+ });
154
+
155
+ program.parse(process.argv);
@@ -0,0 +1,213 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { DesignTokensCustomizer } from './DesignTokensCustomizer';
3
+ import { useState } from 'react';
4
+
5
+ // Enhanced preview components
6
+ const PreviewContainer = ({ title, description, children }: {
7
+ title?: string;
8
+ description?: string;
9
+ children: React.ReactNode;
10
+ }) => (
11
+ <div className="story-preview-container">
12
+ {title && <h3 className="story-preview-title">{title}</h3>}
13
+ {description && <p className="story-preview-description">{description}</p>}
14
+ <div className="story-preview-content">
15
+ {children}
16
+ </div>
17
+ </div>
18
+ );
19
+
20
+ const meta: Meta<typeof DesignTokensCustomizer> = {
21
+ title: 'DevTools/DesignTokensCustomizer',
22
+ component: DesignTokensCustomizer,
23
+ parameters: {
24
+ layout: 'fullscreen',
25
+ docs: {
26
+ description: {
27
+ component: 'Interactive design tokens customization tool for real-time theme adjustments.'
28
+ }
29
+ }
30
+ }
31
+ };
32
+
33
+ export default meta;
34
+ type Story = StoryObj<typeof DesignTokensCustomizer>;
35
+
36
+ // Basic Usage
37
+ export const Default: Story = {
38
+ render: () => (
39
+ <PreviewContainer
40
+ title="Design Tokens Customizer"
41
+ description="Interactive tool for customizing design tokens in real-time"
42
+ >
43
+ <DesignTokensCustomizer />
44
+ </PreviewContainer>
45
+ ),
46
+ parameters: {
47
+ docs: {
48
+ description: {
49
+ story: 'The default design tokens customizer with all standard controls and features.'
50
+ }
51
+ }
52
+ }
53
+ };
54
+
55
+ // With Custom Configuration
56
+ export const WithCustomConfig: Story = {
57
+ render: () => {
58
+ const customConfig = {
59
+ colors: {
60
+ primary: '#667eea',
61
+ secondary: '#764ba2',
62
+ accent: '#f093fb'
63
+ },
64
+ spacing: {
65
+ small: '8px',
66
+ medium: '16px',
67
+ large: '24px'
68
+ },
69
+ typography: {
70
+ fontFamily: 'Inter, sans-serif',
71
+ fontSize: '16px',
72
+ fontWeight: '400'
73
+ }
74
+ };
75
+
76
+ return (
77
+ <PreviewContainer
78
+ title="Custom Configuration"
79
+ description="Design tokens customizer with predefined custom configuration"
80
+ >
81
+ <DesignTokensCustomizer initialConfig={customConfig} />
82
+ </PreviewContainer>
83
+ );
84
+ }
85
+ };
86
+
87
+ // Theme Preview Mode
88
+ export const ThemePreview: Story = {
89
+ render: () => (
90
+ <PreviewContainer
91
+ title="Theme Preview Mode"
92
+ description="Customizer with live theme preview components"
93
+ >
94
+ <div className="theme-preview-layout">
95
+ <div className="customizer-panel">
96
+ <DesignTokensCustomizer />
97
+ </div>
98
+ <div className="preview-panel">
99
+ <div className="preview-components">
100
+ <button className="preview-button">Primary Button</button>
101
+ <button className="preview-button secondary">Secondary Button</button>
102
+ <div className="preview-card">
103
+ <h3>Preview Card</h3>
104
+ <p>This card updates in real-time with your token changes.</p>
105
+ <input className="preview-input" placeholder="Type to see styling" />
106
+ </div>
107
+ <div className="preview-colors">
108
+ <div className="color-swatch primary"></div>
109
+ <div className="color-swatch secondary"></div>
110
+ <div className="color-swatch accent"></div>
111
+ </div>
112
+ </div>
113
+ </div>
114
+ </div>
115
+ </PreviewContainer>
116
+ ),
117
+ parameters: {
118
+ viewport: {
119
+ viewports: {
120
+ desktop: {
121
+ name: 'Desktop',
122
+ styles: { width: '1200px', height: '800px' }
123
+ }
124
+ },
125
+ defaultViewport: 'desktop'
126
+ }
127
+ }
128
+ };
129
+
130
+ // Compact Mode
131
+ export const Compact: Story = {
132
+ render: () => (
133
+ <PreviewContainer
134
+ title="Compact Mode"
135
+ description="Space-efficient customizer for smaller screens"
136
+ >
137
+ <DesignTokensCustomizer compact={true} />
138
+ </PreviewContainer>
139
+ ),
140
+ parameters: {
141
+ viewport: {
142
+ viewports: {
143
+ mobile: {
144
+ name: 'Mobile',
145
+ styles: { width: '375px', height: '667px' }
146
+ }
147
+ },
148
+ defaultViewport: 'mobile'
149
+ }
150
+ }
151
+ };
152
+
153
+ // With Export Options
154
+ export const WithExport: Story = {
155
+ render: () => {
156
+ const [exportData, setExportData] = useState('');
157
+
158
+ const handleExport = (tokens: any) => {
159
+ setExportData(JSON.stringify(tokens, null, 2));
160
+ };
161
+
162
+ return (
163
+ <PreviewContainer
164
+ title="With Export Options"
165
+ description="Customizer with export functionality for sharing themes"
166
+ >
167
+ <div className="export-workflow">
168
+ <DesignTokensCustomizer onExport={handleExport} />
169
+ {exportData && (
170
+ <div className="export-output">
171
+ <h4>Exported Theme Data:</h4>
172
+ <pre>{exportData}</pre>
173
+ <button
174
+ onClick={() => navigator.clipboard.writeText(exportData)}
175
+ className="copy-button"
176
+ >
177
+ Copy to Clipboard
178
+ </button>
179
+ </div>
180
+ )}
181
+ </div>
182
+ </PreviewContainer>
183
+ );
184
+ }
185
+ };
186
+
187
+ // Interactive Tutorial
188
+ export const InteractiveTutorial: Story = {
189
+ render: () => (
190
+ <PreviewContainer
191
+ title="Interactive Tutorial"
192
+ description="Guided tour of the design tokens customizer features"
193
+ >
194
+ <div className="tutorial-container">
195
+ <div className="tutorial-steps">
196
+ <div className="tutorial-step active">
197
+ <h4>Step 1: Explore Color Tokens</h4>
198
+ <p>Click on the Colors section to customize your primary and secondary colors.</p>
199
+ </div>
200
+ <div className="tutorial-step">
201
+ <h4>Step 2: Adjust Typography</h4>
202
+ <p>Modify font sizes, weights, and line heights for better readability.</p>
203
+ </div>
204
+ <div className="tutorial-step">
205
+ <h4>Step 3: Configure Spacing</h4>
206
+ <p>Set consistent spacing values for margins and padding.</p>
207
+ </div>
208
+ </div>
209
+ <DesignTokensCustomizer />
210
+ </div>
211
+ </PreviewContainer>
212
+ )
213
+ };