There's a new library of React components that are shared across the organization at my job, and it uses Styled Components which I don't know much about.

I know that styled components use JavaScript template literals to define the CSS for an element right in line with the element tag.

From the Styled Components docs:

// define a component
const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

const App = () => (
  // then use it in your regular React component
  <Title />
);

That's mostly what I knew about styled components at the beginning of the day.

Then I read some docs and now I know a bunch more!

Things I learned today:

  • It's important to define the styled components outside the React component where they are used, so they don't get created each time the component renders.
  • CSS defined in styled components are automatically vendor-prefixed.
  • Every styled component has an as prop that changes what the base element of the component is.
    • I'd been using the as prop when using components exported from the shared component library at work, but didn't realize it was something I could do on all components and not just, say, the <Button> component.
  • The styled component will accept any other props that the underlying element usually accepts, and passes them through to the underlying element.
    • I had been wondering how to know which props were available on shared components like <Button> - but turns out it's everything available on the base element!
  • You can also define other props that your component will accept, that perhaps change the styles on the base element.
// from https://www.styled-components.com/docs/basics#passed-props
const Button = styled.button`
  /* Adapt the colors based on primary prop */
  background: ${props => props.primary ? "palevioletred" : "white"};
  color: ${props => props.primary ? "white" : "palevioletred"};
  `
  
const Input = styled.input.attrs(props => ({
    // we can define static props
    type: "password",
    // or we can define dynamic ones
    size: props.size || "1em",
  }))`
  color: palevioletred;
  font-size: 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
  /* here we use the dynamically computed prop */
  margin: ${props => props.size};
  padding: ${props => props.size};
`;