css - 样式化组件:通过 props 传递的 hover 样式
我有一个 StyledButton,我像这样使用它:
const StyledButton = styled.div<{
hoverStyle?: CSSProperties
}>`
color: black;
background: blue;
// What can I do here to apply the hoverStyle?
`
<StyledButton
hoverStyle={{
backgroundColor: 'red',
color: 'white',
}}
>
My button
</StyledButton>
有办法做到吗?
答案#1
通常我们会在额外的样式属性中提供单个值,但仍然绝对可以提供一组 CSS 规则(CSS 对象)。
首先,你需要使用插值函数根据运行时属性调整样式:
const StyledButton = styled.div<{
hoverStyle?: CSSProperties
}>`
color: black;
background: blue;
// What can I do here to apply the hoverStyle?
${(props) => props.hoverStyle && inlineRules(props.hoverStyle)}
`
在这里,我使用了一个 inlineRules 函数将 CSSObject 转换为规则列表:
function inlineRules(rulesObj: CSSProperties) {
return Object.entries(rulesObj).map(([property, value]) => `${property}: ${value};`).join('');
}
然后,基于你样式属性的 “hoverStyle” 名称,这些规则似乎应该仅在 :hover 时应用,而不是直接与你的 <div> 的根样式合并。在这种情况下,你需要将它们放入嵌套块中,你可以使用 & 符号来引用自身样式:
&单个与号指代组件的所有实例;它用于应用广泛的覆盖
&:hover {
${(props) => props.hoverStyle && inlineRules(props.hoverStyle)}
}
CodeSandbox 上的实时演示:https://codesandbox.io/s/sleepy-brook-h515v7?file=/src/App.tsx
注意:styled-components 中的 CSS 规则实际上使用普通的“kebab-case”表示法,而 CSSProperties 则定义为 camelCase(在你的例子中是“background-color”与“backgroundColor”)。在上面的演示中,我使用了模板字面量转换类型,将它们转换为 kebab-case,这是基于 TypeScript 从实际的 camelCase 键生成 kebab-case 类型的方式。
