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.

Overriding sx props that are not exposed via styled-system props

See original GitHub issue

What is the recommended way to override border props on an extended component, since the border props from styled-system are not available on the Box or Card components.

For example, if I create a component like this:

import { Card as BaseCard } from 'rebass/styled-components'

const Card = React.forwardRef((props, ref) => {
  return (
    <BaseCard
      ref={ref}
      as="section"
      sx={{
        borderRadius: 's',
        boxShadow: 'm',
        p: 3,
        bg: 'primaryColor',
        color: 'primaryText',
      }}
      {...props}
    />
  )
})

How can I override borderRadius when using the component? I would expect to be able to do something like this:

<Card borderRadius="m">A card with a bigger border radius</Card>

But since borderRadius styled-system prop is not available, then maybe I could try this:

<Card sx={{borderRadius: 'm'}}>A card with a bigger border radius</Card>

But this doesn’t work as expected because the sx prop from the base Card component gets completely overridden.

One workaround I have found is to do this:

import { Card as BaseCard } from 'rebass/styled-components'
import merge from 'lodash/merge'

const Card = React.forwardRef(({ sx, ...rest }, ref) => {
  return (
    <BaseCard
      ref={ref}
      as="section"
      {...rest}
      sx={merge(
        {
          borderRadius: 's',
          boxShadow: 'm',
          p: 3,
          bg: 'primaryColor',
          color: 'primaryText',
        },
        sx
      )}
    />
  )
})

Then I can do this with the expected result:

<Card sx={{borderRadius: 'm'}}>A card with a bigger border radius</Card>

But it feels pretty horrible…

Another solution is to use the __css prop that is in rebass, which also frees me up to be able to use the sx prop to apply overrides:

const Card = React.forwardRef(({ sx, ...rest }, ref) => {
  return (
    <BaseCard
      ref={ref}
      as="section"
      {...rest}
      __css={{
        borderRadius: 's',
        boxShadow: 'm',
        p: 3,
        bg: 'primaryColor',
        color: 'primaryText',
      }}
    />
  )
})

But this also feels bad because presumably __css is named with a double underscore because it’s not part of the public interface and you don’t want people using it.

Suggestions…?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
goszczynskipcommented, Sep 19, 2019

@jxnblk Solution with spreading both objects works fine until you work with objects but sx allows also a function. Current types shows errors when you try to merge that way. I’ve skimmed through rebass/styled-system repo to find some helpers for merging styles and failed to find one.

It would be nice to use css from @styled-system/css but right now it accepts only one object. Extending it that it’ll accept array will solve merging problems. It could work the same as in css from @emotion/core. https://emotion.sh/docs/composition

1reaction
jxnblkcommented, Sep 5, 2019

@palashkaria the __css API is private because it’s not an ideal solution and it could break with an update, but I would like some public API to support similar functionality. You can use the sx prop like described above for the time being

Read more comments on GitHub >

github_iconTop Results From Across the Web

Overriding styles with the sx prop | Primer React
The sx prop allows ad-hoc styling that is still theme-aware. Declare the styles you want to apply in CamelCase object notation, ...
Read more >
Build a Box - Styled System
As a general rule of thumb, you should only expose style props when it's something likely to change on a per-instance basis throughout...
Read more >
When to use the MUI 'sx' Prop, Styled API, or Theme Override
In this post I will explain the similarities and differences between sx , styled , and theme overrides in MUI. Here's an important...
Read more >
Styling themes
In a nutshell, this means that your styling is a function of props and theme. import styled from 'styled-components' import { space, color...
Read more >
The sx prop - MUI System
The sx prop lets you work with a superset of CSS that packages all of the style functions exposed in @mui/system . You...
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