Extending
Rebass components are designed to be used as foundational primitives for building a custom design system. By extending these base components, you can quickly start a component library with a consistent API and styles that are driven by design constraints that you define in your theme.
To extend a component, pass props through and define custom styles in the sx prop.
import React from 'react'import { Box } from 'rebass'const Container = props =><Box{...props}sx={{maxWidth: '1024px',mx: 'auto',px: 3,}}/>
If you prefer, you can also use @emotion/styled to extend components.
Order of Styles
Because Rebass still uses CSS, you might have to contend with the cascade, depending on how you define your styles, especially in regards to source order and using shorthand CSS properties.
Rebass components apply styles in the following order:
- Variant
sxpropcssprop- Styled System props
Shorthand CSS Properties
If you're using CSS properties that have shorthand variations, try to use the normal CSS property instead.
// avoid shorthand syntaxsx={{border: '1px solid tomato',}}
// use regular properties insteadsx={{borderWidth: '1px',borderStyle: 'solid',borderColor: 'tomato',}}
Conflicting Styles
It's easy to add conflicting styles in two different places and end up with unexpected results.
- If you're intending to use a style prop, don't use it in the
sxprop or in variants. - If you're intending to use variants, don't include conflicting styles in the
sxprop
Default Props
Instead of using the defaultProps property on your component, define defaults inline in the JSX.
The {...props} from the outside will override the ones you set on the component.
const Container = props =><BoxmaxWidth='container'px={3}mx='auto'{...props}/>
Default Variants
To set a default variant, include the variant in your theme.
variants: {badge: {color: 'white',bg: 'tomato',px: 2,},}
Then add the default prop in your component.
const Badge = props =><Boxvariant='badge'{...props}/>
Example Extensions
Avatar
const Avatar = props =><Image{...props}sx={{width: 48,height: 48,borderRadius: 9999,}}/>
Embed
const Embed = props =><Box{...props}sx={{width: '100%',height: 0,paddingBottom: (9 / 16) + '%',position: 'relative',overflow: 'hidden','& > iframe': {position: 'absolute',width: '100%',height: '100%',top: 0,bottom: 0,left: 0,border: 0}}}/>
Pre
const Pre = props =><Text{...props}as='pre'sx={{fontFamily: 'monospace',p: 2,color: 'secondary',bg: 'muted',overflowX: 'auto',}}/>
Fixed
const Fixed = props =><Box{...props}sx={{position: 'fixed'}}/>
Divider
const Divider = props =><Box{...props}as='hr'sx={{bg: 'gray',border: 0,height: 1}}/>
See the Recipes page for more examples.