테마 컴포넌트 시스템 · 신규 리소스

Chakra UI 디자인 시스템.

토큰, 시맨틱 색상 역할, 레시피, 복합 폼 컴포넌트를 살펴볼 수 있는 Chakra UI v3 레퍼런스입니다. 실제 간격과 글자 크기 체계를 확인하고, 유효성 검사와 저장 실패 시뮬레이션, 라이트·다크 모드를 지원하는 기본 워크스페이스 프로필 폼을 사용해 보세요.

OpenDesign 가이드9개 챕터참고 항목 47개독자적 적용 가이드
01

Chakra UI 디자인 시스템 인터페이스 미리보기

빈 필드 유효성 검사, 저장 실패 시뮬레이션, 입력값 유지, 로컬 저장 확인, 테마 전환을 살펴보세요.

네이티브 Chakra 작업 공간 프로필전체 예시 열기
React 19를 사용하는 네이티브 Chakra UI 3.37.0 자체 포함 번들입니다. 애플리케이션의 사용자 지정 시맨틱 토큰과 레시피를 모두 공개합니다. · 구현 레퍼런스
02

Chakra UI 디자인 시스템 디자인 참고 자료

Chakra UI 3.37.0 기본 테마 참고 자료와 명시적으로 구분한 OpenDesign 애플리케이션 토큰입니다. rem 값은 루트 글꼴 크기를 기준으로 하며, 픽셀 환산값은 16px를 가정합니다. 전체 내보내기 테마가 아닌, 실제 작업에 참고할 일부 항목입니다.

기본 시맨틱 색상

출처
이름 / 규칙값 / 구성용도
bgwhite / black밝은 모드/어두운 모드 페이지 캔버스.
bg.panelwhite / gray.950밝은 모드/어두운 모드 카드 표면.
bg.subtlegray.50 / gray.950절제된 표면.
fgblack / gray.50기본 텍스트.
fg.mutedgray.600 / gray.400보조 텍스트.
bordergray.200 / gray.800패널 및 컨트롤 경계선.
fg.errorred.500 / red.400오류 텍스트.
bg.errorred.50 / red.950오류 표면.
teal.fgteal.700 / teal.300옅은 청록색 표면 위의 텍스트.
teal.subtleteal.100 / teal.900현재 단계 스타일.

이 예제에서 사용하는 기본 색상 값

출처
이름 / 규칙값 / 구성용도
gray.50#fafafa 밝은 캔버스.
gray.200#e4e4e7 밝은 테두리.
gray.800#27272a 어두운 테두리.
gray.950#111111 어두운 캔버스.
teal.700#0c5d56 사용자 지정 밝은 모드 동작에서 이 값을 참조합니다.
teal.300#5eead4 사용자 지정 어두운 모드 동작에서 이 값을 참조합니다.

기본 간격 중 일부

출처
이름 / 규칙값 / 구성용도
spacing.10.25rem / 4px상태 표시 영역의 세로 패딩.
spacing.20.5rem / 8px인라인 컨트롤 간격.
spacing.30.75rem / 12px동작 그룹 간격.
spacing.41rem / 16px작은 뷰포트의 패딩.
spacing.61.5rem / 24px폼 필드 간 간격.
spacing.82rem / 32px주요 레이아웃 간격.
spacing.102.5rem / 40px사용 가능한 더 넓은 간격.
spacing.123rem / 48px사용 가능한 섹션 간격.

기본 타이포그래피 중 일부

출처
이름 / 규칙값 / 구성용도
fonts.body / fonts.headingInter, system fallbacks글꼴 토큰만으로는 Inter를 다운로드하지 않습니다.
fontSizes.xs0.75rem예제 주석.
fontSizes.sm0.875rem도움말 텍스트.
fontSizes.md1rem입력란 및 일반 본문 텍스트.
fontSizes.lg1.125rem사용 가능한 더 큰 본문 크기.
fontSizes.xl1.25rem카드 제목.
fontSizes.2xl1.5rem예제 제목.
fontWeights.medium / semibold500 / 600레이블 계층 구조.
lineHeights.shorter / moderate1.25 / 1.5제목/문단 간격.
letterSpacings.wide0.025em작은 보조 제목.

