Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Styled Component dynamic tag name

I want to make a dynamic component. (the dynamic TAG will be a styled component -> emotion)

const Dynamic = ({ tag: Tag, children, ...rest }) =>
   <Tag {...rest}>
      { children }
   </Tag>

The component will be a styled component like:

const Column = styled(div)({ color: 'red' })
const Row = styled(span)({ color: 'yellow' })

This looks all nice, and working properly, BUUUUUT:

When I try use a DynamicComponent inside another DynamicComponent:

<DynamicComponent tag={Row}>
   {
      mapOver.map(item=>
         <DynamicComponent tag={Column}/>
      )
   }
</DynamicComponent>

then for some reason the Dynamic children will use the Dynamic Parent's style.

Is there anything I missing?

P.S.:

If instead of using dynamic styles, I do something like this:

<Row>
   <Column/>
</Row>

then the styles, classNames, styled tags, are applied properly.

To make it a little more clear:

enter image description here

As you can see the DynamicComponent's will use the parent's styles, classNames, styled tags... (NOT THE BEHAVIOUR I WOULD EXPECT)

like image 356
Istvan Orban Avatar asked Aug 30 '18 09:08

Istvan Orban


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.

How do you use ThemeProvider in React?

Usage. Import createTheming from the library to create a theming object. import { createTheming } from '@callstack/react-theme-provider'; const { ThemeProvider, withTheme, useTheme } = createTheming(defaultTheme); Then wrap your code in ThemeProvider component to make it available to all components.

Can I use variables in styled-components?

In SCSS, you can use variables and formulas for expressing colors, font sizes, widths and spacing variants. However, when you switch from SCSS to styled components, the syntax isn't valid anymore. Styled component files are CSS-in-JS, so they are actually JavaScript files.


1 Answers

Below example creating a dynamic tag name for a styled-component:

// All headings use the same styled-component "Heading" function
const StyledHeading = styled.div`
    font-size: ${({level}) => 4/level }em; // <- dynamic font size
    font-weight: 300;
    margin: 0;
`

// the trick here is the "as={...}" to create dynamic tag name
const Heading = ({level = 1, children}) => 
    <StyledHeading as={`h${level}`} level={level}>
        {children}
    </StyledHeading>


ReactDOM.render([
    <Heading>Hello, world!</Heading>,
    <Heading level={2}>Title 2</Heading>,
    <Heading level={3}>Title 3</Heading>
  ] ,document.body
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/styled-components.min.js"></script>

Reference:

  • "as" prop documentation
like image 75
vsync Avatar answered Oct 26 '22 17:10

vsync