npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sb-theme-switcher

v0.1.0

Published

A Storybook addon for switching between multiple themes with support for toggle (2 themes) and dropdown (3+ themes)

Readme

sb-theme-switcher

Аддон для Storybook, позволяющий пользователям переключаться между несколькими темами с интеллектуальной адаптацией UI.

Storybook 7 Storybook 8 Storybook 9 Storybook 10 npm version License: MIT

English | Русский

Почему sb-theme-switcher?

В отличие от storybook-dark-mode, который поддерживает только светлую/темную тему, sb-theme-switcher предоставляет:

🎯 Полный контроль над темами

  • Автоматическая адаптация UI: кнопка-переключатель для 2 тем, выпадающий список для 3+ тем
  • Неограниченное количество тем: не только светлая/темная — добавляйте сколько угодно тем
  • Полная синхронизация: изменения темы применяются одновременно к интерфейсу Storybook и к iframe с превью

Нулевая сложность настройки

  • Не требуются декораторы: работает из коробки без оборачивания stories
  • Автоматическая синхронизация превью: тема мгновенно применяется к вашим компонентам
  • Автоматическая синхронизация manager: тема интерфейса Storybook меняется автоматически

🎨 Максимальная гибкость

  • Кастомные иконки: используйте свои иконки для каждой темы
  • Цветовые индикаторы: визуальная идентификация тем в выпадающем списке
  • TypeScript First: полная типизация и поддержка IntelliSense

Возможности

Умный UI: автоматически выбирает переключатель (2 темы) или выпадающий список (3+ темы)
🔄 Полная синхронизация: изменяет тему и в Storybook manager, и в iframe превью
🎨 Неограниченное количество тем: поддержка 2, 3, 4 и более тем
💾 Сохранение: сохраняет выбранную тему в localStorage
📱 Синхронизация между вкладками: тема синхронизируется между вкладками браузера
📚 Режим Docs: отлично работает в Canvas и Docs
🔧 TypeScript: полные определения типов включены

Установка

npm install sb-theme-switcher
# или
yarn add sb-theme-switcher

Быстрый старт

1. Настройте темы

Создайте темы Storybook (.storybook/themes.ts):

import { create } from 'storybook/theming';

export const lightTheme = create({
  base: 'light',
  brandTitle: 'Мое приложение',
  colorPrimary: '#167FFB'
  // ... другие опции темы
});

export const darkTheme = create({
  base: 'dark',
  brandTitle: 'Мое приложение',
  colorPrimary: '#2A8CFF'
  // ... другие опции темы
});

2. Зарегистрируйте аддон

В .storybook/main.ts:

import type { StorybookConfig } from 'storybook/internal/types';
import { lightTheme, darkTheme } from './themes';

const config: StorybookConfig = {
  addons: [
    // ... другие аддоны
    {
      name: 'sb-theme-switcher',
      options: {
        themes: [
          {
            id: 'light',
            title: 'Светлая',
            class: 'light-theme',
            color: '#ffffff',
            storybookTheme: lightTheme
          },
          {
            id: 'dark',
            title: 'Темная',
            class: 'dark-theme',
            color: '#1a1a1a',
            storybookTheme: darkTheme
          },
          {
            id: 'blue',
            title: 'Синяя',
            class: 'blue-theme',
            color: '#167FFB',
            storybookTheme: blueTheme
          }
        ],
        defaultTheme: 'light',
        storageKey: 'my-app-theme'
      }
    }
  ]
};

export default config;

3. Включите поддержку Docs (опционально)

В .storybook/preview.tsx:

import { DocsContainer } from 'sb-theme-switcher';
import { lightTheme, darkTheme } from './themes';

const themes = [
  {
    id: 'light',
    title: 'Светлая',
    class: 'light-theme',
    storybookTheme: lightTheme
  },
  {
    id: 'dark',
    title: 'Темная',
    class: 'dark-theme',
    storybookTheme: darkTheme
  }
];