기본 모서리 반경

출처
이름 / 규칙값 / 구성용도
radii.sm0.25rem / 4px좁은 모서리.
radii.md0.375rem / 6px이 예제의 상태 칩.
radii.lg0.5rem / 8px적당한 둥글기.
radii.xl0.75rem / 12px이 예제의 프로필 카드.
radii.full9999px필 형태의 모서리. 폼에는 사용하지 않습니다.

기본 반응형 중단점

출처
이름 / 규칙값 / 구성용도
sm480px동작 행을 가로로 배치할 수 있습니다.
md768px진행률 열을 폼 옆에 배치합니다.
lg1024px사용 가능한 와이드 레이아웃 중단점.
xl1280px사용 가능한 데스크톱 중단점.
2xl1536px사용 가능한 초광폭 중단점.

애플리케이션 시맨틱 토큰: 아래에서 정의

출처
이름 / 규칙값 / 구성용도
workspace.canvasgray.50 / gray.950사용자 지정 라이트/다크 캔버스 매핑입니다.
workspace.actionbrand.700 / brand.300사용자 지정 액션 배경색입니다. 브랜드 프리미티브는 theme.js에 선언합니다.
workspace.onActionwhite / gray.950배경색에 맞춘 사용자 지정 액션 텍스트 색상입니다.
03

Chakra UI 디자인 시스템 전체 가이드

실제 인터페이스를 위해 이 시스템을 선택하고 적용하고 검토하는 실용 가이드.

DESIGN-chakra-ui.md

완전한 안내와 구현 시작점, 소스 링크.

가이드 다운로드

Chakra UI 디자인 시스템 v3: 구성, 토큰, 컴포넌트

기존 테마 객체를 전달하는 대신 시스템을 만드세요

구현은 세 계층으로 구성됩니다. theme.js는 디자인 결정을 정의하고, main.jsx는 그 결과로 만들어진 시스템을 제공하며, App.jsx는 양식을 구성합니다. createSystem(defaultConfig, config)는 기본 컴포넌트 레시피를 유지하면서 애플리케이션 구성을 병합합니다. 사용자 지정 시스템을 처음부터 만들려면 더 많은 정의가 필요하므로, 여기서는 기본값을 확장하는 방식을 의도적으로 선택했습니다.

이 OpenDesign 가이드에서

미리보기에는 그려 넣은 대체 요소가 아니라 Chakra 컴포넌트를 사용합니다. 사이드바는 애플리케이션 전용 순서형 진행 목록이며, Chakra Steps 컴포넌트가 탑재되었다는 의미는 아닙니다. 프로필 카드, 필드, 선택 상자, 알림, 버튼은 Chakra 컴포넌트를 기본으로 조합해 구성합니다.

지원 사양 읽기

각 계층에 포함되는 항목

  • tokens: 예시에 사용된 두 가지 브랜드 색상을 비롯한 재사용 가능한 프리미티브 값입니다.
  • semanticTokens: 개별 화면과 무관하게 workspace.action처럼 조건에 따라 달라지는 역할을 정의합니다.
  • recipes: 재사용 가능한 컴포넌트 변형입니다. 애플리케이션의 React 상태에 따라 양식이 오류, 대기, 실패 또는 확인 상태가 됩니다.

Chakra UI 디자인 시스템의 프리미티브 색상과 시맨틱 테마 역할

표현 방식이 달라지는 곳에는 역할을 사용하세요

bg.panel과 fg.muted는 각각 표면과 텍스트의 역할을 나타내며, 기본 값은 gray.950과 gray.400입니다. 참고 표에는 라이트/다크 모드에서 각 값이 어떻게 적용되는지 나와 있습니다. 데모에서 문서 루트를 라이트와 다크 사이에서 전환하면 각 Field나 Card를 다시 작성하지 않아도 조건부 값이 적용됩니다. 이 로컬 전환 기능은 의도적으로 설정을 저장하거나 시스템 기본 설정과 연동하지 않습니다.

