개발자 리소스
토큰과 컴포넌트를 소비하는 방법 — Web/React와 Flutter(wiz_ui) 모두 설치·테마·계약·테스트 게이트까지 사용 가능.
마지막 업데이트 2026-06-13
설치 · 소비 (Web)#
@wds/ui-web는 사내 GitLab npm 레지스트리로 배포됩니다 — 다른 제품에서 설치해 쓰는
방법은 패키지 설치 가이드 를 보세요. 모노레포
안에서는 같은 워크스페이스에서 배럴로 가져옵니다.
import { Button, Input, Modal } from '@wds/ui-web';
컴포넌트는 --wds-* CSS 변수를 소비합니다 — 앱이 토큰 시트를 한 번 로드하고
[data-theme]로 테마를 전환합니다(다크는 다크 모드 참조).
// 앱 진입(layout 등)에서 생성된 토큰 시트를 1회 로드 (codegen 산출물 tokens/dist/wds.css)
import '../../tokens/dist/wds.css';
// <html data-theme="light | dark"> 에서 테마 결정 — FOUC 방지 스크립트는 동기 주입
브레이크포인트 상수가 필요하면 별도 서브패스로 가져옵니다(CSS 미디어쿼리는 var()
불가라 JS 상수로 소비 — ADR-012).
import { BP } from '@wds/ui-web/breakpoints'; // BP.compact 600 · BP.expanded 840
ref 전달 (React 19 ref-as-prop)#
전 컴포넌트(58종)가 ref를 전달합니다 — 선택적 가산 prop이라 기존 호출은 무영향.
React 19에서 ref는 일반 prop이므로 forwardRef 없이 직접 받습니다. ref 타깃은
컴포넌트 종류로 정해집니다(정본: COMPONENT_API §2).
| 종류 | ref 타깃 | 예 |
|---|---|---|
| 폼 컨트롤 | 네이티브 컨트롤 요소(input/textarea/토글 button) | Input·Checkbox·Switch·Slider |
| 버튼·링크 | 루트 인터랙티브 요소 | Button·IconButton·Chip·TextLink |
| 트리거 보유 오버레이 | 트리거 button | Select·Popover·DropdownMenu·DatePicker |
| 명령형 다이얼로그 | 패널 [role=dialog] — 닫힘(미마운트) 동안 null | Modal·Drawer·BottomSheet·SideSheet |
| 레이아웃·합성·Tooltip | 최외곽 루트 | Card·Stack·Tabs·DataGrid·Tooltip |
폼 컨트롤 ref가 래퍼가 아니라 컨트롤 요소를 가리키므로 React Hook Form 등록이 바로 동작합니다.
const { register } = useForm();
<Input aria-label="이메일" {...register('email')} />; // ref가 내부 <input>에 병합된다
명령형 다이얼로그는 닫혀 있으면 포털이 미마운트되어 ref.current가 null입니다 —
열림 이후에 패널을 참조하세요.
테스트 게이트#
루트에서 단일 명령으로 전 게이트를 돌립니다.
make check # 빠른(~13초): 타입체크 · eslint · stylelint(DD-4) · 유닛
make check-full # 전체(~5분): check + 실브라우저 axe + 시각 회귀(빌드 포함)
make hooks # push 전 make check 자동 실행(opt-in, core.hooksPath)
| 게이트 | 명령 | 잡는 것 |
|---|---|---|
| 토큰 대비/패리티 | pnpm --filter @wds/build-tokens test | WCAG AA·토널 대비 법칙·Web↔Dart 일치 |
| 컴포넌트 유닛 | pnpm --filter @wds/ui-web test | 동작·ARIA 구조(jsdom axe) |
| 실브라우저 a11y | pnpm --filter @wds/ui-web test:browser | color-contrast 실측(Chromium) |
| 시각 회귀 | pnpm --filter @wds/portal test:visual | 브레이크포인트×테마 픽셀 디프 |
스타일은 --wds-* 토큰만 허용됩니다(DD-4 — stylelint가 색·그림자·라디우스·보더·
폰트의 raw 값을 차단). 베이스라인 갱신은 pnpm --filter @wds/portal test:visual:update.
설치 · 소비 (Flutter — wiz_ui)#
같은 토큰 SSOT가 wiz_tokens.dart로 생성되어 flutter/wiz_ui에 흐릅니다.
모노레포 안에서는 path 의존, 외부 제품 리포는 git tag 의존(AD-9 — ref: 고정,
main 직소비 금지)으로 가져옵니다. Pretendard(OFL)가 패키지에 동봉되어 별도 폰트
설정이 필요 없습니다.
dependencies:
wiz_ui:
git:
url: ... # wiz-design-system 저장소
path: flutter/wiz_ui
ref: wiz_ui-v0.5.0 # 릴리스 태그 고정
테마는 WizTheme 팩토리 한 쌍으로 적용하고, 색은 WizTheme.of(context)로 읽습니다.
import 'package:wiz_ui/wiz_ui.dart';
MaterialApp(theme: WizTheme.light(), darkTheme: WizTheme.dark(), themeMode: mode);
final c = WizTheme.of(context).colors; // WizColorScheme — c.primary, c.textMuted …
컴포넌트 15종(WizButton~WizKnowledgeCard)은 웹과 같은 계약을 따릅니다 —
variant는 enum, 크기는 WizSize.sm/md/lg, 비활성화는 onPressed: null 관용,
슬롯은 Widget?. 전체 매핑 규칙은 COMPONENT_API §3이 정본입니다.
| 웹(React) | Flutter | 비고 |
|---|---|---|
variant="secondary" | variant: WizButtonVariant.secondary | 유니온 = enum |
disabled | onPressed: null (+enabled) | Flutter 관용 우선 |
leadingIcon={node} | leadingIcon: Widget? | 슬롯 = Widget |
Modal open/onClose | await WizModal.show(context, …) | 명령형 — pop 값이 Future로 |
useToast() | WizToaster.show(context, …) | 우하단 스택·자동 닫힘 |
useResponsive() | WizResponsive.of(context) | compact/medium/expanded 동일 경계 |
반응형은 WizResponsive + 레이아웃 프리미티브(WizStack·WizContainer·WizGrid·
WizSplit — 웹 4종과 동일 토큰)로 구성하고, WizGrid는 size class에 따라
4/8/12컬럼을 자동 적용합니다.
Flutter 게이트#
cd flutter/wiz_ui
flutter analyze # 0 이슈 (strict)
flutter test # 단위·위젯·골든
cd example && flutter test # 데모 + 웹/Flutter 로그인 패리티 diff ≤ 5%
패리티는 같은 카드 폭의 웹 캡처와 Flutter 골든을 픽셀 비교하는 게이트로
상시 검증됩니다(현재 실측 라이트 2.70% · 다크 2.55%). 설치·계약·하니스의 전체
정본은 저장소 docs/FLUTTER_GUIDE.md입니다.