使用 Styled Components 进行主题化
使用 Styled Components 为 Web 应用程序创建主题的指南。
为什么要设定主题?
- 主题有助于为您的应用程序创建独特的标识。主题可以将特定颜色、长度或阴影的所有用法抽象到一个统一的地方,以便所有用例都能遵循该主题。
- 修改起来更容易。无论你当前的应用程序多么稳定,设计师总会遇到需要调换两种颜色的棘手情况。如果你的应用程序里到处都使用了颜色,那将会非常麻烦。如果你认为可以通过查找和替换来解决,请务必考虑CSS 中所有表示颜色的方法。
如何设置主题?
Styled Components 内置了一个主题提供程序ThemeProvider来帮助你完成这项工作。主题提供程序类似于React 上下文提供程序(本质上就是一个上下文提供程序)。你需要将内容包裹在主题提供程序中ThemeProvider,然后就可以开始了:
import { ThemeProvider } from 'styled-components';
function App() {
return (
<ThemeProvider theme={{}}>
<p>All the other stuff goes here...</p>
</ThemeProvider>
);
}
主题可以是任何简单的 POJO。例如:
const theme = {
colors: {
primary: `yellow`,
secondary: `red`,
}
}
return (
<ThemeProvider theme={theme}>
</ThemeProvider>
);
如何获取主题?
可以通过使用样式组件来访问主题props.theme。唯一需要注意的是,Button渲染此组件的位置应该被包裹在其父组件的某个位置,该父组件ThemeProvider提供了主题属性theme。
const Button = styled(Button)`
background-color: ${props => props.theme.primary};
`;
但是如果它没有被包裹在 `<div>` 标签中呢ThemeProvider?如果您相信创建的组件即使没有上下文父组件也能正常工作,那么您应该给它赋予一些主题defaultProps。
const Button = styled(Button)`
background-color: ${props => props.theme.colors.primary};
`;
Button.defaultProps = {
theme: {
colors: {
primary: 'transparent',
},
},
};
嵌套主题
多个主题提供程序可以相互嵌套。组件会从与其嵌套位置最近的主题提供程序中获取主题。
const Button = styled.button`
background-color: ${props => props.theme.colors.primary};
`;
const theme = {
colors: {
primary: `yellow`,
}
}
return (
<ThemeProvider theme={theme}>
<Button>Primary Button</Button>
<ThemeProvider theme={specialTheme}>
<Button>Special Button</Button>
</ThemeProvider>
</ThemeProvider>
);
Styled Components 的另一项强大功能是嵌套主题提供程序。Styled Components 会将从父组件接收到的当前主题作为参数传递给该组件,您可以使用该参数来操作主题或为其添加值。
import Navbar from "./Navbar";
const theme = (currentTheme) => ({
...currentTheme,
navbar: {
height: "6rem",
},
});
return (
<ThemeProvider theme={theme}>
<ThemeProvider theme={specialTheme}>
<Navbar />
</ThemeProvider>
</ThemeProvider>
);
变体
变体(Various)是我们创建能够根据属性(props)进行调整的组件的一种方式。您可能在一些 UI 库中见过它们:
<Button primary>Primary Button</Button>
<Button secondary>Secondary Button</Button>
传统方式
使用 styled-components,您可以根据 props 进行调整。
const Button = styled.button`
${props => props.primary && `
background-color: ${props.theme.colors.primary};
`}
${props => props.secondary && `
background-color: ${props.theme.colors.secondary};
`}
`;
风格化主题
您可以想象,传统的构建变体的方法在大规模应用时会非常麻烦,尤其是在构建设计系统时。
Styled Components 系列有一个名为styled theming 的库。它提供了一个更易于使用的 API,用于创建和维护基于变体的样式。例如,要创建一个在浅色和深色模式下显示不同的按钮:
import styled, {ThemeProvider} from 'styled-components';
import theme from 'styled-theming';
const backgroundColor = theme('mode', {
light: '#f1c40f',
dark: '#f39c12',
});
const Button = styled.div`
background-color: ${backgroundColor};
`;
export default function App() {
return (
<ThemeProvider theme={{ mode: 'light' }}>
<Button>
Primary Button
</Button>
</ThemeProvider>
);
}
好的,但如果我们需要创建这个的第二个变体呢?这就需要variants用到函数了。
import styled, {ThemeProvider} from 'styled-components';
import theme from 'styled-theming';
const backgroundColor = theme('mode', 'variant', {
primary: {
light: '#f1c40f',
dark: '#f39c12',
},
secondary: {
light: '#2ecc71',
dark: '#27ae60',
},
});
const Button = styled.div`
background-color: ${backgroundColor};
`;
export default function App() {
return (
<ThemeProvider theme={{ mode: 'light' }}>
<Button variant="primary">
Primary Button
</Button>
<Button variant="secondary">
Secondary Button
</Button>
</ThemeProvider>
);
}
你还用过哪些 styled-components 的神奇技巧✨?关于如何在 TypeScript 中使用 styled-components,请参阅我的相关文章。
文章来源:https://dev.to/boywithsilverwings/theming-with-styled-components-3ig2我每月都会发布一份简报,详细介绍当月网站平台的所有动态。您可以在 Buttondown 上阅读往期内容并订阅。