workspace.* 역할은 애플리케이션에서 추가한 것입니다. 밝은 표면에는 짙은 청록색 액션을, 어두운 표면에는 옅은 청록색 액션을 선택하고, 각각에 맞는 텍스트 색상도 지정합니다. 이는 공식 Chakra 토큰 이름이 아닙니다. 색상 쌍을 테마에 함께 두면 다크 모드에서 버튼 배경만 바뀌고 레이블은 흰색으로 남는 문제를 방지할 수 있습니다.

지원 사양 읽기

참조 구문은 컴포넌트의 축약 구문과 다릅니다

토큰 정의 안에서는 전체 참조 경로 {colors.gray.950}를 사용합니다. 스타일 prop에서 bg="workspace.canvas"는 color 범주 안에서 해석됩니다. 복합 CSS 값에서는 전체 토큰 경로를 다시 사용해야 합니다. 이러한 차이를 이해하면 일반 문자열을 테마 참조로 잘못 해석하는 일을 방지할 수 있습니다.

jsx
<Box bg="workspace.canvas" color="fg" border="1px solid {colors.gray.200}" p="4" />

코드 참조

Chakra UI 디자인 시스템: 명시적 토큰으로 구성하는 읽기 쉬운 글자 크기 체계

이 구성에 글자 크기 체계를 적용하세요

제목에는 fontSize="2xl"과 lineHeight="shorter"를 사용하고, 카드 제목에는 xl, 도움말 텍스트에는 sm, 예시 주석에는 xs를 사용합니다. 의미상 제목 단계는 바꾸지 않으면서 이러한 선택으로 계층을 만듭니다. 화면 제목은 h1이고 양식 제목은 h2입니다. 일반적인 양식 콘텐츠에는 기본 본문 크기를 유지합니다.

Chakra의 기본 본문 및 제목 글꼴 스택은 Inter로 시작하고 플랫폼 글꼴을 대체 글꼴로 사용합니다. 이 독립형 데모는 외부 글꼴을 요청하지 않으므로 운영체제에 따라 렌더링되는 대체 글꼴이 달라질 수 있습니다. 정확한 타이포그래피가 필요하다면 적절한 라이선스가 있는 글꼴을 로컬에서 제공하세요. 글꼴 토큰만 설정해도 글꼴 파일이 제공되는 것은 아닙니다.

지원 사양 읽기

타이포그래피와 의미를 분리하세요

현재 단계 칩은 간결한 메타데이터이지 주요 안내 문구가 아닙니다. 필수 입력 및 오류 메시지는 필드 옆에 읽기 쉬운 크기로 표시합니다. 오버라인의 자간을 변경해도 양식 레이블은 영향을 받지 않으며, 긴 워크스페이스 이름은 입력란 안에 유지해 주변 카드의 너비가 바뀌지 않도록 합니다.

Chakra UI 디자인 시스템: Field, NativeSelect, Card, Alert 조합하기

Field는 스타일이 지정된 입력란이 아니라 관계를 나타냅니다

Field.Root는 레이블, 컨트롤, 도움말, 오류를 하나로 묶습니다. 필수 표시와 RequiredIndicator는 필수 입력임을 알리고, invalid는 오류 상태를 제어합니다. 이 예시에서는 React를 통해 입력값을 제어하고, workspace-name 오류를 Field.ErrorText에 표시합니다. 분리된 문단에 오류 스타일을 따로 지정하지 않습니다.

팀 규모에는 NativeSelect.Root, NativeSelect.Field, NativeSelect.Indicator를 사용합니다. 옵션이 적고 고정된 경우에도 네이티브 선택 동작을 유지할 수 있습니다. 검색 가능한 원격 결과를 제공하는 것처럼 동작하지는 않습니다. 그런 기능에는 다른 컨트롤과 데이터 상호작용 방식이 필요합니다.

