question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Best practice for customizing/passing styles to components in a styled-components project

See original GitHub issue

It’s a common use case that we built some small components that later want it to styled differently. Allowing passing a style prop is one way to do it. However, by doing this, we are eventually mixing inline style (when passing styles to the component) with styled-component styles.

Say we are styling a button, it’s easy to classify it as either large or small button, so size could be passed in as prop, and we can then write styles differently inside a styled-component syntax. But how about container components, where we need to change the layout of a list of other components for example. Greater flexibility is needed in this case and then passing a style prop may be the best choice?

I am curious what’s the community’s approach/opinion towards this problem? I can’t find many useful insights by Google search.

Thanks in advance for answering my question!

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:32
  • Comments:11 (1 by maintainers)

github_iconTop GitHub Comments

10reactions
episode17commented, Mar 7, 2017

I’m facing a similar issue where my components need to be highly customizable and ThemeProvider wouldn’t cut it (the theme could be any css property; for each styled components).

The solution I’m currently testing out is inspired by react-toolbox and basically involves making styled components a dependency of your more complex components through a factory.

// Thing.js
export function createThing({
    Wrapper,
    Header,
    Content
    Footer
}) {
    const Thing = ({ title, text }) => (
        <Wrapper>
            <Header>{title}</Header>
            <Content text={text} />
            <Footer />
        </Wrapper>
    );

    return Thing;
}


// Content.js
export function createContent({
    Wrapper,
    Box
}) {
    const Content = ({ text }) => (
        <Wrapper>
            <Box>I present you:</Box>
            {text}
        </Wrapper>
    );

    return Content;
}


// ThemedThing.js
import styled from 'styled-components';
import { createThing } from './Thing';
import { createContent } from './Content';

const ThemedThing = createThing({
    Wrapper: styled.div`
        ...
    `,
    Header: styled.header`
        ...
    `,
    Content: createContent({
        Wrapper: styled.div`
            ...
        `,
        Box: styled.div`
            ...
        `
    }),
    Footer: styled.footer`
        ...
    `
});

export default ThemedThing;


// Use it
import ThemedThing from './ThemedThing';

ReactDOM.render(<ThemedThing title="Thing" text="Cool" />, ...);

To leverage an existing UI kit you could:

const ThemedThing = createThing({
    SubmitButton: (props) => <Button type="submit" size="small" {...props} />
});

It would make more sense if there was more of an involved logic within Thing. Also, a themed component doesn’t need to do all the creation. You could import a common ThemedContent and pass it on instead of creating it for Thing specifically.

The author of react-toolbox is currently experimenting with this method in react-toolbox-airbnb. EDIT: The source for the core is within this branch of toolbox: react-toolbox/agnostic-components

This method works but I feel it requires a lot of boilerplate to get started and would perhaps even require validation of the dependencies or a way to express what type of component you’re expected to inject.

1reaction
sherryxiao1988commented, Apr 18, 2017

@episode17 Thanks for the information!

I really like this approach. DatePicker is a good example.

This approach is closer to my original understanding of styled-components. Naked components without styles should be easily wrapped with styles and then be plugged into other components.

However, here is the most common pattern that I found how people use styled-component(took from react-adminlte-dash):

Define the styles used for each sub components:

const StyledSection = styled.section`
  height: auto;
  padding-bottom: 10px;
  display: block;
`;

const StyledAside = styled.aside`
  ...
`;

And then hardcode those styled components in render method of the main component:

const Sidebar = ({
  children,
  fixed = false,
  sidebarMini = false,
  sidebarCollapse = false,
}) => (
  <StyledAside
    fixed={fixed}
    collapse={sidebarCollapse}
    mini={sidebarMini}
  >
    <StyledSection name="sidebar-wrapper">
      {renderChildren(children, sidebarCollapse)}
    </StyledSection>
  </StyledAside>
);

The thought process of using styled-component this way is very similar to how we style components traditionally using classnames, but isn’t it make reusing naked components (components with pure functionality and no styling) harder?

I do see the airbnb way introduces certain complexity/overhead, but I generally prefer it to the other approach. Any other thought?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Styled Components Best Practices - Robin Wieruch
If you change the style of the styled component, check all components which import it. If no component uses the style anymore, delete...
Read more >
Basics - styled-components
styled -components utilises tagged template literals to style your components. It removes the mapping between components and styles. This means that when you're ......
Read more >
How To Use React Styled Components Efficiently - Copycat
Learn how to set up organized React styled components in your project through examples, comprehensive explanations, and tips and tricks!
Read more >
How To Use Styled-Components In React - Smashing Magazine
In React's own words, styled components are “visual primitives for components”, and their goal is to give us a flexible way to style...
Read more >
The styled-components Happy Path - Josh W Comeau
styled -components is a wonderfully powerful styling library for React, and over the years ... This article shares my personal “best practices”.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found