크로스 플랫폼 및 모바일 UI · 새 리소스

Tamagui 디자인 시스템.

검증, 진행 상황, 빈 상태 복구 기능이 포함된 기본 컴포넌트 기반 습관 관리 보드에서 Tamagui의 실제 v5 토큰 범주와 라이트/다크 블루 테마를 살펴보세요.

OpenDesign 가이드8개 챕터참조 항목 50개독자적 적용 가이드
01

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

습관을 추가하고 진행 상황을 표시한 뒤, 미완료 항목을 필터링하고 파란색 테마로 전환하세요.

작은 습관 보드 만들기전체 예시 열기
Tamagui 2.7.7 기본 웹 구성 요소, v5 구성 및 자체 로컬 상태를 사용합니다. · 구현 레퍼런스
02

Tamagui 디자인 시스템 디자인 참고 자료

2.7.7의 @tamagui/config/v5 및 @tamagui/themes가 내보내는 값과 확인된 기본 구성 요소 계약입니다.

v5 크기 토큰

출처
이름 / 규칙값 / 구성용도
size.$120실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
size.$228실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
size.$336실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
size.$444실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
size.$552실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
size.$664실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.

v5 간격 토큰

출처
이름 / 규칙값 / 구성용도
space.$12실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
space.$1.54실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
space.$27실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
space.$2.510실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
space.$313실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
space.$3.516실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
space.$418실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
space.$524실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
space.$632실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.

v5 모서리 반경 토큰

출처
이름 / 규칙값 / 구성용도
radius.00실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
radius.13실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
radius.25실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
radius.37실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
radius.49실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
radius.510실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.
radius.616실제 v5 구성 값입니다. 같은 숫자의 토큰 이름이라도 크기, 간격 및 모서리 반경에서 의미가 다릅니다. $4를 모든 곳에 통용되는 픽셀 값으로 취급하지 마세요.

light_blue 시맨틱 테마

출처
이름 / 규칙값 / 구성용도
light_blue.backgroundhsla(207, 100%, 98%, 1)v5 파란색 테마에서 확인된 시맨틱 역할입니다. 호버, 누름 또는 활성 상태에서는 구성 요소가 더 구체적인 하위 테마를 선택할 수 있습니다.
light_blue.backgroundHoverhsla(210, 100%, 99%, 1)v5 파란색 테마에서 확인된 시맨틱 역할입니다. 호버, 누름 또는 활성 상태에서는 구성 요소가 더 구체적인 하위 테마를 선택할 수 있습니다.
light_blue.backgroundPresshsla(205, 92%, 95%, 1)v5 파란색 테마에서 확인된 시맨틱 역할입니다. 호버, 누름 또는 활성 상태에서는 구성 요소가 더 구체적인 하위 테마를 선택할 수 있습니다.
light_blue.colorhsla(216, 71%, 23%, 1)v5 파란색 테마에서 확인된 시맨틱 역할입니다. 호버, 누름 또는 활성 상태에서는 구성 요소가 더 구체적인 하위 테마를 선택할 수 있습니다.
light_blue.borderColorhsla(203, 100%, 92%, 1)v5 파란색 테마에서 확인된 시맨틱 역할입니다. 호버, 누름 또는 활성 상태에서는 구성 요소가 더 구체적인 하위 테마를 선택할 수 있습니다.
light_blue.borderColorFocushsla(203, 100%, 92%, 1)v5 파란색 테마에서 확인된 시맨틱 역할입니다. 호버, 누름 또는 활성 상태에서는 구성 요소가 더 구체적인 하위 테마를 선택할 수 있습니다.
light_blue.placeholderColorhsla(206, 100%, 50%, 1)v5 파란색 테마에서 확인된 시맨틱 역할입니다. 호버, 누름 또는 활성 상태에서는 구성 요소가 더 구체적인 하위 테마를 선택할 수 있습니다.

dark_blue 시맨틱 테마