지원 사양 읽기

피드백은 별도의 구성 요소로 만듭니다

지원 사양 읽기

Chakra UI 디자인 시스템: 간격 토큰과 반응형 스타일 prop 적용하기

구체적인 간격 정책

필드 그룹 사이에는 gap="6", 액션 사이에는 gap="3", 진행 열과 양식 사이에는 gap="8"을 사용합니다. 페이지 패딩은 md에서 p="4"에서 p="8"로 바뀝니다. 루트 글꼴 크기가 16px일 때 각각 24px, 12px, 32px, 16px, 32px에 해당합니다. rem 기반 값은 사용자의 루트 글꼴 크기에 따라 조정됩니다.

카드에는 rounded="xl"을, 상태 칩에는 rounded="md"를 사용합니다. 큰 컨테이너와 작은 레이블은 형태가 다르므로 반경도 의도적으로 다르게 설정했습니다. 이러한 사용 방식을 모든 Chakra 애플리케이션에 적용해야 하는 기본 규칙으로 해석하지 마세요.

지원 사양 읽기

md에서 구성을 변경하세요

md 미만에서는 그리드가 한 열로 표시되고, md부터는 220px 너비의 진행 열 옆에 유연한 양식 열이 배치됩니다. minmax(0, 1fr)을 사용하면 그리드 안에서 양식 열이 줄어들 수 있습니다. 액션 스택은 sm에서 변경됩니다. 이러한 객체 값은 모바일 우선 재정의이며 기기를 감지하는 기능이 아닙니다.

jsx
<Grid templateColumns={{ base: "1fr", md: "220px minmax(0, 1fr)" }} gap="8">
  <Box as="nav" aria-label="Setup progress">…</Box>
  <Card.Root rounded="xl">…</Card.Root>
</Grid>

코드 참조

Chakra UI 디자인 시스템: 유효성 검사, 로딩, 복구 연결하기

미리보기 상태 머신

공백을 제거한 이름을 제출하면 유효하지 않은 상태가 되고 입력란에 포커스가 이동합니다. 유효한 이름을 제출하면 대기 상태가 되며, 편집이 비활성화되고 Button의 loadingText가 표시됩니다. 로컬 타이머가 끝난 뒤 실패 체크박스의 선택 여부에 따라 실패 또는 완료 상태가 표시됩니다. 어느 경우에도 네트워크 요청을 보내거나 데이터를 저장하지 않습니다.

실패 결과가 표시되어도 제어되는 이름과 선택한 크기는 그대로 유지됩니다. 실패 시뮬레이션을 끄면 다시 시도할 수 있습니다. 완료되면 프로필 필드가 비활성화되고 첫 번째 진행 상태 칩이 바뀝니다. Reset을 누르면 편집 상태로 돌아갑니다. 이 예제는 화면에 표시되는 상태 조합을 보여 주며, 백엔드 저장 동작을 보장하지는 않습니다.

지원 사양 읽기

순서대로 상태 확인하기

  1. 양식을 초기화한 뒤 이름을 입력하지 않고 제출해 필드 메시지와 포커스가 이동한 입력란을 확인합니다.
  2. 이름을 입력하고 저장 실패 시뮬레이션을 켠 뒤 제출합니다. 오류가 표시된 뒤에도 값이 유지되는지 확인합니다.
  3. 실패 시뮬레이션을 끄고 다시 제출합니다. 확인 요약을 살펴본 뒤 표시 스타일을 변경합니다.

Chakra UI 네이티브 시맨틱을 합성 과정에서도 유지하는 디자인 시스템

유효성 검사와 진행 상태를 명확하게 전달합니다

이 예제는 noValidate를 사용해 브라우저의 기본 유효성 검사 UI 대신 사용자 지정 Field 오류 경로를 보여 줍니다. Field를 사용해 레이블과 입력란의 연결을 유지하고, 유효하지 않은 첫 번째 입력란에 포커스를 둡니다. 대기 중인 작업은 라이브 상태 영역으로 알립니다. 스피너만으로 상태를 전달하지 않습니다.

