如何在 Storybook 6.0 中自定义深色和浅色主题 [英] How to customize both dark and light themes in Storybook 6.0

查看:38
本文介绍了如何在 Storybook 6.0 中自定义深色和浅色主题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用明暗主题制作 PWA,我想创建我的 Storybook 明暗主题来反映这些主题.

I am making a PWA using light and dark themes, and I want to create my Storybook light and dark themes to reflect those.

所以我创建了一个函数,如果我向它传递一个 Material UI 主题和一个基本名称,它将返回一个新的 Storybook 主题对象给我.

So I created a function that will return a new Storybook theme object to me if I pass it a Material UI Theme and a base name.

但是如何将这 2 个对象作为主题传递给 Storybook?

But how do I pass these 2 objects to Storybook as themes?

我发现我应该去 manager.js 并添加以下代码

I have found out that I am supposed to go to manager.js and add the following code

import theme from '../src/theme/theme'
import createThemeFromMUITheme from './create-theme-from-mui-theme'
import addons from '@storybook/addons'

addons.setConfig({
  theme: createThemeFromMUITheme('light', theme.light),
})

但是我如何设置明暗主题?

But how do I set theme for both light and dark?

我试过了

import theme from '../src/theme/theme'
import createThemeFromMUITheme from './create-theme-from-mui-theme'
import addons from '@storybook/addons'

addons.setConfig({
  theme: {
    light: createThemeFromMUITheme('light', theme.light),
    dark: createThemeFromMUITheme('dark', theme.dark)
  },
})

但这使得故事书什么都没有显示(但是它并没有失败)

But that makes the storybook show nothing (it does not fail however)

请帮忙:-)

我也尝试了以下

import theme from '../src/theme/theme'
import createThemeFromMUITheme from './create-theme-from-mui-theme'
import addons from '@storybook/addons'

addons.setConfig({
  theme: createThemeFromMUITheme('light', theme.light),
})

addons.setConfig({
  theme: createThemeFromMUITheme('dark', theme.dark),
})

编辑 #2:从 createThemeFromMUITheme 返回的主题配置对象是有效的 BTW

EDIT #2: The returned theme config object from createThemeFromMUITheme is valid BTW

如果有人想要我制作的将 MUI 主题对象转换为 SB 主题对象的功能 - 那么就是这样...

And if anyone should want the function I made to convert a MUI theme object into a SB theme object - then this is it...

(我还没有弄乱表单颜色...)

(I did not mess with form colors yet...)

import { create } from '@storybook/theming/create'

const createThemeFromMUITheme = (name, theme) => {
  return create({
    base: name,

    colorPrimary: theme.palette.primary.main,
    colorSecondary: theme.palette.secondary.main,

    // UI
    appBg: theme.palette.background.default,
    appContentBg: theme.palette.background.paper,
    appBorderColor: theme.palette.background.paper,
    appBorderRadius: theme.shape.borderRadius,

    // Typography
    fontBase: theme.typography.fontFamily,
    fontCode: 'monospace',

    // Text colors
    textColor: theme.palette.text.primary,
    textInverseColor: theme.palette.text.secondary,

    // Toolbar default and active colors
    barTextColor: theme.palette.text.primary,
    barSelectedColor: theme.palette.text.secondary,
    barBg: theme.palette.background.default,

    brandTitle: 'Add your brand title here',
    brandUrl: 'https://yourbrandurl.com',
    brandImage: 'https://placehold.it/350x150',
  })
}

export default createThemeFromMUITheme

推荐答案

嗯 - 解决方案就在我眼前,但像往常一样,我没有充分阅读文档.

Well - the solution was staring me right in the eyes, but as usual I had not read the documentation enough.

我确实安装了 storybook-dark-theme,我的想法是完全集成 MUI,这样浅色主题将显示我的应用程序浅色主题,而深色主题将显示我的深色主题 - 组件也是如此.

I did have storybook-dark-theme installed, and my idea was to have MUI fully integrated so that the light theme will show my application light theme, and the dark theme will show my dark theme - and the components likewise.

通过这种方式,明暗主题切换器变得完全全局化.

This way the light/dark theme switcher becomes fully global.

不过,它确实比你写的要多一点.

It does however take a little more than what you wrote.

这就是我的目标

您可以从这里下载所有内容使用解决方案链接到我的 github

And you can download all of it from here Link to my github with the solution

当故事书第一次渲染时,它将使用默认主题,因此您会在使用踢球覆盖的明/暗主题之前看到一些闪烁.

When storybook renders first time it will use the default theme, and as such you will get some flickering before the light/dark themes you have been overriding with kicks in.

