Создание компонента React с вариациями на основе компонента Chakra-UI
Я пытаюсь создать некоторые компоненты типографики, используя
Heading
и
Text
компоненты из chakra-ui: https://chakra-ui.com/. Идея состоит в том, что эти компоненты содержат в себе все стили line-height, letter-spacing, font-weight и другие стили, которые мне нужны в одном компоненте.
Так, например,
<DisplayOne>
компонент имеет
font-size
96 пикселей, a
line-height
100% и др. А
<DisplayThree>
компонент имеет
font-weight
и
line-height
72px. И другие.
Теперь это работает, но не так элегантно, как хотелось бы. В идеале хотелось бы примерно такого:
<Heading level="d1">Display One</Heading>
<Heading level="d2">Display Two</Heading>
<Heading level="d3">Display Three</Display>
...
<Text level="small">Small Text</Text>
...
Другими словами, вместо того, чтобы иметь несколько компонентов, используйте один компонент с опорой для управления вариациями. Однако у меня возникли проблемы с тем, чтобы понять, как заставить это работать.
Прямо сейчас мой код выглядит так:
import { Heading, Text } from '@chakra-ui/core'
const TextBase = ({ children, ...rest }) => (
<Text color="darkGrey" fontWeight="semibold" lineHeight="base">
{children}
</Text>
)
const HeadingBase = ({ children, ...rest }) => (
<Heading color="dark" fontWeight="bold" letterSpacing="tight">
{children}
</Heading>
)
// Display
export const DisplayOne = ({ children, ...rest }) => (
<HeadingBase fontSize="96px" lineHeight="100%" {...rest}>
{children}
</HeadingBase>
)
export const DisplayTwo = ({ children, ...rest }) => (
<HeadingBase fontSize="88px" lineHeight="100%" {...rest}>
{children}
</HeadingBase>
)
...
// Text
export const BodyText = ({ children, ...rest }) => (
<TextBase fontSize="md" {...rest}>
{children}
</TextBase>
)
export const SmallText = ({ children, ...rest }) => (
<TextBase fontSize="sm" {...rest}>
{children}
</TextBase>
)
...
Однако я решил сделать что-то вроде этого:
import { Heading as HeadingBase, Text as TextBase } from '@chakra-ui/core'```
export const Heading = (props) => {
if (props.level === "d1") {
return <Heading fontSize="96px"...>{props.children}</Heading>
} else if (props.level === "d2") { ... }
...
}
}
Однако это кажется довольно сложным, не очень сухим, и мне интересно, есть ли более простой и / или более элегантный способ сделать это.
Есть идеи?
Благодарю.