样式组件的多个道具选项
Multiple Props Options for Styled Components
我有一个使用样式化组件创建的导航栏组件。我想创建一些道具来改变背景颜色 and/or 文本颜色。
例如:<Navbar dark>
应该有以下 CSS:
background: #454545;
color: #fafafa;
而<Navbar light>
应该是相反的:
background: #fafafa;
color: #454545;
但是,如果两个道具都没有使用,那么我想要一个默认的背景和文本颜色——比如(出于演示目的),像这样:
background: #eee;
color: #333;
现在,我的问题是如何在样式化组件中进行设置。
我可以做到以下几点:
background: ${props => props.dark ? #454545 : '#eee'}
background: ${props => props.dark ? #fafafa : '#eee'}
background: #eee;
颜色也类似。
但是这是多余的而且不是很优雅。我想要某种 if/else 语句:
background: ${ props => {
if (props.dark) { #454545 }
elseif (props.light) { #fafafa }
else { #eee }
}
但我不知道如何在样式组件中设置类似的东西。
有什么建议吗?
提前致谢。
保持传入的 prop
名称相同。然后你可以使用 switch/case
语句。例如,传入 color
属性并将其用作 type
以匹配 case
.
工作示例:
例如:
<Button color="primary">Example</Button>
components/Button
import styled from "styled-components";
const handleColorType = color => {
switch (color) {
case "primary":
return "#03a9f3";
case "danger":
return "#f56342";
default:
return "#fff";
}
};
const Button = styled.button`
display: block;
cursor: pointer;
border: 0;
margin: 5px 0;
background: #000;
font-size: 20px;
color: ${({ color }) => handleColorType(color)};
&:focus {
outline: 0;
}
`;
export default Button;
如果您有多个属性(如一对 color
和一对 background
),则使用与上述相同的概念,将 handleColorType
更改为 return string
具有属性并调用 handleColorType
函数 没有 样式 属性.
例如:
<MultiButton color="primary">Example</MultiButton>
components/MultiButton
import styled from "styled-components";
const handleColorType = color => {
switch (color) {
case "primary":
return "color: #03a9f3; background: #000;";
case "danger":
return "color: #fff; background: #f56342;";
default:
return "color: #000; background: #eee;";
}
};
const MultiButton = styled.button`
display: block;
margin: 5px 0;
cursor: pointer;
border: 0;
font-size: 20px;
${({ color }) => handleColorType(color)};
&:focus {
outline: 0;
}
`;
export default MultiButton;
这是我最终使用的解决方案:
export const Navbar = styled.nav`
width: 100%;
... // rest of the regular CSS code
${props => {
if (props.dark) {
return `
background: ${colors.dark};
color: ${colors.light};
`
} else if (props.light) {
return `
background: ${colors.light};
color: ${colors.dark};
`
} else {
return `
background: ${colors.light};
color: ${colors.dark};
`
}
}}
`
你也可以这样做:
const colorType= {
dark: '#454545',
light: '#0a0a0a',
normal: '#dedede'
};
export const Navbar= styled.nav`
background: ${({color}) => colorType[color] || `${color}`};
`;
给你:
<Navbar color="primary" />
<Navbar color="#FFFFFF" />
更优雅(我猜)和现代的东西是解构道具和使用 switch 语句的组合,例如:
const Button = styled.button`
${({primary, secondary}) => {
switch(true) {
case primary:
return `background-color : green`
case secondary:
return `background-color : red`
}
}
}
`
样式化组件还接受一个函数,您可以在其中读取道具。此外,如果您选择传递一个主题道具,您还可以为您的主题定义一个对象。
const themes = {
dark: css `
background: ${colors.dark};
color: ${colors.light};
`,
light: css`
background: ${colors.light};
color: ${colors.dark};
`
}
export const Navbar = styled.nav(({theme})=>`
width: 100%;
background: ${colors.light};
color: ${colors.dark};
... // rest of the css
${theme?themes[theme]:''}
`)
<Navbar theme="dark" />
解决方案使用Styled-tools
在你的具体情况下
因为你只有两个主题,一个是默认的light
,一个是你可以切换的dark
,你只需要检查它是否是黑暗模式。
import {ifProp} from "styled-tools";
export const Navbar = styled.nav`
${ifProp("dark",
css`
background: ${colors.dark};
color: ${colors.light};
`,
css`
background: ${colors.light};
color: ${colors.dark};
`,
)}
`;
并使用 <Navbar $dark={isDarkMode} />
渲染
更通用的解决方案
当然,您仍然想使用 dark/light 等主题方法。设置变体会让事情变得更容易。例如,您可以在单独的枚举中跟踪您想要的不同主题。像这样:
enum Themes {
DARK = "dark",
LIGHT = "light",
}
稍后在您的样式中您可以指定:
import {switchProp} from "styled-tools";
export const Navbar = styled.nav`
${switchProp({
dark: css`
background: ${colors.dark};
color: ${colors.light};
`,
light: css`
background: ${colors.light};
color: ${colors.dark};
`,
})}
`;
然后渲染 <Navbar variant={Theme.LIGHT} />
或 <Navbar variant={Theme.DARK} />
参考资料
怎么样:
const StyledButton = styled.button`
padding: 8px 16px;
border-radius: ${props => props.rounded ? '10px' : '0px'};
${props => {
switch (props.type) {
case 'primary':
return `
background-color : #000;
color: #fff;
border: 1px solid #000000;
`;
case 'secondary':
return `
background-color : #DEDEDE;
border: 1px solid #999;
`;
}
}
}`;
我有一个使用样式化组件创建的导航栏组件。我想创建一些道具来改变背景颜色 and/or 文本颜色。
例如:<Navbar dark>
应该有以下 CSS:
background: #454545;
color: #fafafa;
而<Navbar light>
应该是相反的:
background: #fafafa;
color: #454545;
但是,如果两个道具都没有使用,那么我想要一个默认的背景和文本颜色——比如(出于演示目的),像这样:
background: #eee;
color: #333;
现在,我的问题是如何在样式化组件中进行设置。
我可以做到以下几点:
background: ${props => props.dark ? #454545 : '#eee'}
background: ${props => props.dark ? #fafafa : '#eee'}
background: #eee;
颜色也类似。
但是这是多余的而且不是很优雅。我想要某种 if/else 语句:
background: ${ props => {
if (props.dark) { #454545 }
elseif (props.light) { #fafafa }
else { #eee }
}
但我不知道如何在样式组件中设置类似的东西。
有什么建议吗?
提前致谢。
保持传入的 prop
名称相同。然后你可以使用 switch/case
语句。例如,传入 color
属性并将其用作 type
以匹配 case
.
工作示例:
例如:
<Button color="primary">Example</Button>
components/Button
import styled from "styled-components";
const handleColorType = color => {
switch (color) {
case "primary":
return "#03a9f3";
case "danger":
return "#f56342";
default:
return "#fff";
}
};
const Button = styled.button`
display: block;
cursor: pointer;
border: 0;
margin: 5px 0;
background: #000;
font-size: 20px;
color: ${({ color }) => handleColorType(color)};
&:focus {
outline: 0;
}
`;
export default Button;
如果您有多个属性(如一对 color
和一对 background
),则使用与上述相同的概念,将 handleColorType
更改为 return string
具有属性并调用 handleColorType
函数 没有 样式 属性.
例如:
<MultiButton color="primary">Example</MultiButton>
components/MultiButton
import styled from "styled-components";
const handleColorType = color => {
switch (color) {
case "primary":
return "color: #03a9f3; background: #000;";
case "danger":
return "color: #fff; background: #f56342;";
default:
return "color: #000; background: #eee;";
}
};
const MultiButton = styled.button`
display: block;
margin: 5px 0;
cursor: pointer;
border: 0;
font-size: 20px;
${({ color }) => handleColorType(color)};
&:focus {
outline: 0;
}
`;
export default MultiButton;
这是我最终使用的解决方案:
export const Navbar = styled.nav`
width: 100%;
... // rest of the regular CSS code
${props => {
if (props.dark) {
return `
background: ${colors.dark};
color: ${colors.light};
`
} else if (props.light) {
return `
background: ${colors.light};
color: ${colors.dark};
`
} else {
return `
background: ${colors.light};
color: ${colors.dark};
`
}
}}
`
你也可以这样做:
const colorType= {
dark: '#454545',
light: '#0a0a0a',
normal: '#dedede'
};
export const Navbar= styled.nav`
background: ${({color}) => colorType[color] || `${color}`};
`;
给你:
<Navbar color="primary" />
<Navbar color="#FFFFFF" />
更优雅(我猜)和现代的东西是解构道具和使用 switch 语句的组合,例如:
const Button = styled.button`
${({primary, secondary}) => {
switch(true) {
case primary:
return `background-color : green`
case secondary:
return `background-color : red`
}
}
}
`
样式化组件还接受一个函数,您可以在其中读取道具。此外,如果您选择传递一个主题道具,您还可以为您的主题定义一个对象。
const themes = {
dark: css `
background: ${colors.dark};
color: ${colors.light};
`,
light: css`
background: ${colors.light};
color: ${colors.dark};
`
}
export const Navbar = styled.nav(({theme})=>`
width: 100%;
background: ${colors.light};
color: ${colors.dark};
... // rest of the css
${theme?themes[theme]:''}
`)
<Navbar theme="dark" />
解决方案使用Styled-tools
在你的具体情况下
因为你只有两个主题,一个是默认的light
,一个是你可以切换的dark
,你只需要检查它是否是黑暗模式。
import {ifProp} from "styled-tools";
export const Navbar = styled.nav`
${ifProp("dark",
css`
background: ${colors.dark};
color: ${colors.light};
`,
css`
background: ${colors.light};
color: ${colors.dark};
`,
)}
`;
并使用 <Navbar $dark={isDarkMode} />
更通用的解决方案
当然,您仍然想使用 dark/light 等主题方法。设置变体会让事情变得更容易。例如,您可以在单独的枚举中跟踪您想要的不同主题。像这样:
enum Themes {
DARK = "dark",
LIGHT = "light",
}
稍后在您的样式中您可以指定:
import {switchProp} from "styled-tools";
export const Navbar = styled.nav`
${switchProp({
dark: css`
background: ${colors.dark};
color: ${colors.light};
`,
light: css`
background: ${colors.light};
color: ${colors.dark};
`,
})}
`;
然后渲染 <Navbar variant={Theme.LIGHT} />
或 <Navbar variant={Theme.DARK} />
参考资料
怎么样:
const StyledButton = styled.button`
padding: 8px 16px;
border-radius: ${props => props.rounded ? '10px' : '0px'};
${props => {
switch (props.type) {
case 'primary':
return `
background-color : #000;
color: #fff;
border: 1px solid #000000;
`;
case 'secondary':
return `
background-color : #DEDEDE;
border: 1px solid #999;
`;
}
}
}`;