진행 목록에는 순서 있는 목록 시맨틱을 사용하고, 활성 항목에는 aria-current="step"을 적용합니다. 사용할 수 없는 화면으로 연결되는 가짜 링크는 넣지 않았습니다. 미리보기의 두 번째와 세 번째 단계는 맥락을 설명하는 용도이며 클릭할 수 없습니다. 이를 통해 예제의 범위를 명확히 보여 줍니다.

지원 사양 읽기

포커스는 사용자 지정 동작 레시피의 일부입니다

온보딩 변형에는 오프셋을 포함한 명시적인 focus-visible 윤곽선을 정의했습니다. 어두운 화면 스타일로 전환하면 동작 역할과 함께 윤곽선 역할도 바뀝니다. 네이티브 체크박스와 선택 상자는 키보드로 조작할 수 있습니다. 컴포넌트 수준의 예제만으로 전체 온보딩 제품의 접근성을 보장할 수는 없으므로, 이를 사용하는 애플리케이션에서도 포커스, 필드 알림, 확대/축소, 스크린 리더 출력을 확인하세요.

Chakra UI 디자인 시스템 레시피, Provider 연결, 버전 경계

Button을 확장하고 Status는 로컬에서 정의합니다

온보딩용 Button 변형은 theme.recipes.button에 추가합니다. 구성에서 defaultConfig를 확장하므로 outline 같은 기존 변형도 계속 사용할 수 있습니다. 상태 칩은 defineRecipe와 useRecipe를 사용해 로컬에서 정의합니다. 상태별 변형은 current, complete, waiting을 서로 다른 의미 역할에 연결합니다. 이는 애플리케이션 컴포넌트이며 Chakra에서 내보내는 컴포넌트가 아닙니다.

단일 요소 레시피는 스타일 객체 하나를 반환합니다. Field처럼 여러 부분으로 이루어진 컴포넌트는 각 부분을 함께 테마에 적용할 때 슬롯 레시피가 필요합니다. 버튼 스타일 레시피를 Field 전체에 적용하면 레이블, 입력 컨트롤, 오류 메시지를 각각 제어할 수 없습니다.

지원 사양 읽기

제공된 파일을 함께 사용하세요

v2의 extendTheme 설정을 가져오거나 이 v3 Provider에 theme={...}을 전달하지 마세요. 실제 루트에서는 ChakraProvider value={system}을 사용합니다. 이 예제에는 두 번째 색상 모드 Provider를 의도적으로 추가하지 않았습니다. 독립적인 미리보기에는 로컬 light/dark 클래스 전환으로 충분하지만, 실제 앱에서는 환경설정 저장과 서버 렌더링 지원이 필요할 수 있습니다.

지원 사양 읽기

Chakra UI 테마와 양식을 함께 확인하는 디자인 시스템

이 예제로 확인할 수 있는 항목

검토에 적합한 단위는 두 가지 화면 스타일의 프로필 카드 전체입니다. 레이블, 입력란, 도움말 텍스트, 유효성 오류, 대기 중 버튼, 실패 알림, 성공 요약이 모두 포함됩니다. 버튼 하나만으로는 의미에 맞지 않는 배경이나 레이블과 연결되지 않은 오류 상태를 발견할 수 없습니다.

기준 표의 규칙을 실제 인터페이스에 적용된 값과 비교합니다. 사용자 지정 청록색 동작 스타일은 기본 윤곽선 동작 스타일과 달라야 하고, 간격 6은 필드 사이에 적용되어야 하며, md 아래에서는 그리드가 한 열로 바뀌어야 합니다. 이러한 확인을 통해 문서의 규칙과 렌더링 결과를 연결할 수 있습니다.

예제에서 다루지 않는 항목

