How can I create a generic heading component using styled system and styled components?
The following works but all my heading use h1 tag.
import css from "@styled-system/css"
import styled from "styled-components"
import { color, ColorProps, textAlign, TextAlignProps, variant } from "styled-system"
type Props = {
level: 1 | 2 | 3 | 4 | 5 | 6
} & TextAlignProps &
ColorProps
const Css = css({
fontFamily: "heading",
fontWeight: "heading",
})
const Variant = variant({
prop: "level",
variants: {
1: {
fontSize: 7,
lineHeight: 7,
},
2: {
fontSize: 6,
lineHeight: 6,
},
3: {
fontSize: 5,
lineHeight: 5,
},
4: {
fontSize: 4,
lineHeight: 4,
},
5: {
fontSize: 3,
lineHeight: 3,
},
6: {
fontSize: 2,
lineHeight: 2,
},
},
})
const Heading = styled("h1")<Props>(Css, Variant, textAlign, color)
export default Heading
I tried to create a HeadingBase component like:
type Props = {
level: 1 | 2 | 3 | 4 | 5 | 6,
as: string | undefined
} & TextAlignProps &
ColorProps
const HeadingBase = ({ level, as: Component = `h${level}`, ...props }: Props) => <Component {...props} />
const Heading = styled(HeadingBase)<Props>(Css, Variant, textAlign, color)
But I get an error at the <Component {...props} />
because it doesn't have an API for TextAlignProps and ColorProps.
Perhaps you can leverage
as
so that when a variant is provided, theas
key automatically changes to the variant string. This might be easier to explain by code, take a look.