最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to select parent components variant in styled components? - Stack Overflow

programmeradmin1浏览0评论

In styled-ponents we can add contextual styles using ponent selector pattern. But how do we select specific parents variants to contextually style the child ponent? For example, we have three ponents here, Child, NoteWrapper, and Note.

const Child = styled.div<{ editing?: boolean }>`
  ${props => props.editing && css`some styles`}
`

const NoteWrapper = styled.div<{ pact?: boolean }>`
  ${props => propspact && css`some styles`}
`

const Note = styled.input`

/* How do I style this when Child is editing and NoteWrapper is pact */

`

const App = () => {
  return (
   <Child editing>
    <NoteWrapper pact>
     <Note/>
    </NoteWrapper>
   </Child>
  )
}

`

With plain CSS we could do something like this


.child.editing .note-wrapperpact .note {
  /* Contextual styles here */
}

I know I can easily use the editing and pact variables and pass it to the Note ponent. However, it would be difficult to do so if ponents are highly nested.

My question is how do I style Note when Child is editing and NoteWrapper is pact in styled-ponents selector pattern?

I don't think we can do something like this in styled-ponents in some way? Can we?

const Note = styled.input`
 ${Child.editingClass} ${NoteWrapperpactClass} & {
  /* The contextual styles here*/
 }
`

In styled-ponents we can add contextual styles using ponent selector pattern. But how do we select specific parents variants to contextually style the child ponent? For example, we have three ponents here, Child, NoteWrapper, and Note.

const Child = styled.div<{ editing?: boolean }>`
  ${props => props.editing && css`some styles`}
`

const NoteWrapper = styled.div<{ pact?: boolean }>`
  ${props => props.pact && css`some styles`}
`

const Note = styled.input`

/* How do I style this when Child is editing and NoteWrapper is pact */

`

const App = () => {
  return (
   <Child editing>
    <NoteWrapper pact>
     <Note/>
    </NoteWrapper>
   </Child>
  )
}

`

With plain CSS we could do something like this


.child.editing .note-wrapper.pact .note {
  /* Contextual styles here */
}

I know I can easily use the editing and pact variables and pass it to the Note ponent. However, it would be difficult to do so if ponents are highly nested.

My question is how do I style Note when Child is editing and NoteWrapper is pact in styled-ponents selector pattern?

I don't think we can do something like this in styled-ponents in some way? Can we?

const Note = styled.input`
 ${Child.editingClass} ${NoteWrapper.pactClass} & {
  /* The contextual styles here*/
 }
`
Share Improve this question edited Nov 30, 2021 at 4:00 Bijay Shrestha asked Nov 30, 2021 at 3:53 Bijay ShresthaBijay Shrestha 871 gold badge1 silver badge7 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

As far as I know, you can't access editing or pact, since they're props and aren't "propagated" in CSS. 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-pact={true}>
      <Note/>
    </NoteWrapper>
  </Child>
  )
}

const Child = styled.div`
`

const NoteWrapper = styled.div`
`

const Note = styled.input`
  ${Child}[data-editing="true"] ${NoteWrapper}[data-pact="true"] & {
    /* 
      Only applied when Child is editing and NoteWrapper is pact
    */
    color: red;
  }

`

Essentially, styled-ponents needs to produce valid CSS at the end of the day. ${Child} will be replaced by the custom-generated classname, like .sc-abc123. And so the end result is .sc-abc123[data-editing="true"], which is totally-valid CSS.

You could also use classes, which looks a bit tidier:

const App = () => {
  return (
  <Child className="editing">
    <NoteWrapper className="pact">
      <Note/>
    </NoteWrapper>
  </Child>
  )
}

const Child = styled.div`
`

const NoteWrapper = styled.div`
`

const Note = styled.input`
  ${Child}.editing ${NoteWrapper}.pact & {
    /* 
      Only applied when Child is editing and NoteWrapper is pact
    */
    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. But that's a subjective preference, they both work equally well in terms of objective functionality :)

You could also pass the props to the Note ponent itself and do a similar logic check.

<Note
  pactEdit={editing && pact}
/>

const Note = styled.div`
  ${props =>
    props.pactEdit
      ? css`color: red;`
      : css`color: blue;`
    };
`;
发布评论

评论列表(0)

  1. 暂无评论