Chakra Factory
Chakra Factory
Chakra Factory는 어떤 HTML 요소든 JSX style prop을 받을 수 있는 슈퍼차지 컴포넌트로 만들어 주는 도구예요. 스타일 prop을 쉽게 활용하고 싶다면 꼭 알아두면 좋아요.
출처: 문서
본문
개요
Chakra factory는 어떤 HTML 요소로부터든 JSX style prop을 받을 수 있는 슈퍼차지 JSX 컴포넌트를 만드는 방법이에요.
import { chakra } from "@chakra-ui/react"
chakra factory는 JSX 요소로 쓰거나 factory 함수로 쓰는 두 가지 방법으로 사용할 수 있어요.
JSX 요소
Style prop은 컴포넌트에 prop으로 전달할 수 있는 CSS 속성이에요. JSX factory를 쓰면 chakra.<element> 문법으로 style prop을 지원하는 JSX 요소를 만들 수 있어요.
import { chakra } from "@chakra-ui/react"
const Button = ({ children }) => (
<chakra.button bg="blue.500" color="white" py="2" px="4" rounded="md">
{children}
</chakra.button>
)
Factory 함수
chakra 함수를 사용해서 네이티브 요소나 커스텀 컴포넌트를 변환할 수 있어요. 핵심 요건은 컴포넌트가 prop으로 className을 반드시 받아야 한다는 점이에요.
const Link = chakra("a")
function Example() {
return <Link bg="red.200" href="https://chakra-ui.com" />
}
커스텀 컴포넌트를 쓴 또 다른 예시예요.
import * as RadixScrollArea from "@radix-ui/react-scroll-area"
const ScrollArea = chakra(RadixScrollArea.Root)
function Example() {
return (
<ScrollArea>
<RadixScrollArea.Viewport>
<div>Hello</div>
</RadixScrollArea.Viewport>
</ScrollArea>
)
}
스타일 붙이기
chakra 함수를 사용해서 컴포넌트에 스타일이나 recipe를 붙일 수 있어요.
const Link = chakra("a", {
base: {
bg: "papayawhip",
color: "red.500",
},
})
// usage: <Link href="https://chakra-ui.com" />
Recipe 붙이기
컴포넌트에 recipe를 붙이는 예시예요.
const Card = chakra("div", {
base: {
shadow: "lg",
rounded: "lg",
bg: "white",
},
variants: {
variant: {
outline: {
border: "1px solid",
borderColor: "red.500",
},
solid: {
bg: "red.500",
color: "white",
},
},
},
})
// usage: <Card variant="outline" />
Prop 전달 (Forwarding props)
기본적으로 chakra factory는 chakra 관련 style prop만 DOM으로 전달되지 않도록 걸러내요. prop 전달을 더 세밀하게 제어하고 싶다면 shouldForwardProp 옵션을 전달하면 돼요.
$로 시작하지 않는 모든 prop을 전달하는 예시예요.
function shouldForwardProp(prop: string) {
return !prop.startsWith("$")
}
const Component = chakra("div", {}, { shouldForwardProp })
커스텀 prop 전달 로직을 만들려면 @emotion/is-prop-valid 패키지와 Chakra UI의 isValidProperty를 함께 쓰세요.
import { chakra, defaultSystem } from "@chakra-ui/react"
import shouldForwardProp from "@emotion/is-prop-valid"
const { isValidProperty } = defaultSystem
function shouldForwardProp(prop: string, variantKeys: string[]) {
const chakraSfp = !variantKeys?.includes(prop) && !isValidProperty(prop)
return shouldForwardProp(prop) || chakraSfp
}
const Component = chakra("div", {}, { shouldForwardProp })
기본 Props
defaultProps 옵션을 사용해서 컴포넌트에 기본 prop을 전달할 수 있어요.
const Button = chakra(
"button",
{
base: {
bg: "blue.500",
color: "white",
},
},
{ defaultProps: { type: "button" } },
)
다형성 (Polymorphism)
chakra factory로 만든 모든 컴포넌트는 as와 asChild prop을 받아서 실제 DOM 요소를 바꿀 수 있어요.
<Button as="a" href="https://chakra-ui.com">
Chakra UI
</Button>
또는
<Button asChild>
<a href="https://chakra-ui.com">Chakra UI</a>
</Button>
Chakra UI에서의 컴포지션에 대해 더 알아보려면 여기를 참고하세요.