출처
이름 / 규칙값 / 구성용도
dark_blue.backgroundhsla(218, 39%, 11%, 1)v5 파란색 테마에서 확인된 시맨틱 역할입니다. 호버, 누름 또는 활성 상태에서는 구성 요소가 더 구체적인 하위 테마를 선택할 수 있습니다.
dark_blue.backgroundHoverhsla(212, 69%, 16%, 1)v5 파란색 테마에서 확인된 시맨틱 역할입니다. 호버, 누름 또는 활성 상태에서는 구성 요소가 더 구체적인 하위 테마를 선택할 수 있습니다.
dark_blue.backgroundPresshsla(215, 42%, 9%, 1)v5 파란색 테마에서 확인된 시맨틱 역할입니다. 호버, 누름 또는 활성 상태에서는 구성 요소가 더 구체적인 하위 테마를 선택할 수 있습니다.
dark_blue.colorhsla(205, 100%, 88%, 1)v5 파란색 테마에서 확인된 시맨틱 역할입니다. 호버, 누름 또는 활성 상태에서는 구성 요소가 더 구체적인 하위 테마를 선택할 수 있습니다.
dark_blue.borderColorhsla(209, 100%, 19%, 1)v5 파란색 테마에서 확인된 시맨틱 역할입니다. 호버, 누름 또는 활성 상태에서는 구성 요소가 더 구체적인 하위 테마를 선택할 수 있습니다.
dark_blue.borderColorFocushsla(209, 100%, 19%, 1)v5 파란색 테마에서 확인된 시맨틱 역할입니다. 호버, 누름 또는 활성 상태에서는 구성 요소가 더 구체적인 하위 테마를 선택할 수 있습니다.
dark_blue.placeholderColorhsla(206, 100%, 50%, 1)v5 파란색 테마에서 확인된 시맨틱 역할입니다. 호버, 누름 또는 활성 상태에서는 구성 요소가 더 구체적인 하위 테마를 선택할 수 있습니다.

시스템 글꼴 역할

출처
이름 / 규칙값 / 구성용도
body.family-apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serifv5 시스템 글꼴 스택은 원격 글꼴을 요청하지 않습니다.
body.$213px / 20px크기와 줄 높이를 짝지은 글꼴 역할입니다. 같은 이름의 구성 요소 크기 토큰과는 별개입니다.
body.$314px / 21px크기와 줄 높이를 짝지은 글꼴 역할입니다. 같은 이름의 구성 요소 크기 토큰과는 별개입니다.
body.$415px / 23px크기와 줄 높이를 짝지은 글꼴 역할입니다. 같은 이름의 구성 요소 크기 토큰과는 별개입니다.
body.$516px / 24px크기와 줄 높이를 짝지은 글꼴 역할입니다. 같은 이름의 구성 요소 크기 토큰과는 별개입니다.
body.$618px / 27px크기와 줄 높이를 짝지은 글꼴 역할입니다. 같은 이름의 구성 요소 크기 토큰과는 별개입니다.
body.$826px / 38px크기와 줄 높이를 짝지은 글꼴 역할입니다. 같은 이름의 구성 요소 크기 토큰과는 별개입니다.

기본 구성 구성 계약

출처
이름 / 규칙값 / 구성용도
createTamaguidefaultConfig from @tamagui/config/v5React 바깥에서 구성 인스턴스를 하나 생성하고, getCSS()로 웹 테마 CSS을 제공합니다.
TamaguiProviderconfig + defaultTheme애플리케이션은 보드 상태를 유지하면서 밝은 모드와 어두운 모드를 선택합니다.
Themename="blue"현재 모양에 맞는 파란색 하위 테마를 확인합니다.
Checkboxchecked + onCheckedChange보드는 value === true인 경우에만 완료로 처리합니다. 미확정 상태는 완료로 간주하지 않습니다.
Inputvalue + onChangeText제어되는 초안, 공백 제거 후 유효성 검사 및 명시적인 중복 처리입니다.
Progressvalue from 0 to 100표시기는 완료된 항목 수를 전체 행 수로 나눈 값에서 계산합니다.
YStack / XStackdirectional layout with token gap별도의 모방 스타일시트 없이 읽기 편한 레이아웃의 반응형 동작을 유지하세요.
03

Tamagui 디자인 시스템 전체 가이드

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

DESIGN-tamagui.md

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

가이드 다운로드

Tamagui 디자인 시스템 버전 관리 구성 및 CSS

