[英]How to select parent components variant in styled components?
In styled-components
we can add contextual styles using component selector pattern .在
styled-components
中,我们可以使用组件选择器模式添加上下文 styles。 But how do we select specific parents variants to contextually style the child component?但是我们如何 select 特定的父变体以上下文样式设置子组件? For example, we have three components here,
Child
, NoteWrapper
, and Note
.例如,我们这里有三个组件,
Child
、 NoteWrapper
和Note
。
const Child = styled.div<{ editing?: boolean }>`
${props => props.editing && css`some styles`}
`
const NoteWrapper = styled.div<{ compact?: boolean }>`
${props => props.compact && css`some styles`}
`
const Note = styled.input`
/* How do I style this when Child is editing and NoteWrapper is compact */
`
const App = () => {
return (
<Child editing>
<NoteWrapper compact>
<Note/>
</NoteWrapper>
</Child>
)
}
`
With plain CSS we could do something like this使用普通的 CSS 我们可以做这样的事情
.child.editing .note-wrapper.compact .note {
/* Contextual styles here */
}
I know I can easily use the editing
and compact
variables and pass it to the Note
component.我知道我可以轻松地使用
editing
和compact
变量并将其传递给Note
组件。 However, it would be difficult to do so if components are highly nested.但是,如果组件高度嵌套,则很难做到这一点。
My question is how do I style Note
when Child
is editing
and NoteWrapper
is compact
in styled-components
selector pattern?我的问题是当
Child
正在editing
并且NoteWrapper
在styled-components
选择器模式中compact
时如何设置Note
样式?
I don't think we can do something like this in styled-components
in some way?我认为我们不能以某种方式在
styled-components
中做这样的事情吗? Can we?我们可以吗?
const Note = styled.input`
${Child.editingClass} ${NoteWrapper.compactClass} & {
/* The contextual styles here*/
}
`
As far as I know, you can't access editing
or compact
, since they're props and aren't "propagated" in CSS.据我所知,您无法访问 editor 或
compact
,因为它们是道具并且不会在editing
中“传播”。 But you can achieve the same result using either classes or data attributes.但是您可以使用类或数据属性来获得相同的结果。
Here's how I'd do it:这是我的做法:
const App = () => {
return (
<Child data-editing={true}>
<NoteWrapper data-compact={true}>
<Note/>
</NoteWrapper>
</Child>
)
}
const Child = styled.div`
`
const NoteWrapper = styled.div`
`
const Note = styled.input`
${Child}[data-editing="true"] ${NoteWrapper}[data-compact="true"] & {
/*
Only applied when Child is editing and NoteWrapper is compact
*/
color: red;
}
`
Essentially, styled-components needs to produce valid CSS at the end of the day.本质上,styled-components 需要在一天结束时生成有效的 CSS。
${Child}
will be replaced by the custom-generated classname, like .sc-abc123
. ${Child}
将被自定义生成的类名替换,例如.sc-abc123
。 And so the end result is .sc-abc123[data-editing="true"]
, which is totally-valid CSS.所以最终结果是
.sc-abc123[data-editing="true"]
,这是完全有效的 CSS。
You could also use classes, which looks a bit tidier:您还可以使用看起来更整洁的类:
const App = () => {
return (
<Child className="editing">
<NoteWrapper className="compact">
<Note/>
</NoteWrapper>
</Child>
)
}
const Child = styled.div`
`
const NoteWrapper = styled.div`
`
const Note = styled.input`
${Child}.editing ${NoteWrapper}.compact & {
/*
Only applied when Child is editing and NoteWrapper is compact
*/
color: red;
}
`
I prefer to use data-attributes because it's clear that they're used for logical purposes, and not because editing
is a CSS class with a bunch of styles.我更喜欢使用数据属性,因为很明显它们用于逻辑目的,而不是因为
editing
是 CSS class 和一堆 styles。 But that's a subjective preference, they both work equally well in terms of objective functionality:)但这是一种主观偏好,它们在客观功能方面都同样有效:)
I think it can be solved without the &
character我认为它可以在没有
&
字符的情况下解决
const Note = styled.input`
${Child.editingClass} ${NoteWrapper.compactClass} {
/* The contextual styles here*/
}
`
You could also pass the props to the Note
component itself and do a similar logic check.您还可以将 props 传递给
Note
组件本身并进行类似的逻辑检查。
<Note
compactEdit={editing && compact}
/>
const Note = styled.div`
${props =>
props.compactEdit
? css`color: red;`
: css`color: blue;`
};
`;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.