미리보기에는 계정 생성, 초대 전송, 데이터 저장, 인증, 다른 온보딩 화면과의 연동 기능이 없습니다. 타이머는 시뮬레이션임을 명시합니다. 실제 엔드포인트를 연결할 때는 여기서 보여 준 필드 상태와 요청 상태의 구분을 유지하고, 타이머를 요청으로 바꾸세요. 또한 완료가 로컬에서 수락된 상태인지, 원격 저장이 끝난 상태인지, 완전히 활성화된 상태인지 정의해야 합니다.

Chakra UI 디자인 시스템 컴포넌트 예제

theme.js — 원시 토큰, 의미 역할, 레시피

예제에서 사용하는 전체 애플리케이션 테마입니다. 워크스페이스 역할과 온보딩 변형은 새로 추가한 항목이며, defaultConfig는 Chakra의 기본 테마를 제공합니다.

자바스크립트
import { createSystem, defaultConfig, defineConfig, defineRecipe } from '@chakra-ui/react';

export const statusRecipe = defineRecipe({
  base: { display: 'inline-flex', px: '2', py: '1', rounded: 'md', fontSize: 'xs', fontWeight: 'semibold' },
  variants: {
    state: {
      current: { bg: 'teal.subtle', color: 'teal.fg' },
      complete: { bg: 'bg.success', color: 'fg.success' },
      waiting: { bg: 'bg.muted', color: 'fg.muted' },
    },
  },
  defaultVariants: { state: 'waiting' },
});

const config = defineConfig({
  theme: {
    tokens: { colors: { brand: { 700: { value: '#0c5d56' }, 300: { value: '#5eead4' } } } },
    semanticTokens: { colors: {
      'workspace.canvas': { value: { base: '{colors.gray.50}', _dark: '{colors.gray.950}' } },
      'workspace.action': { value: { base: '{colors.brand.700}', _dark: '{colors.brand.300}' } },
      'workspace.onAction': { value: { base: '{colors.white}', _dark: '{colors.gray.950}' } },
    } },
    recipes: {
      button: defineRecipe({ variants: { variant: {
        onboarding: {
          bg: 'workspace.action', color: 'workspace.onAction',
          _hover: { opacity: 0.9 },
          _focusVisible: { outline: '2px solid', outlineColor: 'workspace.action', outlineOffset: '2px' },
        },
      } } }),
    },
  },
});
export const system = createSystem(defaultConfig, config);

코드 참조

  • 브랜드 값은 참조된 청록색 원시 토큰과 의도적으로 일치시켰습니다.
  • 상태 레시피는 로컬에서 정의하고, Button 변형은 시스템에 등록합니다.

App.jsx — 네이티브 양식 및 상태 예제 전체

미리보기에서 사용하는 실제 React 구성입니다. 테마 전환, Field 유효성 검사, 네이티브 선택 상자, 대기 중 피드백, 실패 시뮬레이션, 확인, 초기화가 포함됩니다.

jsx
import React, { useEffect, useRef, useState } from 'react';
import { Box, Button, Card, Field, Grid, Heading, Input, NativeSelect, Stack, Text, Alert, chakra, useRecipe } from '@chakra-ui/react';
import { statusRecipe } from './theme';

function Status({ state, children }) {
  const recipe = useRecipe({ recipe: statusRecipe });
  return <chakra.span css={recipe({ state })}>{children}</chakra.span>;
}