이름이 지정된 v5 프리셋 사용

이 예제는 tamagui와 @tamagui/config의 버전을 2.7.7로 고정하고 @tamagui/config/v5에서 defaultConfig를 가져옵니다. 구성 이름은 v5이며 npm 패키지의 메이저 버전이 아닙니다. 이 두 숫자를 혼동하면 잘못된 설치 명령을 안내하게 됩니다. createTamagui는 컴포넌트 바깥에서 한 번 실행하고, 생성된 CSS을 보드 렌더링 전에 삽입하여 테마 변수와 기본 스타일을 실제 웹 환경에서 사용할 수 있도록 합니다.

이 OpenDesign 가이드에서

소규모 구성 재정의를 명시적으로 표현

제공된 소스에서는 이 예제가 padding, backgroundColor처럼 읽기 쉬운 긴 형식의 속성을 사용하므로 onlyAllowShorthands를 false로 설정합니다. 이는 프리셋에 추가된 애플리케이션 수준의 선택입니다. v5 기본 구성에는 애니메이션 드라이버가 포함되어 있지 않으며, 이 예제에서는 드라이버를 새로 만들거나 애니메이션 전환을 지원한다고 주장하지 않습니다. 간단한 진행률 및 체크박스 동작은 별도의 애니메이션 의존성을 추가하지 않아도 작동합니다.

Tamagui 디자인 시스템 크기, 간격 및 모서리 반경 토큰

라벨이 같다고 토큰을 혼동하지 마세요

고정된 v5 구성에서 size $4는 44, space $4는 18, radius 4는 9입니다. 따라서 컴포넌트 크기, 레이아웃 간격, 모서리 반경에는 동일한 배율 규칙을 적용할 수 없습니다. 참고 자료에는 각 범주가 따로 나와 있으며, 예제에서는 실제 Tamagui 프롭을 통해 범주에 맞는 값을 사용합니다. 이 구성에서 사용하지 않는 일반적인 4px 단위 값의 목록보다 훨씬 유용합니다.

  • size.$4 = 44
  • space.$4 = 18
  • radius.4 = 9
  • 본문 글꼴 $4 = 15px, 행간 23px

타이포그래피 스케일도 별도로 유지하세요

본문 글꼴 $4는 23px 행간의 15px이며, 컴포넌트 크기 $4는 44입니다. 시스템 글꼴 스택은 v5에서 제공되므로 글꼴 파일을 다운로드할 필요가 없습니다. H1, H2, Text에는 각각 기본 글꼴 컨텍스트가 적용되고, 소스에 지정된 fontSize와 lineHeight 값이 원본 보드의 계층 구조를 결정합니다. 바깥쪽 너비 880px은 이 레이아웃에만 적용되는 선택이며, 전역 Tamagui 토큰이 아닙니다.

Tamagui 디자인 시스템 시맨틱 테마와 외관

파란색 하위 테마와 밝은 모드 또는 어두운 모드 조합하기

TamaguiProvider에는 선택한 defaultTheme을 전달하고, Theme name="blue"는 이에 해당하는 하위 테마를 적용합니다. 소스에서는 컴포넌트 트리 곳곳에 16진수 색상 값을 반복해서 쓰지 않고 background, backgroundHover, color, borderColor 역할을 사용합니다. 표에는 실제 light_blue와 dark_blue 값이 기록되어 있으므로, 하나의 고정된 브랜드 팔레트가 적용된다고 가정하는 대신 구성에 따라 해석된 값을 비교할 수 있습니다.

외관을 바꿔도 보드 상태 유지하기

dark 플래그는 행, 입력 초안, 필터와 별개로 관리됩니다. 외관을 전환하면 기본 컴포넌트의 모양만 바뀌고 보드는 그대로 유지됩니다. 버튼과 체크박스에는 각자의 컴포넌트 하위 테마 값이 적용될 수 있으므로, 계산된 색상이 부모 배경 토큰과 같지 않을 수 있습니다. 계층 구조를 사용자 지정 CSS로 단순화하기 전에 렌더링된 상태를 확인하세요.

Tamagui 디자인 시스템 체크박스와 계산된 진행률