第一次点击将使其保持浅色主题,但现在它将使用您的浅色主题.

First click will make it remain light theme, but now it will use YOUR light theme.

解决这个问题的方法是在manager.ts中使用light主题进行初始化

The solution to this is to initialize with the light theme in manager.ts like so

import { addons } from '@storybook/addons'
import { theme as appTheme } from '../src/theme/theme'
import { createThemeFromMuiTheme } from './utils/create-theme-from-mui-theme'

addons.setConfig({
    theme: createThemeFromMuiTheme({
        theme: appTheme.light,
        options: {
            base: 'light',
            brandTitle: 'Storybook with MUI',
            brandUrl: 'https://www.github.com/IgorSzyporyn/storybook-with-mui'
        },
    })
})

然后在 preview.ts 中,您需要像这样设置明/暗覆盖

And then in preview.ts you need to then set the light/dark overrides like so

import React from 'react'
import { addDecorator } from '@storybook/react'
import { theme as appTheme } from '../src/theme/theme'
import { WithMuiTheme } from './components/WithMuiTheme'
import { createThemeFromMuiTheme } from './utils/create-theme-from-mui-theme'

addDecorator((story) => <WithMuiTheme>{story()}</WithMuiTheme>)

export const parameters = {
    exportedParameter: 'exportedParameter',
    darkMode: {
        current: 'light',
        light: createThemeFromMuiTheme({ theme: appTheme.light, asStorybookTheme: false }),
        dark: createThemeFromMuiTheme({ theme: appTheme.dark, asStorybookTheme: false })
    },
}

让你的装饰器包装器像这样./components/WithMuiThemeProps

And have your decorator wrapper made like this ./components/WithMuiThemeProps

import React from 'react'
import { MuiThemeProvider, CssBaseline, StylesProvider } from '@material-ui/core'
import { useThemeType } from '../hooks/UseThemeType'
import { theme } from '../../src/theme/theme'

type WithMuiThemeProps = {
    children: React.ReactNode
}

export const WithMuiTheme = ({ children }: WithMuiThemeProps) => {
    const themeType = useThemeType()

    return (
        <MuiThemeProvider theme={theme[themeType]}>
            <CssBaseline />
            <StylesProvider injectFirst>{children}</StylesProvider>
        </MuiThemeProvider>
    )
}

这是使更新发生的钩子./hooks/UseThemeType.ts

import React from 'react'
import addons from '@storybook/addons'

const channel = addons.getChannel()

export const useThemeType = () => {
    const [isDark, setDark] = React.useState(false)

    React.useEffect(() => {
        channel.on('DARK_MODE', setDark)
        return () => channel.off('DARK_MODE', setDark)
    }, [channel, setDark])

    const paletteType = isDark ? 'dark' : 'light'

    return paletteType
}

最后是 ./utils/create-theme-from-mui-theme.ts

import { create } from '@storybook/theming/create'
import { Theme } from '@material-ui/core'

type CreateThemFromMuiTheme = {
    theme: Theme
    options?: Object
    asStorybookTheme?: boolean
}

export const createThemeFromMuiTheme = ({
    theme,
    options = {},
    asStorybookTheme = true,
}: CreateThemFromMuiTheme) => {
    const themeValue = {
        colorPrimary: theme.palette.primary.main,
        colorSecondary: theme.palette.secondary.main,

        // UI
        appBg: theme.palette.background.paper,
        appContentBg: theme.palette.background.default,
        appBorderColor: theme.palette.background.paper,
        appBorderRadius: theme.shape.borderRadius,

        // Typography
        fontBase: theme.typography.fontFamily,
        fontCode: 'monospace',

        // Text colors
        textColor: theme.palette.text.primary,
        textInverseColor: theme.palette.text.secondary,

        // Toolbar default and active colors
        barTextColor: theme.palette.text.secondary,
        barSelectedColor: theme.palette.secondary.main,
        barBg: theme.palette.background.default,

        // Form color
        inputBg: 'transparent',
        inputBorder: 'silver',
        inputTextColor: theme.palette.text.primary,
        inputBorderRadius: theme.shape.borderRadius,

        ...options,
    }

    return asStorybookTheme ? create(themeValue) : themeValue
}

现在您将能够使用完全集成到 Storybook 中的主题 - 当您切换 Storybook 主题时,Storybook 本身将更改为主题并且您使用的组件也会发生变化.

And now you will be able to use the theme fully integrated into Storybook - when you switch storybook theme then Storybook itself will change into the theme AND the components you use will change as well.

这篇关于如何在 Storybook 6.0 中自定义深色和浅色主题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