export default function App() {
  const [dark, setDark] = useState(false);
  useEffect(() => { document.documentElement.className = dark ? 'dark' : 'light'; }, [dark]);
  const [name, setName] = useState('Northstar Studio');
  const [size, setSize] = useState('2–10');
  const [invalid, setInvalid] = useState(false);
  const [phase, setPhase] = useState('editing');
  const [simulateFailure, setSimulateFailure] = useState(false);
  const nameInput = useRef(null);
  const pending = phase === 'pending';
  const complete = phase === 'complete';
  const save = (event) => {
    event.preventDefault();
    if (!name.trim()) { setInvalid(true); nameInput.current?.focus(); return; }
    setInvalid(false); setPhase('pending');
    window.setTimeout(() => setPhase(simulateFailure ? 'failed' : 'complete'), 600);
  };
  return <Box className={dark ? 'dark' : 'light'} bg='workspace.canvas' color='fg' p={{ base: '4', md: '8' }}>
    <Box maxW='960px' mx='auto'>
      <Stack direction={{ base: 'column', sm: 'row' }} justify='space-between' align={{ base: 'stretch', sm: 'center' }} gap='4' mb='8'>
        <Box><Text fontSize='xs' fontWeight='semibold' color='teal.fg' letterSpacing='wide'>CHAKRA UI · NATIVE SPECIMEN</Text><Heading as='h1' fontSize='2xl' lineHeight='shorter' mt='2'>Set up your workspace</Heading></Box>
        <Button variant='outline' size='sm' onClick={() => setDark(!dark)} aria-pressed={dark}> {dark ? 'Light appearance' : 'Dark appearance'} </Button>
      </Stack>
      <Grid templateColumns={{ base: '1fr', md: '220px minmax(0, 1fr)' }} gap='8'>
        <Box as='nav' aria-label='Setup progress'>
          <Stack as='ol' gap='6' listStyleType='none' m='0' p='0'>
            <Box as='li' aria-current={complete ? undefined : 'step'}><Status state={complete ? 'complete' : 'current'}>{complete ? 'Complete' : 'Current'}</Status><Text fontWeight='semibold' mt='2'>1. Workspace profile</Text><Text fontSize='sm' color='fg.muted'>Name and team size</Text></Box>
            <Box as='li'><Status state='waiting'>Next</Status><Text fontWeight='medium' mt='2'>2. Invite your team</Text><Text fontSize='sm' color='fg.muted'>Available in the full product</Text></Box>
            <Box as='li'><Status state='waiting'>Optional</Status><Text fontWeight='medium' mt='2'>3. Connect tools</Text><Text fontSize='sm' color='fg.muted'>Complete this later</Text></Box>
          </Stack>
          <Box mt='8' borderTopWidth='1px' borderColor='border' pt='4'><Text fontSize='xs' color='fg.muted'>Scale in this specimen</Text><Text fontSize='sm' mt='2'>Field gap 6 · Card padding 6<br/>Page gap 8 · Radius xl</Text></Box>
        </Box>
        <Card.Root bg='bg.panel' borderColor='border' rounded='xl'>
          <Card.Header><Heading as='h2' fontSize='xl'>Workspace profile</Heading><Text color='fg.muted' fontSize='sm'>The name appears on your team's workspace.</Text></Card.Header>
          <Card.Body>
            <form onSubmit={save} noValidate>
              <Stack gap='6'>
                <Field.Root required invalid={invalid} disabled={pending || complete}>
                  <Field.Label>Workspace name <Field.RequiredIndicator /></Field.Label>
                  <Input ref={nameInput} value={name} onChange={e => {setName(e.target.value);setInvalid(false);}} autoComplete='organization' />
                  <Field.HelperText>Use a name your teammates will recognize.</Field.HelperText>
                  <Field.ErrorText>Enter a workspace name.</Field.ErrorText>
                </Field.Root>
                <Field.Root disabled={pending || complete}>
                  <Field.Label>Team size</Field.Label>
                  <NativeSelect.Root><NativeSelect.Field value={size} onChange={e => setSize(e.target.value)}><option>Just me</option><option>2–10</option><option>11–50</option><option>51+</option></NativeSelect.Field><NativeSelect.Indicator /></NativeSelect.Root>
                  <Field.HelperText>Used only for this local preview summary.</Field.HelperText>
                </Field.Root>
                <Box><label style={{display:'flex',gap:'8px',alignItems:'center',fontSize:'14px'}}><input type='checkbox' checked={simulateFailure} disabled={pending || complete} onChange={e=>setSimulateFailure(e.target.checked)} />Simulate a failed save</label></Box>
                {phase === 'failed' && <Alert.Root status='error'><Alert.Indicator /><Alert.Content><Alert.Title>Demo save failed</Alert.Title><Alert.Description>Your values are still here. Turn off failure simulation and retry.</Alert.Description></Alert.Content></Alert.Root>}
                {complete && <Alert.Root status='success'><Alert.Indicator /><Alert.Content><Alert.Title>Profile confirmed in this preview</Alert.Title><Alert.Description>{name.trim()} · {size} people. Nothing was sent or stored.</Alert.Description></Alert.Content></Alert.Root>}
                <Stack direction={{base:'column',sm:'row'}} gap='3'>
                  <Button type='submit' variant='onboarding' loading={pending} loadingText='Checking profile' disabled={complete}>Confirm profile</Button>
                  <Button type='button' variant='outline' disabled={pending} onClick={()=>{setPhase('editing');setInvalid(false);setName('');setSize('2–10');setSimulateFailure(false);nameInput.current?.focus();}}>Reset example</Button>
                </Stack>
                <Text role='status' aria-live='polite' fontSize='sm' color='fg.muted'>{pending ? 'Simulating a response. No network request is made.' : complete ? 'Profile step complete. Reset to try another state.' : 'Try an empty name, a failed save, or a different appearance.'}</Text>
              </Stack>
            </form>
          </Card.Body>
        </Card.Root>
      </Grid>
      <Text mt='6' fontSize='xs' color='fg.muted'>Actual Chakra UI 3.37.0 components. Custom workspace semantic tokens and button recipe. Memory-only demonstration.</Text>
    </Box>
  </Box>;
}

