[英]Emotion CSS-in-JS - how to add conditional CSS based on component props?
我想要一個帶有Emotion樣式的組件,它采用最終控制樣式的道具。 例如,考慮一個GridCol
組件,它有各種改變內邊距和寬度的道具(寬度可以在不同的視口寬度之間改變)。
我想使用這樣的 API:
<GridCol gutter size="2>
// or alternatively, like this:
<GridCol gutter size={{
m: 2,
l: 4
}}>
這里發生了三件事:
gutter
是一個布爾道具,它向列添加一些水平填充size
道具可以是字符串或對象。 如果它是一個字符串,我們只需添加幾行 CSS 就可以了,但是,如果它是一個對象,我們需要根據在別處設置的斷點對象插入一些媒體查詢。Emotion 的文檔不清楚如何處理這種性質的樣式,至少我沒有見過,所以我希望能找到一個通用的解決方案。
對於gutter
道具,它是微不足道的:
const GridCol = props => styled('div')`
display: block;
box-sizing: border-box;
flex: 1 0 0;
min-width: 0;
padding: ${props.gutter ? `0 10px` : '0'};
`
對於size
道具,它變得更加復雜,我希望生成的 CSS 看起來像這樣:
const GridCol = props => styled('div')`
display: block;
box-sizing: border-box;
flex: 1 0 0;
min-width: 0;
padding: ${props.gutter ? `0 10px` : '0'};
/* styles here if `size` is a string */
width: 10%;
/* styles here if `size` is an object */
@media screen and (min-width: 500px) {
width: 20%;
}
@media screen and (min-width: 800px) {
width: 30%;
}
@media screen and (min-width: 1100px) {
width: 40%;
}
`
width
值將由 prop 的 key 決定,它對應於breakpoints
對象中的一個值,這部分不是微不足道的,但我不知道如何動態生成所需的 css。
我確定我可以添加更多信息,我進行了一些嘗試,但目前都沒有工作。 我的感覺是我應該創建一個無狀態的功能組件,為每個條件生成 css,然后在最后加入 CSS..
這是一個很好的問題。 首先,避免這種模式。
const GridCol = props => styled('div')`
display: block;
box-sizing: border-box;
flex: 1 0 0;
min-width: 0;
padding: ${props.gutter ? `0 10px` : '0'};
`
在這個例子中,在每次渲染時都會創建一個新的樣式組件,這對性能來說很糟糕。
任何表達式或插值都可以是函數。 此函數將接收 2 個參數: props
和context
const GridCol = styled('div')`
display: block;
box-sizing: border-box;
flex: 1 0 0;
min-width: 0;
padding: ${props => props.gutter ? `0 10px` : '0'};
`
至於您示例中的size
道具,我將使用以下模式。
import { css } from 'emotion'
const sizePartial = (props) => typeof props.size === 'string' ?
css`width: 10%;` :
css`
@media screen and (min-width: 500px) {
width: 20%;
}
@media screen and (min-width: 800px) {
width: 30%;
}
@media screen and (min-width: 1100px) {
width: 40%;
}
`
然后,您可以像在表達式中出現的任何其他函數一樣使用部分。
const GridCol = styled('div')`
display: block;
box-sizing: border-box;
flex: 1 0 0;
min-width: 0;
padding: ${props => props.gutter ? `0 10px` : '0'};
${sizePartial};
`
這是一個非常強大的模式,可用於在您的項目中組合可重用的動態樣式。
如果您對利用此模式的其他庫感興趣,請查看https://github.com/emotion-js/facepaint和https://github.com/jxnblk/styled-system
如果您正在尋找一種使用 Emotion 的css
道具實現條件樣式的方法,您可以執行以下操作:
import { css } from '@emotion/core';
const styles = ({ isSelected }) => css`
border: solid 1px black;
border-radius: 10px;
padding: 16px;
cursor: pointer;
${isSelected === true &&
`
background-color: #413F42;
color: white;
`}
`;
const ConditionalComponent = () => {
const [isSelected, setIsSelected] = useState(false);
return (
<div css={styles({ isSelected })} onClick={() => setIsSelected(!isSelected)}>
Click here to change styles.
</div>
);
};
此處有更多詳細信息: https : //seanconnolly.dev/emotion-conditionals
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.