완료 상태는 하나의 행 컬렉션에서 관리하세요

각 행에는 고유 ID, 읽기 쉬운 텍스트, done 불리언 값이 있습니다. Checkbox에는 checked와 onCheckedChange를 전달하며, 값이 true일 때만 완료로 표시합니다. Checkbox.Indicator는 체크 표시를 제공합니다. 인접한 텍스트와 접근성 이름은 같은 습관을 가리키며, 취소선은 완료 상태를 시각적으로도 나타냅니다. 소스에서는 행과 동기화되지 않을 수 있는 별도의 완료 개수를 만들지 않습니다.

보드 전체를 기준으로 진행률 계산하기

Tamagui 디자인 시스템 초안 유효성 검사와 중복 항목 처리

실제로 제어되는 입력 만들기

Input은 value와 onChangeText를 통해 현재 초안을 관리합니다. Add habit 동작은 입력값의 앞뒤 공백을 제거한 뒤, 비어 있으면 화면에 오류 메시지를 표시하고 aria-invalid 및 오류 설명을 설정합니다. 입력이 비어 제출되면 포커스가 입력란으로 돌아갑니다. 대소문자를 구분하지 않는 중복 검사를 통해 같은 텍스트가 두 번째 행으로 추가되지 않도록 하며, 수정할 수 있도록 초안을 그대로 유지합니다. 이러한 규칙은 라이브러리가 아니라 원본 보드에 속합니다.

유효한 항목을 추가한 뒤에만 보드를 업데이트하세요

초안이 유효하면 미완료 상태의 새 행을 추가하고, 입력을 비우고, 오류를 제거합니다. 새 컬렉션을 기준으로 계산되므로 진행률의 분모도 즉시 바뀝니다. 습관을 추가해도 알림이 등록되거나 계정이 생성되지는 않습니다. 보드 상태는 의도적으로 로컬 React 상태로 유지되며, 문서를 새로 불러오면 예시 상태로 돌아갑니다.

Tamagui 디자인 시스템 필터링된 보기와 빈 상태 복구

필터가 적용되는 범위를 명확히 하세요

미완료 항목만 표시하면 완료된 행은 컬렉션에 남겨 두고 화면에서만 숨깁니다. 해당 보기에서 표시할 항목이 없으면, 전체 목록은 그대로 있다는 설명과 전체 목록으로 돌아가는 바로가기 동작을 빈 상태에 표시합니다. 이는 사용자의 선택에 따라 의미 있게 나타나는 빈 상태이지, 임의의 플레이스홀더 카드를 바꾸는 장식용 토글이 아닙니다.

초기화와 외관 변경을 구분하세요

예시 보드 초기화는 처음의 세 행을 복원하고, 초안과 오류를 지우며, 전체 목록 보기로 돌아갑니다. 현재 외관은 바꾸지 않습니다. 각 변경이 명시적인 상태로 관리되므로 문서를 새로 불러오거나 설정된 provider를 버릴 필요가 없습니다. 테마와 콘텐츠 복구를 각각 독립적으로 테스트할 수 있습니다.

Tamagui 디자인 시스템 반응형 스택과 접근성 있는 읽기 흐름

스택 높이는 콘텐츠에 따라 결정되도록 하세요

YStack은 주요 읽기 흐름을 배치하고, XStack은 제목 컨트롤, 체크박스 행, 작업 버튼을 정렬합니다. 컨트롤 그룹은 줄바꿈되므로 데스크톱 너비를 고정할 필요가 없습니다. 바깥쪽 컨테이너의 최대 너비는 880px이며, 패딩에는 실제 space $4 토큰을 사용합니다. 각 행에서는 텍스트를 축소하고 줄바꿈할 수 있으며, 컨트롤은 280px 너비와 그보다 넓은 테스트 너비에서 모두 사용할 수 있습니다.

레이아웃이 바뀐 뒤에도 상호작용을 테스트하세요

