Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Styling Nested Components in Styled-Components

I have created a Dropdown Component in React using Styled Components. Here is a simplified outline of the component:

const Dropdown = (
    <DropdownBase>
      <Trigger>
        {title}
      </Trigger>
      <Submenu>
        {children}
      </Submenu>
    </DropdownBase>
  )

const DropdownBase = styled.div`
  /* Default Styles */
`

const Trigger = styled(Link)`
  /* Default Styles */
`

const Submenu = styled.div`
  /* Default Styles */
`

Now, when I import and use the component I want to be able to override the default styles of the nested components (i.e., DropdownBase, Trigger and Submenu). And I want to be able to override those default styles using Styled Components. The problem is, that I do not import those nested components -- I only import the Dropdown component -- like this:

import { Dropdown } from '../path/to/dropdown'

<Dropdown />

So I am wondering, how can I override those nested components when I import the parent component using Styled Components?

like image 658
Moshe Avatar asked Jan 14 '20 16:01

Moshe


People also ask

How can you apply dynamic styles to styled-components?

One way to dynamically change css properties with styled components is to insert a custom prop into your React component and access said property using the dollar sign and curly braces commonly used for template literals. Our current example is testing to see if our use pointer prop is true.

Can you add Classnames to styled-components?

Finally, you can use styled-components with any CSS framework. For example, let's create a Button component with Bootstrap styling. We used the attrs method to add a className attribute to the component with btn btn-primary value.

Can I use mixin in styled-components?

While Styled Components doesn't have anything out of the box for mixins, per se, we can use it to achieve exactly what we need.

Can you style a styled-component?

Styled Components allow you to style any custom component that you've created. First, the custom component must receive the prop className and pass it to the underlying DOM element. Once that is done, pass the custom component to the styled function and invoke it as a Tagged Template to receive a new Styled Component.


2 Answers

The best way to do this would be to export DropdownBase, Trigger, and Submenu from your Dropdown component, then import them along with Dropdown and override this like this:

import { Dropdown, DropdownBase, Trigger, Submenu } from '../path/to/dropdown'
import styled from 'styled-components'

const MyComponent = () => {
  return <StyledDropdown />
}

const StyledDropdown = styled(Dropdown)`
  ${DropdownBase} {
    // custom styles
  }

  ${Trigger} {
    // custom styles
  }

  ${Submenu} {
    // custom styles
  }
`

This works well because it targets the specific child styled components.

Alternatively, you could target them based on their tag or child order, but this may fail if you make updates to the Dropdown component.

like image 62
Appel21 Avatar answered Sep 25 '22 05:09

Appel21


How about this:

const Dropdown = (
    <DropdownBase className={dropdownBaseClassName}>
      <Trigger className={triggerClassName}>
        {title}
      </Trigger>
      <Submenu className={submenuClassName}>
        {children}
      </Submenu>
    </DropdownBase>
  )
import { Dropdown } from '../path/to/dropdown'

<StyledDropdown />

const StyledDropdown = styled(Dropdown).attrs({ dropdownBaseClassName:..., triggerClassName:..., submenuClassName:... })`
.${dropdownBaseClassName} {
// styles
}
.${triggerClassName} {
// styles
}
.${submenuClassName} {
// styles
}
like image 24
Johnny Zabala Avatar answered Sep 24 '22 05:09

Johnny Zabala