export const parameters = {
  docs: {
    container: props => <DocsContainer {...props} themes={themes} />
  }
};

4. Добавьте CSS для тем

В вашем глобальном CSS (например, preview-head.html или основной CSS файл):

[data-theme='light-theme'] {
  --background: #ffffff;
  --text-color: #000000;
  /* ... ваши переменные светлой темы */
}

[data-theme='dark-theme'] {
  --background: #1a1a1a;
  --text-color: #ffffff;
  /* ... ваши переменные темной темы */
}

Параметры конфигурации

Объект Theme

interface Theme {
  id: string; // Уникальный идентификатор
  title: string; // Отображаемое имя в выпадающем списке
  class: string; // CSS класс, применяемый к document.documentElement
  color?: string; // Цветовой индикатор в выпадающем списке
  storybookTheme: object; // Объект темы Storybook
  icon?: string | React.ComponentType; // Кастомная иконка (SVG строка или компонент)
}

Опции аддона

interface ThemeSwitcherOptions {
  themes: Theme[]; // Массив тем (минимум 2)
  defaultTheme?: string; // ID темы по умолчанию
  storageKey?: string; // Ключ localStorage (по умолчанию: 'sb-theme-switcher')
  icons?: Record<string, string | React.ComponentType>; // Кастомные иконки для тем
}

Примеры

Пример 1: Две темы (переключатель)

{
  name: 'sb-theme-switcher',
  options: {
    themes: [
      {
        id: 'light',
        title: 'Светлая',
        class: 'light-theme',
        storybookTheme: lightTheme
      },
      {
        id: 'dark',
        title: 'Темная',
        class: 'dark-theme',
        storybookTheme: darkTheme
      }
    ]
  }
}

Результат: кнопка-переключатель с иконками солнца/луны

Пример 2: Множество тем (выпадающий список)

{
  name: 'sb-theme-switcher',
  options: {
    themes: [
      {
        id: 'light',
        title: 'Светлая',
        class: 'light-theme',
        color: '#ffffff',
        storybookTheme: lightTheme
      },
      {
        id: 'dark',
        title: 'Темная',
        class: 'dark-theme',
        color: '#1a1a1a',
        storybookTheme: darkTheme
      },
      {
        id: 'blue',
        title: 'Синяя',
        class: 'blue-theme',
        color: '#167FFB',
        storybookTheme: blueTheme
      }
    ],
    defaultTheme: 'light'
  }
}

Результат: выпадающий список с цветовыми индикаторами

Пример 3: Кастомные иконки

{
  name: 'sb-theme-switcher',
  options: {
    themes: [
      {
        id: 'light',
        title: 'Светлая',
        class: 'light-theme',
        storybookTheme: lightTheme,
        icon: '<svg>...</svg>' // Кастомная SVG строка
      },
      {
        id: 'dark',
        title: 'Темная',
        class: 'dark-theme',
        storybookTheme: darkTheme,
        icon: MyCustomIcon // React компонент
      }
    ]
  }
}

Как это работает

Автоматическая синхронизация тем

Когда вы переключаете темы, sb-theme-switcher автоматически обновляет:

  1. Интерфейс Storybook Manager - весь интерфейс Storybook (боковая панель, тулбар, панели) меняет тему
  2. Iframe превью - ваши компоненты в превью получают обновленный атрибут data-theme
  3. Страницы Docs - страницы документации автоматически переключаются на выбранную тему

Это главное преимущество перед другими решениями, которые изменяют только превью или требуют ручной настройки декораторов.