브라우저 테스트에서는 오버플로를 측정하기 전에 습관을 추가하고, 완료로 표시하고, 목록을 필터링하고, 외관을 전환합니다. 처음 레이아웃의 스크린샷만으로는 오류, 긴 라벨, 필터링된 상태가 좁은 화면 구성에서 문제를 일으키는지 확인할 수 없습니다. 기본 체크박스의 시맨틱과 표시되는 텍스트는 진행률 계산과 함께 실제로 테스트했으며, 단순히 존재한다고 가정하지 않았습니다.

Tamagui 디자인 시스템 브라우저 빌드 완성하기

provider, CSS, 빌드 정의를 제공하세요

제공된 세 파일이면 로컬 웹 예제를 실행하기에 충분합니다. JSX에는 provider, 설정 하나, 생성된 테마 CSS, 전체 보드가 포함되어 있습니다. build.mjs는 웹 대상과 프로덕션 환경을 고정하고, 브라우저 전용 환경 변수 참조에 process.env가 없을 때 사용할 빈 값을 제공합니다. 이 마지막 정의가 없으면 컴파일에 성공하더라도 process is not defined 오류로 일반 번들 실행이 실패할 수 있습니다.

  1. tamagui.jsx, build.mjs, index.html을 같은 위치에 저장하세요.
  2. 고정된 React 및 Tamagui 패키지를 설치하세요.
  3. 로컬 디렉터리를 빌드하고 제공하세요.
  4. 빈 항목 및 중복 항목 추가, 완료 처리, 필터, 테마, 초기화를 테스트하세요.

네이티브와 웹 도입을 별도로 다루세요

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

tamagui.jsx

설정, 생성된 CSS, 네이티브 컴포넌트, 전체 보드 상태

jsx
import React,{useState} from 'react';import{createRoot}from'react-dom/client';
import{createTamagui,TamaguiProvider,Theme,YStack,XStack,Text,H1,H2,Button,Input,Checkbox,Progress,Separator}from'tamagui';import{defaultConfig}from'@tamagui/config/v5';
const config=createTamagui({...defaultConfig,settings:{...defaultConfig.settings,onlyAllowShorthands:false}});const sheet=document.createElement('style');sheet.textContent=config.getCSS();document.head.append(sheet);
const initial=[{id:1,text:'Read ten pages',done:false},{id:2,text:'Step outside for a break',done:true},{id:3,text:'Write one useful note',done:false}];
function App(){const[dark,setDark]=useState(false),[rows,setRows]=useState(initial),[draft,setDraft]=useState(''),[error,setError]=useState(''),[filter,setFilter]=useState(false);const done=rows.filter(x=>x.done).length;let shown=rows.filter(x=>!filter||!x.done);function add(){let text=draft.trim();if(!text){setError('Write a small habit before adding it.');document.querySelector('#habit-input')?.focus();return}if(rows.some(x=>x.text.toLowerCase()===text.toLowerCase())){setError('That habit is already in this list.');return}setRows([...rows,{id:Date.now(),text,done:false}]);setDraft('');setError('')}return <TamaguiProvider config={config} defaultTheme={dark?'dark':'light'}><Theme name="blue"><YStack backgroundColor="$background" color="$color" padding="$4" gap="$4" maxWidth={880} margin="auto" width="100%" minHeight={0}><XStack justifyContent="space-between" alignItems="center" flexWrap="wrap" gap="$3"><Text fontSize="$2" fontWeight="700">TAMAGUI / ORIGINAL HABIT BOARD</Text><Button size="$3" onPress={()=>setDark(!dark)}>{dark?'Light appearance':'Dark appearance'}</Button></XStack><H1 fontSize="$8" lineHeight="$8">A little progress, every day.</H1><Text fontSize="$4" lineHeight="$5">A local board built with Tamagui 2.7.7 and its v5 blue theme. Your changes stay in this page; no account or daily reminder is connected.</Text><YStack backgroundColor="$backgroundHover" borderWidth={1} borderColor="$borderColor" borderRadius="$4" padding="$4" gap="$3"><XStack justifyContent="space-between" gap="$3" flexWrap="wrap"><H2 fontSize="$5">Today’s small steps</H2><Text id="progress-count" aria-live="polite">{done} of {rows.length} complete</Text></XStack><Progress value={rows.length?done/rows.length*100:0} size="$2" aria-label="Completed habits"><Progress.Indicator animation={undefined}/></Progress><Button size="$3" alignSelf="flex-start" onPress={()=>setFilter(!filter)}>{filter?'Show all habits':'Show unfinished only'}</Button><Separator/>{shown.length?shown.map(row=><XStack key={row.id} gap="$3" alignItems="center" paddingVertical="$2"><Checkbox id={'habit-'+row.id} checked={row.done} onCheckedChange={value=>setRows(rows.map(x=>x.id===row.id?{...x,done:value===true}:x))} aria-label={row.text} size="$4"><Checkbox.Indicator><Text fontWeight="700">✓</Text></Checkbox.Indicator></Checkbox><Text flex={1} fontSize="$4" lineHeight="$5" textDecorationLine={row.done?'line-through':'none'} opacity={row.done?.65:1}>{row.text}</Text></XStack>):<YStack gap="$3"><Text fontWeight="700">Nothing unfinished in this view</Text><Text>All your habits remain in the full list. You can revisit any completed item.</Text><Button onPress={()=>setFilter(false)}>Return to all habits</Button></YStack>}</YStack><YStack gap="$3"><Text htmlFor="habit-input" tag="label" fontWeight="700">Add one small habit</Text><Input id="habit-input" value={draft} onChangeText={v=>{setDraft(v);setError('')}} placeholder="For example, stretch for five minutes" aria-describedby={error?'habit-error':undefined} aria-invalid={!!error} onKeyPress={e=>{if(e.nativeEvent.key==='Enter')add()}}/><Text id="habit-error" color="$color" aria-live="polite">{error}</Text><XStack gap="$3" flexWrap="wrap"><Button theme="active" onPress={add}>Add habit</Button><Button onPress={()=>{setRows(initial);setDraft('');setError('');setFilter(false)}}>Reset sample board</Button></XStack></YStack><Text fontSize="$2" lineHeight="$3">Native Checkbox, Input, Button and Progress components; original board content and state. Theme changes preserve the current board.</Text></YStack></Theme></TamaguiProvider>}
createRoot(document.getElementById('root')).render(<App/>);

