All files / packages/sds-subsystems/.storybook/decorators preview-decorator.js

0% Statements 0/26
0% Branches 0/14
0% Functions 0/8
0% Lines 0/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111                                                                                                                                                                                                                             
import { html } from 'lit-html';
import MyThemes from '../themes.js';
import processThemeState from '../addons/theme-builder/src/utilities/theme-processor.js';
import { loadFont } from '../addons/theme-builder/src/utilities/font-options.js';
import { applyColorScheme } from './apply-color-scheme.js';
 
export const defaultThemeData = {
  colors: {
    brand: '#066AFE',
    success: '#056764',
    error: '#b60554',
    warning: '#8c4b02',
    info: '#0b5cab',
  },
  typography: {
    fontSize: '13px',
    fontFamily: 'default',
    lineHeight: 1.375,
    fontScale: 1,
  },
  spacing: {
    scale: 1,
  },
  borderRadius: {
    scale: 1,
  },
  shadows: {
    show: true,
  },
};
 
const getActiveThemeConfig = (activeTheme) => {
  const savedThemes = JSON.parse(localStorage.getItem('sds-theme-builder-saved-themes'));
  if (savedThemes) {
    const data = savedThemes.find((theme) => theme.name === activeTheme)?.themeData;
    return data;
  }
  return null;
};
 
/**
 * Storybook preview decorator: applies theme, color scheme, and Theme Builder state.
 */
export function previewDecorator(story, context) {
  const selectedTheme = context.globals.themeName || 'cosmos';
  const selectedScheme = context.globals.theme || 'light';
  let themeBuilderTheme =
    context.globals.brand === 'default' ? defaultThemeData : getActiveThemeConfig(context.globals.brand);
  if (context.globals.brand === 'temp') {
    themeBuilderTheme = context.globals.themeState;
  }
 
  // Dispatch event when any of the three properties change
  window.dispatchEvent(
    new CustomEvent('storybook-globals-changed', {
      detail: {
        theme: selectedTheme,
        scheme: selectedScheme,
        themeState: themeBuilderTheme,
      },
      bubbles: true,
      composed: true,
    }),
  );
 
  // Apply light/dark color scheme.
  applyColorScheme(selectedScheme);
 
  // Load Cosmos or Lightning Blue hooks.
  const theme = MyThemes[selectedTheme];
 
  // ✅ Apply Theme Builder theme if available
  if (themeBuilderTheme) {
    console.log('🎨 Applying Theme Builder theme:', themeBuilderTheme);
  }
 
  // Creates a new arg `themeName` for every Story and sets value from global toolbar.
  const { args } = context;
  args.themeName = selectedTheme;
 
  return html`
    <style>
        ${theme.import.map((path) => `@import "${path}";`).join('\n')}
      // Should be updated. WIP
    </style>
    <style id="theme-builder-styles">
      ${(() => {
        if (JSON.stringify(themeBuilderTheme) !== JSON.stringify(defaultThemeData)) {
          return `:root {
          ${(() => {
            const allHookMappings = processThemeState(themeBuilderTheme);
            console.log('allHookMappings', allHookMappings);
            return allHookMappings
              .map((mapping) => `${mapping.name}: ${mapping.value};`)
              .join('\n            ');
          })()}
          }`;
        }
      })()}
    </style>
    ${(() => {
      // Load font based on themeState.typography.fontFamily
      if (themeBuilderTheme?.typography?.fontFamily !== 'default') {
        loadFont(themeBuilderTheme.typography.fontFamily);
      }
      return '';
    })()}
    ${story()}
  `;
}