/** * Storybook Preview Configuration * * Integrates DSS design tokens into Storybook: * - Applies tokens globally to all stories * - Configures Storybook UI with DSS colors * - Sets up theme switching with token variables * - Enables component stories to use own design system */ // Import tokens generated from Figma // These would be auto-generated via build process from token exporters const DSSTokens = { colors: { primary: '#0066FF', secondary: '#FF6B00', success: '#00B600', warning: '#FFB800', danger: '#FF0000', text: '#1A1A1A', textLight: '#666666', surface: '#FFFFFF', background: '#F5F5F5', border: '#E0E0E0', }, spacing: { xs: '4px', sm: '8px', md: '16px', lg: '24px', xl: '32px', }, typography: { headingFamily: "'Inter', sans-serif", bodyFamily: "'Inter', sans-serif", monospaceFamily: "'Courier New', monospace", }, borderRadius: { sm: '4px', md: '8px', lg: '12px', full: '9999px', }, shadows: { sm: '0 1px 2px rgba(0, 0, 0, 0.05)', md: '0 4px 6px rgba(0, 0, 0, 0.1)', lg: '0 10px 15px rgba(0, 0, 0, 0.1)', }, }; // Create Storybook theme using DSS tokens const createStorybookTheme = () => ({ base: 'light', colorPrimary: DSSTokens.colors.primary, colorSecondary: DSSTokens.colors.secondary, appBg: DSSTokens.colors.background, appContentBg: DSSTokens.colors.surface, appBorderColor: DSSTokens.colors.border, appBorderRadius: parseInt(DSSTokens.borderRadius.md), textColor: DSSTokens.colors.text, textInverseColor: '#FFFFFF', barTextColor: DSSTokens.colors.text, barBg: DSSTokens.colors.surface, barSelectedColor: DSSTokens.colors.primary, barHoverColor: DSSTokens.colors.primary, barBorderColor: DSSTokens.colors.border, inputBg: '#FFFFFF', inputBorder: DSSTokens.colors.border, inputTextColor: DSSTokens.colors.text, inputBorderRadius: parseInt(DSSTokens.borderRadius.md), brandUrl: 'https://dss.overbits.luz.uy', brandImage: '/dss-logo.svg', brandTitle: 'DSS Design System', }); // Register all CSS variables globally const registerCSSVariables = () => { const style = document.documentElement.style; // Register color tokens Object.entries(DSSTokens.colors).forEach(([name, value]) => { style.setProperty(`--dss-color-${name}`, value); }); // Register spacing tokens Object.entries(DSSTokens.spacing).forEach(([name, value]) => { style.setProperty(`--dss-spacing-${name}`, value); }); // Register typography tokens Object.entries(DSSTokens.typography).forEach(([name, value]) => { style.setProperty(`--dss-typography-${name}`, value); }); // Register border radius tokens Object.entries(DSSTokens.borderRadius).forEach(([name, value]) => { style.setProperty(`--dss-radius-${name}`, value); }); // Register shadow tokens Object.entries(DSSTokens.shadows).forEach(([name, value]) => { style.setProperty(`--dss-shadow-${name}`, value); }); }; // Export preview configuration export const preview = { parameters: { // Apply DSS theme to Storybook UI docs: { theme: createStorybookTheme(), }, // Configure viewport options viewport: { viewports: { mobile: { name: 'Mobile', styles: { width: '375px', height: '812px' }, type: 'mobile', }, tablet: { name: 'Tablet', styles: { width: '768px', height: '1024px' }, type: 'tablet', }, desktop: { name: 'Desktop', styles: { width: '1280px', height: '720px' }, type: 'desktop', }, }, }, // Setup backgrounds backgrounds: { default: 'light', values: [ { name: 'light', value: DSSTokens.colors.surface }, { name: 'dark', value: '#1A1A1A' }, { name: 'gray', value: DSSTokens.colors.background }, ], }, }, // Global decorator to apply DSS tokens to all stories decorators: [ (Story, context) => { // Register CSS variables registerCSSVariables(); // Get the story content const storyContent = Story(); // Create wrapper div with DSS token styles const wrapper = document.createElement('div'); wrapper.style.cssText = ` --dss-primary: ${DSSTokens.colors.primary}; --dss-secondary: ${DSSTokens.colors.secondary}; --dss-text: ${DSSTokens.colors.text}; --dss-surface: ${DSSTokens.colors.surface}; --dss-background: ${DSSTokens.colors.background}; --dss-border: ${DSSTokens.colors.border}; --dss-spacing-base: ${DSSTokens.spacing.md}; --dss-font-body: ${DSSTokens.typography.bodyFamily}; --dss-font-heading: ${DSSTokens.typography.headingFamily}; --dss-radius: ${DSSTokens.borderRadius.md}; font-family: ${DSSTokens.typography.bodyFamily}; color: ${DSSTokens.colors.text}; background-color: ${DSSTokens.colors.surface}; padding: ${DSSTokens.spacing.lg}; `; // Append story content to wrapper if (typeof storyContent === 'string') { wrapper.innerHTML = storyContent; } else if (storyContent instanceof Node) { wrapper.appendChild(storyContent); } return wrapper; }, ], }; // Export Storybook theme (for use in stories) export const dssTheme = createStorybookTheme(); // Export DSS tokens for use in stories export const dssTokens = DSSTokens;