테마 개요
테마 개요
Chakra UI의 테마 시스템을 설정하는 방법을 다루는 가이드예요. 이 글을 따라 설정하고 나면 성능 좋고 확장 가능한 스타일링 시스템을 손쉽게 구성할 수 있답니다.
출처: 문서
본문
아키텍처
Chakra UI 테마 시스템은 Panda CSS의 API 위에 만들어졌어요.
성능 좋고 확장 가능한 스타일링 시스템을 제공하기 위한 구조를 간단히 살펴볼게요.
defineConfig함수를 사용해 스타일링 시스템 설정을 정의한다.createSystem함수를 사용해 스타일링 엔진을 만든다.- 스타일링 엔진을
ChakraProvider컴포넌트에 전달한다.
import {
ChakraProvider,
createSystem,
defaultConfig,
defineConfig,
} from "@chakra-ui/react"
const config = defineConfig({
theme: {
tokens: {
colors: {},
},
},
})
const system = createSystem(defaultConfig, config)
export default function App() {
return (
<ChakraProvider value={system}>
<Box>Hello World</Box>
</ChakraProvider>
)
}
설정 (Config)
Chakra UI 시스템은 defineConfig 함수로 설정해요. 이 함수는 스타일링 시스템의 동작을 커스터마이징할 수 있는 설정 객체를 받아요.
설정을 정의한 뒤에는 createSystem 함수에 전달해 스타일링 엔진을 만들어요.
cssVarsRoot
cssVarsRoot는 토큰 CSS 변수가 적용될 루트 요소를 지정해요.
const config = defineConfig({
cssVarsRoot: ":where(:root, :host)",
})
export default createSystem(defaultConfig, config)
cssVarsPrefix
cssVarsPrefix는 토큰 CSS 변수에 사용할 접두사(prefix)를 지정해요.
const config = defineConfig({
cssVarsPrefix: "ck",
})
export default createSystem(defaultConfig, config)
globalCss
globalCss는 시스템에 전역 스타일을 적용할 때 사용해요.
const config = defineConfig({
globalCss: {
"html, body": {
margin: 0,
padding: 0,
},
},
})
export default createSystem(defaultConfig, config)
preflight
preflight는 시스템에 css 리셋 스타일을 적용할 때 사용해요.
const config = defineConfig({
preflight: false,
})
export default createSystem(defaultConfig, config)
혹은 preflight 설정 속성을 이용해 css 리셋 스타일을 시스템에 적용할 수도 있어요. 특정 요소에 css 리셋 스타일을 적용하고 싶을 때 유용해요.
const config = defineConfig({
preflight: {
scope: ".chakra-reset",
},
})
export default createSystem(defaultConfig, config)
theme
theme 설정 속성으로 시스템 테마를 정의할 수 있어요. 이 속성은 다음 속성들을 받아요.
breakpoints: 브레이크포인트 정의keyframes: css 키프레임 애니메이션 정의tokens: 토큰 정의semanticTokens: 시맨틱 토큰 정의textStyles: 타이포그래피 스타일 정의layerStyles: 레이어 스타일 정의animationStyles: 애니메이션 스타일 정의recipes: 컴포넌트 레시피 정의slotRecipes: 컴포넌트 슬롯 레시피 정의
const config = defineConfig({
theme: {
breakpoints: {
sm: "320px",
md: "768px",
lg: "960px",
xl: "1200px",
},
tokens: {
colors: {
red: "#EE0F0F",
},
},
semanticTokens: {
colors: {
danger: { value: "{colors.red}" },
},
},
keyframes: {
spin: {
from: { transform: "rotate(0deg)" },
to: { transform: "rotate(360deg)" },
},
},
},
})
export default createSystem(defaultConfig, config)
conditions
conditions 설정 속성으로 시스템에서 사용할 커스텀 선택자와 미디어 쿼리 조건을 정의할 수 있어요.
const config = defineConfig({
conditions: {
cqSm: "@container(min-width: 320px)",
child: "& > *",
},
})
export default createSystem(defaultConfig, config)
사용 예시:
<Box mt="40px" _cqSm={{ mt: "0px" }}>
<Text>Hello World</Text>
</Box>
strictTokens
strictTokens 설정 속성으로 디자인 토큰만 사용하도록 강제할 수 있어요. 테마에 정의되지 않은 토큰을 사용하려 하면 TS 에러가 발생해요.
const config = defineConfig({
strictTokens: true,
})
export default createSystem(defaultConfig, config)
// ❌ This will throw a TS error
<Box color="#4f343e">Hello World</Box>
// ✅ This will work
<Box color="red.400">Hello World</Box>
TypeScript와 함께 strictTokens를 쓴다면, 로컬 개발과 CI/CD에서 CLI typegen 명령을 실행해 토큰 타입이 테마와 동기화되도록 하세요.
TypeScript
시스템을 설정할 때(colors, space, fonts 등) CLI가 타입 정의를 생성해 테마와 @chakra-ui/react를 동기화해 줘요. 덕분에 타입 안전한 API와 자동 완성을 누릴 수 있답니다.
postinstall, CI, 모노레포에서 typegen을 실행하는 방법은 CLI 문서를 참고하세요.
npx @chakra-ui/cli typegen ./theme.ts
시스템 (System)
설정을 정의한 뒤에는 createSystem 함수에 전달해 스타일링 엔진을 만들어요. 반환된 system은 프레임워크에 종속되지 않는 자바스크립트 스타일링 엔진으로, 컴포넌트 스타일링에 사용할 수 있어요.
const system = createSystem(defaultConfig, config)
시스템은 다음 속성들을 포함해요.
token
token 함수는 원시 토큰 값 또는 css 변수를 가져오는 데 사용해요.
const system = createSystem(defaultConfig, config)
// raw token
system.token("colors.red.200")
// => "#EE0F0F"
// token with fallback
system.token("colors.pink.240", "#000")
// => "#000"
token.var 함수를 사용하면 css 변수를 얻을 수 있어요.
// css variable
system.token.var("colors.red.200")
// => "var(--chakra-colors-red-200)"
// token with fallback
system.token.var("colors.pink.240", "colors.red.200")
// => "var(--chakra-colors-red-200)"
중요한 점은 semanticTokens는 token이나 token.var를 쓰든 항상 css 변수를 반환한다는 거예요. 시맨틱 토큰은 테마에 따라 값이 바뀌기 때문이에요.
// semantic token
system.token("colors.danger")
// => "var(--chakra-colors-danger)"
system.token.var("colors.danger")
// => "var(--chakra-colors-danger)"
tokens
const system = createSystem(defaultConfig, config)
system.tokens.getVar("colors.red.200")
// => "var(--chakra-colors-red-200)"
system.tokens.expandReferenceInValue("3px solid {colors.red.200}")
// => "3px solid var(--chakra-colors-red-200)"
system.tokens.cssVarMap
// => Map { "colors": Map { "red.200": "var(--chakra-colors-red-200)" } }
system.tokens.flatMap
// => Map { "colors.red.200": "var(--chakra-colors-red-200)" }
css
css 함수는 chakra 스타일 객체를 emotion이나 styled-components 또는 그 외 스타일링 라이브러리에 전달할 수 있는 CSS 스타일 객체로 변환해 줘요.
const system = createSystem(defaultConfig, config)
system.css({
color: "red.200",
bg: "blue.200",
})
// => { color: "var(--chakra-colors-red-200)", background: "var(--chakra-colors-blue-200)" }
cva
cva 함수는 컴포넌트 레시피를 만드는 데 사용해요. props 집합과 함께 호출하면 스타일 객체를 반환하는 함수를 돌려줘요.
const system = createSystem(defaultConfig, config)
const button = system.cva({
base: {
color: "white",
bg: "blue.500",
},
variants: {
outline: {
color: "blue.500",
bg: "transparent",
border: "1px solid",
},
},
})
button({ variant: "outline" })
// => { color: "blue.500", bg: "transparent", border: "1px solid" }
sva
sva 함수는 컴포넌트 슬롯 레시피를 만드는 데 사용해요. props 집합과 함께 호출하면 각 슬롯에 대한 스타일 객체를 반환하는 함수를 돌려줘요.
const system = createSystem(defaultConfig, config)
const alert = system.sva({
slots: ["title", "description", "icon"],
base: {
title: { color: "white" },
description: { color: "white" },
icon: { color: "white" },
},
variants: {
status: {
info: {
title: { color: "blue.500" },
description: { color: "blue.500" },
icon: { color: "blue.500" },
},
},
},
})
alert({ status: "info" })
// => { title: { color: "blue.500" }, description: { color: "blue.500" }, icon: { color: "blue.500" } }
isValidProperty
isValidProperty 함수는 속성이 유효한지 확인할 때 사용해요.
const system = createSystem(defaultConfig, config)
system.isValidProperty("color")
// => true
system.isValidProperty("background")
// => true
system.isValidProperty("invalid")
// => false
splitCssProps
splitCssProps 함수는 props를 css props와 non-css props로 분리하는 데 사용해요.
const system = createSystem(defaultConfig, config)
system.splitCssProps({
color: "red.200",
bg: "blue.200",
"aria-label": "Hello World",
})
// => [{ color: "red.200", bg: "blue.200" }, { "aria-label": "Hello World" }]
breakpoints
breakpoints 속성은 브레이크포인트를 조회할 때 사용해요.
const system = createSystem(defaultConfig, config)
system.breakpoints.up("sm")
// => "@media (min-width: 320px)"
system.breakpoints.down("sm")
// => "@media (max-width: 319px)"
system.breakpoints.only("md")
// => "@media (min-width: 320px) and (max-width: 768px)"
system.breakpoints.keys()
// => ["sm", "md", "lg", "xl"]
토큰 (Tokens)
토큰에 대해 더 자세히 알아보려면 tokens 섹션을 참고하세요.
레시피 (Recipes)
레시피에 대해 더 자세히 알아보려면 recipes 섹션을 참고하세요.