UNPKG

storybook-addon-data-theme-switcher

Version:

A Storybook addon to switch the data-theme attribute on the html element

48 lines (47 loc) 1.66 kB
import { useEffect, useGlobals, useRef } from "storybook/preview-api"; //#region src/constants.ts const ADDON_ID = "storybook/addon-data-theme-switcher"; `${ADDON_ID}`; `${ADDON_ID}`; const DATA_THEME_KEY = "dataTheme"; //#endregion //#region src/withGlobals.ts const withGlobals = (StoryFn) => { const [globals, updateGlobals] = useGlobals(); const dataTheme = globals[DATA_THEME_KEY]; const dataAttribute = globals["dataThemes"]?.dataAttribute || "data-theme"; const lastSetValue = useRef(null); if (!dataTheme || dataTheme === "none") { document.documentElement.removeAttribute(dataAttribute); globalThis.localStorage.removeItem(dataAttribute); lastSetValue.current = null; } else { document.documentElement.setAttribute(dataAttribute, dataTheme); globalThis.localStorage.setItem(dataAttribute, dataTheme); lastSetValue.current = dataTheme; } useEffect(() => { const observer = new MutationObserver(() => { const currentValue = document.documentElement.getAttribute(dataAttribute); if (currentValue !== lastSetValue.current) { lastSetValue.current = currentValue; updateGlobals({ [DATA_THEME_KEY]: currentValue ?? "none" }); } }); observer.observe(document.documentElement, { attributes: true, attributeFilter: [dataAttribute] }); return () => observer.disconnect(); }, [dataAttribute, updateGlobals]); return StoryFn(); }; //#endregion //#region src/preset/preview.ts /** * Note: if you want to use JSX in this file, rename it to `preview.tsx` * and update the entry prop in tsup.config.ts to use "src/preview.tsx", */ const preview = { decorators: [withGlobals] }; //#endregion export { preview as t };