Технические детали

  1. Manager UI: добавляет кнопку в тулбар (переключатель для 2 тем) или выпадающий список (для 3+ тем)
  2. Применение темы:
    • Применяет объект темы Storybook к manager UI через addons.setConfig()
    • Устанавливает атрибут data-theme на document.documentElement iframe превью
    • Отправляет postMessage в превью для мгновенной синхронизации
  3. Сохранение: сохраняет выбранную тему в localStorage с настраиваемым ключом
  4. Синхронизация между вкладками: слушает события storage для синхронизации между вкладками
  5. Поддержка Docs: кастомный DocsContainer с MutationObserver для реактивного обновления темы

Сравнение с storybook-dark-mode

| Функция | sb-theme-switcher | storybook-dark-mode | | ------------------------ | ---------------------------- | -------------------------- | | Количество тем | Неограниченно (2+) | Только 2 (светлая/темная) | | Синхронизация Manager UI | ✅ Автоматическая | ❌ Ручная настройка | | Синхронизация Preview | ✅ Автоматическая | ✅ Через декоратор | | Синхронизация Docs | ✅ Автоматическая | ⚠️ Требует настройки | | Адаптация UI | Умная (переключатель/список) | Только переключатель | | Кастомные иконки | ✅ Для каждой темы | ✅ Глобально | | Цветовые индикаторы | ✅ Да | ❌ Нет | | Сложность настройки | Низкая (один конфиг) | Средняя (нужны декораторы) | | Поддержка Storybook 7-10 | ✅ Да | ⚠️ Ограниченная |

Совместимость

  • Storybook: 7.x, 8.x, 9.x, 10.x
  • React: 16.8+, 17.x, 18.x, 19.x
  • TypeScript: 5.x

Решение проблем

Тема не применяется к превью

Убедитесь, что у вас есть CSS правила для классов тем:

[data-theme='your-theme-class'] {
  /* ваши переменные темы */
}

Тема не сохраняется

Проверьте, что storageKey уникален и не конфликтует с другими ключами localStorage.

Docs не обновляются

Убедитесь, что вы настроили DocsContainer в .storybook/preview.tsx и передали проп themes.

API Reference

Экспорты

// Основные экспорты
export { DocsContainer } from 'sb-theme-switcher';
export { useTheme } from 'sb-theme-switcher';
export { withTheme } from 'sb-theme-switcher';

// Типы
export type { Theme, ThemeSwitcherOptions, StorybookTheme, ThemeState } from 'sb-theme-switcher';

Хук useTheme()

React хук для чтения текущей темы в ваших компонентах:

import { useTheme } from 'sb-theme-switcher';

function MyComponent() {
  const theme = useTheme(); // Возвращает текущий класс темы, например, 'dark-theme'
  return <div>Текущая тема: {theme}</div>;
}

Миграция с storybook-dark-mode

Переход с storybook-dark-mode очень простой:

Было (storybook-dark-mode)

// .storybook/preview.tsx
import { themes } from '@storybook/theming';

export const parameters = {
  darkMode: {
    dark: { ...themes.dark },
    light: { ...themes.light }
  }
};

// Нужны декораторы для превью
export const decorators = [withTheme];

Стало (sb-theme-switcher)

// .storybook/main.ts
import { lightTheme, darkTheme } from './themes';

export default {
  addons: [
    {
      name: 'sb-theme-switcher',
      options: {
        themes: [
          { id: 'light', title: 'Светлая', class: 'light-theme', storybookTheme: lightTheme },
          { id: 'dark', title: 'Темная', class: 'dark-theme', storybookTheme: darkTheme }
        ]
      }
    }
  ]
};

// Декораторы не нужны! Всё работает автоматически

Преимущества:

  • ✅ Не требуются декораторы
  • ✅ Тема Manager UI меняется автоматически
  • ✅ Тема Preview меняется автоматически
  • ✅ Тема Docs меняется автоматически
  • ✅ Можно добавить больше 2 тем в любой момент

Лицензия

MIT

Участие в разработке

Приветствуются любые вклады! Пожалуйста, откройте issue или PR на GitHub.

Благодарности

Вдохновлено storybook-dark-mode и потребностями современных дизайн-систем в переключении тем.