UNPKG

@fredboulanger/ui-skins-storybook

Version:

Generate Storybook ui-skins configuration from *.ui_skins.themes.yml files

208 lines (154 loc) 5.12 kB
# UI Skins Storybook Generate Storybook ui-skins configuration from `*.ui_skins.themes.yml` files. ## Features - Automatically generates Storybook theme configuration from YAML theme files - Provides Vite plugin for seamless integration - Supports theme targeting (html, body, or custom selectors) - Hot reload support for theme file changes ## Installation ```bash npm install @fredboulanger/ui-skins-storybook ``` ## Usage ### Vite Plugin Add the plugin to your Storybook configuration: ```typescript // .storybook/main.ts import { vitePluginThemeGenerator } from '@fredboulanger/ui-skins-storybook/main' export default { // ... other config viteFinal: (config) => ({ ...config, plugins: [...(config.plugins || []), vitePluginThemeGenerator()], }), } ``` Or for JavaScript configuration: ```javascript // .storybook/main.js import { vitePluginThemeGenerator } from '@fredboulanger/ui-skins-storybook/main' export default { // ... other config viteFinal: (config) => ({ ...config, plugins: [...(config.plugins || []), vitePluginThemeGenerator()], }), } ``` ### Using with Namespaces If you're using namespaces in your Storybook configuration, you can pass them to the plugin to search for theme files in those directories: ```typescript // .storybook/main.ts import { vitePluginThemeGenerator } from '@fredboulanger/ui-skins-storybook/main' import { resolve } from 'path' export default { // ... other config viteFinal: (config) => ({ ...config, plugins: [...(config.plugins || []), vitePluginThemeGenerator({ namespaces: { 'malakoff_humanis': resolve('../../../themes/custom/malakoff_humanis'), 'ui_suite_cbd': resolve('../../../themes/custom/ui_suite_cbd'), } })], }), } ``` The plugin will automatically search for `*.ui_skins.themes.yml` files in: - The current working directory - All namespace directories you specify ## Theme File Format Create `*.ui_skins.themes.yml` files in your project. Each theme **must** have the following required properties: - `label`: Display name for the theme in Storybook toolbar - `key`: The data-theme attribute value (usually matches the theme name) - `target`: CSS selector where the data-theme attribute will be applied ```yaml # Example: themes.ui_skins.themes.yml cyberpunk: label: "Cyberpunk" key: "data-theme" target: body forest: label: "Forest" key: "data-theme" target: html garden: label: "Garden" key: "data-theme" target: html ``` **Note**: Themes without all three required properties (`label`, `key`, `target`) will be skipped during generation. ## Generated Output The plugin generates a `.storybook/data-themes.ts` file with: - Theme decorators for applying data-theme attributes - Global types for Storybook toolbar - Theme target mapping ## Integration with Storybook Preview To use the generated themes in your Storybook, you need to integrate the `data-themes.ts` file into your `.storybook/preview.ts` configuration: ### 1. Import the Generated Theme Configuration ```typescript // .storybook/preview.ts import type { Preview } from '@storybook/html' import { themeDecorators, themeGlobalTypes } from './data-themes' export const decorators = [ ...themeDecorators, // Theme decorators // Your other decorators ] export const globalTypes = { ...themeGlobalTypes, // Theme global types // Your other global types } const preview: Preview = { parameters: { controls: { matchers: { color: /(background|color)$/i, date: /Date$/, }, }, }, } export default preview ``` ### 2. What the Integration Provides - **Theme Toolbar**: A paintbrush icon in the Storybook toolbar to switch between themes - **Automatic Theme Application**: Themes are automatically applied to the correct target element (html, body, or custom selector) - **Theme Cleanup**: Previous themes are properly removed before applying new ones - **Global Theme State**: Theme selection persists across story navigation ### 3. Generated File Structure The `data-themes.ts` file exports: - `themeDecorators`: Array of decorators that apply theme attributes - `themeGlobalTypes`: Global types configuration for the Storybook toolbar ### 4. Target Elements Themes can be applied to different target elements: - `body`: Applied to the `<body>` element - `html`: Applied to the `<html>` element - Custom selector: Any valid CSS selector (e.g., `.theme-container`, `#app`) ### 5. Complete Example Here's a complete example of a `.storybook/preview.ts` file: ```typescript import type { Preview } from '@storybook/html' import { themeDecorators, themeGlobalTypes } from './data-themes' export const decorators = [ ...themeDecorators, // Add other decorators as needed ] export const globalTypes = { ...themeGlobalTypes, // Add other global types as needed } const preview: Preview = { parameters: { controls: { matchers: { color: /(background|color)$/i, date: /Date$/, }, }, // Add other parameters as needed }, } export default preview ``` ## License MIT