Back to Styled Components

Styled Component

sections/api/primary/styled-component.mdx

latest4.4 KB
Original Source

import Code from 'components/Code' import Table, { Row, Column } from 'components/Table'

StyledComponent

A styled React component. This is returned when you call styled.tagname or styled(Component) with styles.

This component can take any prop. It passes it on to the HTML node if it's a valid attribute, otherwise it only passes it into interpolated functions. (see Tagged Template Literal)

You can pass an arbitrary classname to a styled component without problem and it will be applied next to the styles defined by the styled call. (e.g. <MyStyledComp className="bootstrap__btn" />)

.attrs

This is a chainable method that attaches some props to a styled component. The first and only argument is an object that will be merged into the rest of the component's props. The attrs object accepts the following values:

<Table head={['Values', 'Description']}> <Row> <Column> <Code>Prop Value</Code> </Column> <Column> These can be of any type, except functions. They'll stay static and will be merged into the existing component props. </Column> </Row> <Row> <Column> <Code>Prop Factory</Code> </Column> <Column> A function that receives the props that are passed into the component and computes a value, that is then going to be merged into the existing component props. </Column> </Row> </Table>

Returns another StyledComponent.

react
// import styled from 'styled-components'

const Input = styled.input.attrs<{ $padding?: string; $small?: boolean; }>(props => ({
  type: 'text',
  size: props.$small ? 5 : undefined,
}))`
  border-radius: 3px;
  border: 1px solid #BF4F74;
  display: block;
  margin: 0 0 1em;
  padding: ${props => props.$padding};

  ::placeholder {
    color: #BF4F74;
  }
`

render(
  <>
    <Input $small placeholder="Small" />
    <Input placeholder="Normal" />
    <Input $padding="2em" placeholder="Padded" />
  </>
)

Learn more about this constructor in the Attaching Additional Props section.

"as" polymorphic prop | v4

If you want to keep all the styling you've applied to a component but just switch out what's being ultimately rendered (be it a different HTML tag or a different custom component), you can use the "as" prop to do this at runtime.

react
// import styled from "styled-components";

const Component = styled.div`
  color: red;
`;

render(
  <Component
    as="button"
    onClick={() => alert('It works!')}
  >
    Hello World!
  </Component>
)

This sort of thing is very useful in use cases like a navigation bar where some of the items should be links and some just buttons, but all be styled the same way.

"forwardedAs" prop | v4.3

If you choose to wrap another component with the styled() HOC that also accepts an "as" prop, use "forwardedAs" to pass along the desired prop to the wrapped component.

Transient props | v5.1

If you want to prevent props meant to be consumed by styled components from being passed to the underlying React node or rendered to the DOM element, you can prefix the prop name with a dollar sign ($), turning it into a transient prop.

In this example, $draggable isn't rendered to the DOM like draggable is.

react
const Comp = styled.div`
  color: ${props =>
    props.$draggable || 'black'};
`;

render(
  <Comp $draggable="red" draggable="true">
    Drag me!
  </Comp>
);

shouldForwardProp | v5.1

This is a more dynamic, granular filtering mechanism than transient props. It's handy in situations where multiple higher-order components are being composed together and happen to share the same prop name.shouldForwardProp works much like the predicate callback of Array.filter. A prop that fails the test isn't passed down to underlying components, just like a transient prop.

Keep in mind that, as in this example, other chainable methods should always be executed after .withConfig.

react
const Comp = styled('div').withConfig({
  shouldForwardProp: (prop) =>
      !['hidden'].includes(prop),
}).attrs({ className: 'foo' })`
  color: red;
  &.foo {
    text-decoration: underline;
  }
`;

render(
  <Comp hidden>
    Drag Me!
  </Comp>
);

Optionally, shouldForwardProp can take a second parameter that provides access to the default validator function. This function can be used as a fallback, and of course, it also works like a predicate, filtering based on known HTML attributes.