System Factory
The system factory serves as an object of system-enabled JSX elements, and also a function that can be used to enable custom component receive system style props.
import { system } from '@hoverinc/design-system-react-web'System JSX Elements
Create base html elements with theme-aware style props using system.<element>
notation. For example, if you want a plain html button with ability to pass
system styles, you can write <system.button />.
<system.button
px='300'
py='200'
bg='darkAlpha.200'
rounded='300'
_hover={{ bg: 'darkAlpha.300' }}
>
Click me
</system.button>This reduces the need to create custom component wrappers and name them. This syntax is available for common html elements. See the reference for the full list of elements supported.
<system.h1 fontSize='lg'> Heading </system.h1>System factory function
This is a function that converts non-system components or jsx element to system-enabled components so you can pass style props to them.
Consider a package called react-input-autoresize, let's use the system factory
function to make possible to pass style props.
The function will infer the prop types from the wrapped component and also add system style props.
import { system } from '@hoverinc/design-system-react-web'
import Textarea from 'react-input-autoresize'
const AutoResizeInput = system(Textarea)
function Example() {
return <AutoResizeInput bg='danger.200' textStyle="body500" />
}Attaching styles
In some instances, you might need to attach specific styles to the component wrapped in the system factory
const AutoResizeInput = system(AutoResizeInput, {
baseStyle: {
bg: 'papayawhip',
color: 'danger.600',
},
})You can also use the system factory on jsx elements as well.
const Card = system('div', {
baseStyle: {
shadow: 'distance100',
rounded: '500',
bg: 'neutral.0',
},
})Allowing custom props to be forwarded
By default, the system factory only filters system-related style props from
getting to the DOM. For more fine-grained control of how and what prop should be
forwarded, pass the shouldForwardProp option.
Here's a simple example that allows all props (including style props)
to pass through except the sample prop.
const Div = system('div', {
shouldForwardProp: (prop) => !['sample'].includes(prop),
})Another example that combines the default shouldForwardProp from Blueprint
with custom logic.
import { system, shouldForwardProp } from '@hoverinc/design-system-react-web'
const Div = system('div', {
shouldForwardProp: (prop) => {
// don't forward Chakra's props
const isSystemProp = !shouldForwardProp(prop)
if (isSystemProp) return false
// else, only forward `sample` prop
return ['sample'].includes(prop)
},
})To filter non-HTML attributes, you can leverage @emotion/is-prop-valid package.
import isValidHTMLProp from '@emotion/is-prop-valid'
import { system, shouldForwardProp } from '@hoverinc/design-system-react-web'
const Div = system('div', {
shouldForwardProp: (prop) => {
// don't forward Chakra's props
const isSystemProp = !shouldForwardProp(prop)
if (isSystemProp) return false
// forward valid HTML props
const isValidProp = isValidHTMLProp(prop)
if (isValidProp) return true
// else, only forward `sample` prop
return ['sample'].includes(prop)
},
})