코드 참조

  • 이 세 파일을 함께 사용하세요.

build.mjs

테스트된 번들에서 사용하는 브라우저 환경 정의

자바스크립트
import {build} from 'esbuild';
await build({entryPoints:['tamagui.jsx'],bundle:true,minify:true,outfile:'tamagui.bundle.js',define:{'process.env.NODE_ENV':'"production"','process.env.TAMAGUI_TARGET':'"web"','process.env':'{}'}});

코드 참조

  • 이 세 파일을 함께 사용하세요.

index.html

독립 실행형 루트 문서 및 번들 가져오기

html
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Small habits board</title><style>body{margin:0}*{box-sizing:border-box}button,input{max-width:100%}</style></head><body><div id="root"></div><script src="./tamagui.bundle.js"></script></body></html>

코드 참조

  • 이 세 파일을 함께 사용하세요.
04

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

구현 시작점

먼저 제공된 파일을 저장한 다음 http://localhost:8000/을 여세요. 이 설정은 브라우저를 대상으로 합니다.

sh
npm init -y
npm install [email protected] [email protected] [email protected] @tamagui/[email protected]
npm install --save-dev esbuild
node build.mjs
python3 -m http.server 8000

프로젝트를 위한 프롬프트

에이전트 프롬프트
v5 프리셋을 사용해 Tamagui 2.7.7 웹 습관 보드를 완전하게 구현하세요. 크기, 간격, 모서리 반경, 글꼴 토큰 범주를 서로 구분하고, 생성된 테마 CSS, 밝고 어두운 파란색 하위 테마, 제어된 체크박스, 앞뒤 공백 제거 및 중복 검사, 전체 행을 기준으로 한 진행률 분모, 미완료 보기로 돌아가기, 모양을 바꾸지 않는 초기화를 유지하세요.
05

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

v5 프리셋을 사용하는 실제 Tamagui 2.7.7 웹 컴포넌트입니다. 습관 보드와 상태 규칙은 독자적으로 작성한 OpenDesign 코드이며, 계정·알림·네이티브 기기 동작은 연결되어 있지 않습니다.