@storybook/addon-themes
Version:
Switch between multiple themes for you components in Storybook
8 lines (6 loc) • 2.75 kB
JavaScript
import { useParameter, useGlobals, addons, useAddonState, useChannel, types } from 'storybook/internal/manager-api';
import React from 'react';
import { IconButton, WithTooltip, TooltipLinkList } from 'storybook/internal/components';
import { styled } from 'storybook/internal/theming';
import { PaintBrushIcon } from '@storybook/icons';
var PARAM_KEY="themes",ADDON_ID=`storybook/${PARAM_KEY}`,GLOBAL_KEY="theme",THEME_SWITCHER_ID=`${ADDON_ID}/theme-switcher`,DEFAULT_ADDON_STATE={themesList:[],themeDefault:void 0},DEFAULT_THEME_PARAMETERS={},THEMING_EVENTS={REGISTER_THEMES:`${ADDON_ID}/REGISTER_THEMES`};var IconButtonLabel=styled.div(({theme})=>({fontSize:theme.typography.size.s2-1})),hasMultipleThemes=themesList=>themesList.length>1,hasTwoThemes=themesList=>themesList.length===2,ThemeSwitcher=React.memo(function(){let{themeOverride,disable}=useParameter(PARAM_KEY,DEFAULT_THEME_PARAMETERS),[{theme:selected},updateGlobals,storyGlobals]=useGlobals(),fromLast=addons.getChannel().last(THEMING_EVENTS.REGISTER_THEMES),initializeThemeState=Object.assign({},DEFAULT_ADDON_STATE,{themesList:fromLast?.[0]?.themes||[],themeDefault:fromLast?.[0]?.defaultTheme||""}),[{themesList,themeDefault},updateState]=useAddonState(THEME_SWITCHER_ID,initializeThemeState),isLocked=GLOBAL_KEY in storyGlobals||!!themeOverride;useChannel({[THEMING_EVENTS.REGISTER_THEMES]:({themes,defaultTheme})=>{updateState(state=>({...state,themesList:themes,themeDefault:defaultTheme}));}});let themeName=selected||themeDefault,label="";if(isLocked?label="Story override":themeName&&(label=`${themeName} theme`),disable)return null;if(hasTwoThemes(themesList)){let currentTheme=selected||themeDefault,alternateTheme=themesList.find(theme=>theme!==currentTheme);return React.createElement(IconButton,{disabled:isLocked,key:THEME_SWITCHER_ID,active:!themeOverride,title:"Theme",onClick:()=>{updateGlobals({theme:alternateTheme});}},React.createElement(PaintBrushIcon,null),label?React.createElement(IconButtonLabel,null,label):null)}return hasMultipleThemes(themesList)?React.createElement(WithTooltip,{placement:"top",trigger:"click",closeOnOutsideClick:!0,tooltip:({onHide})=>React.createElement(TooltipLinkList,{links:themesList.map(theme=>({id:theme,title:theme,active:selected===theme,onClick:()=>{updateGlobals({theme}),onHide();}}))})},React.createElement(IconButton,{key:THEME_SWITCHER_ID,active:!themeOverride,title:"Theme",disabled:isLocked},React.createElement(PaintBrushIcon,null),label&&React.createElement(IconButtonLabel,null,label))):null});addons.register(ADDON_ID,()=>{addons.add(THEME_SWITCHER_ID,{title:"Themes",type:types.TOOL,match:({viewMode,tabId})=>!!(viewMode&&viewMode.match(/^(story|docs)$/))&&!tabId,render:ThemeSwitcher,paramKey:PARAM_KEY});});