코드 참조

  • 요청을 보내지 않습니다. 600ms 지연은 대기 중 UI를 보여 주기 위한 것입니다.
  • 다음 단계는 맥락을 나타내는 레이블이며, 실제로 이동하지 않습니다.
04

Chakra UI 디자인 시스템 에이전트 설정

구현 시작점

설치된 Vite 릴리스와 Chakra가 지원하는 Node.js를 사용하세요. Chakra는 Node 20 이상을 안내합니다. 이 블록에서는 터미널 명령과 src/main.jsx를 구분합니다. 전체 테마 및 App 파일은 위에 제공되어 있으므로 숨겨진 Provider 코드 조각이나 외부 CSS는 필요하지 않습니다.

text
# Terminal: create a JavaScript React application
npm create vite@latest chakra-profile -- --template react
cd chakra-profile
npm install
npm install @chakra-ui/[email protected] @emotion/react

# Save the two complete examples as src/theme.js and src/App.jsx.
# Replace src/main.jsx with:
import React from 'react';
import { createRoot } from 'react-dom/client';
import { ChakraProvider } from '@chakra-ui/react';
import { system } from './theme';
import App from './App';
createRoot(document.getElementById('root')).render(<ChakraProvider value={system}><App /></ChakraProvider>);

# Start from the project directory:
npm run dev

프로젝트를 위한 프롬프트

에이전트 프롬프트
Chakra UI 3.37.0과 제공된 theme.js 및 App.jsx를 시작점으로 사용하세요. workspace 의미 역할, Field 구성, 기본 select, 잘못된 입력과 제출 실패의 구분을 유지하세요. 시뮬레이션 타이머만 실제 영속성 API으로 교체하고, 결과가 확인되기 전에 프로필을 완료로 표시하지 마세요. 키보드 포커스, 반응형 base/md 레이아웃, 라이트/다크 값을 유지하세요. 새 토큰이나 레시피 변형이 있다면 설명하세요.
05

Chakra UI 디자인 시스템의 출처와 범위

문서화된 Chakra UI v3 기반을 사용하는 OpenDesign의 공식 구현 가이드입니다. 기본 토큰 참조와 애플리케이션별 workspace 역할을 구분합니다. 기본 제공 미리보기는 로컬 상태를 보여주는 예시로, workspace 데이터를 저장하거나 온보딩 여정 전체를 구현하지 않습니다.