From Ohouse Design Plugin
Figma 디자인을 @bucketplace/design-system React 화면(.tsx)으로 변환해 prototypes/contents-feed live 프리뷰에서 렌더하고 프로토 제작의 원천 소스로 만든다. ODS 인스턴스는 결정론 매핑(ods-components-index + components-react.md), 비-ODS는 flex+토큰 합성. 검증은 구조/컴포넌트 정합 + tsc + pixel-diff(참고). 사용자가 "Figma를 React로", "ODS React 화면 만들어줘", "contents-feed에 화면 추가", "figma-to-ods-react 실행" 같은 요청을 할 때 트리거.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ohouse-design-plugin:figma-to-ods-reactThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Figma 디자인을 `@bucketplace/design-system` React 화면(.tsx)으로 변환해 `prototypes/contents-feed` live 프리뷰에서 렌더하고, 이후 프로토 제작의 원천 소스로 삼는다. ODS 인스턴스는 결정론 매핑, 비-ODS 노드는 flex+ODS 토큰으로 합성한다. (v1 = 단일 화면)
Figma 디자인을 @bucketplace/design-system React 화면(.tsx)으로 변환해 prototypes/contents-feed live 프리뷰에서 렌더하고, 이후 프로토 제작의 원천 소스로 삼는다. ODS 인스턴스는 결정론 매핑, 비-ODS 노드는 flex+ODS 토큰으로 합성한다. (v1 = 단일 화면)
한 줄 정의: Figma 디자인을 ODS의 진짜 React 컴포넌트로 변환하는 스킬. "그림을 코드처럼 베끼는" 게 아니라 디자인시스템 부품으로 다시 조립해 계속 쓰는 화면 소스를 만든다.
match-ods, componentId→이름 폴백) → ② 번역(resolve-ods, Figma variant→npm props, 추정 금지) → ③ 조립+검증(emit → tsc + 정합 게이트)FIGMA_TOKEN 또는 한시 입력 — 커밋 금지).PD="${CLAUDE_PLUGIN_ROOT}/skills/new-ods-ui-builder/pixel-diff"
[ -d "$PD/node_modules" ] || (cd "$PD" && npm install)
cd prototypes/contents-feed; [ -d node_modules ] || pnpm install
https://figma.com/design/{fileKey}/{name}?node-id={nodeId} → fileKey / nodeId 추출. 하이픈→콜론 변환(1512-38967 → 1512:38967).
Figma REST API(/v1/files/{fileKey}/nodes?ids={nodeId}&depth=20&geometry=paths, X-Figma-Token 헤더)로 노드 트리 수집 → {workdir}/node.json 저장. 토큰 만료 응답("Token expired") 확인.
node ${CLAUDE_PLUGIN_ROOT}/skills/new-ods-ui-builder/pixel-diff/checklist.js \
--node={workdir}/node.json --root={nodeId} --out={workdir}/checklist.md
bucketplace-product-design 플러그인의 ods-prototype MCP가 연결돼 있으면(ToolSearch 로 resolve_figma_component 가 뜨면) MCP를 1순위 식별·검증 도구로 쓰고, 아래 오프라인 파이프라인을 폴백으로 둔다. MCP 도구는 결정론적 카탈로그 조회라 결정론·추정금지 원칙과 정합한다. MCP 미연결이면 이 단계를 건너뛰고 Step 4.1(오프라인)만 수행 — 기능 동등.
resolve_figma_component(figmaName, layerPath?, dimensions?, visualHints?) 호출. resolved && confidence:'high' && props≠{} 이면 그 props 채택. props 가 비었거나(예 Chip/ScrapButton compound) confidence<high면 Step 4.1 오프라인 결과로 폴백.get_component(PascalCaseName) 로 required prop·enum·canonicalUsage 확인 → components-react.md 보다 우선(불일치 시 d.ts 확정값인 MCP 채택 + components-react.md 갱신). 예: Chip = size/variant 둘 다 required.check_component_name(PascalCaseName) — 공백 포함 표시명은 isOds:false 나오니 PascalCase 로 질의(ScrapButton, not Scrap Button). isOds:false면 제안된 ODS 대체 사용.get_component.canonicalUsage 는 일반 예시지 화면 데이터가 아니다 — props·children 은 반드시 실제 Figma 노드값으로 채운다(예: Section.HeaderAction 은 <button>{children}</button>이라 chevron 자동 안 그림 → 예시 "더보기" 텍스트 복사 금지, Figma 의 실제 액션(chevron 등) 사용). ② 이름-only(via:name)·MCP high 식별이어도 "스타일/간격까지 ODS 기본과 동일"의 보장이 아니다 — ODS 컴포넌트 내부 padding/gap 이 Figma 실측과 다를 수 있으니 Step 6 렌더 대조 전 무조건 치환 금지, 어긋나면 인라인 style 로 Figma 실측 보정.먼저 ODS 인스턴스를 결정론 매처+번역기로 일괄 식별·번역한다:
node ${CLAUDE_PLUGIN_ROOT}/skills/new-ods-ui-builder/pixel-diff/match-ods.js \
--node={workdir}/node.json --root={nodeId} \
| node ${CLAUDE_PLUGIN_ROOT}/skills/new-ods-ui-builder/pixel-diff/resolve-ods.js \
> {workdir}/ods-matches.json
→ [{ id, name, ods, via, variantProps, render, props, unresolved, overrides }]
🌀 Tab→Tab, spec §10). 이름 정리는 🌀/이모지뿐 아니라 "ODS " 텍스트 접두도 제거("ODS Scrap Button"→"Scrap Button") — 이 접두를 안 떼면 62개 스크랩버튼·54개 썸네일이 통째로 누락된다. 동시에 Figma variantProps(Size/Color/…)와 render 실측값(stroke·textColor·height·fontWeight)을 함께 캡처.variantProps→npm props(예 Chip white/32(Mobile)→{size:'sm',variant:'normal'}), 미확정 값은 unresolved 플래그(추정 금지, TABLES 확정 매핑만). render 가 variant 기본과 다르면 overrides(예 보라 #6f3dde) 추출. 현재 TABLES 커버리지 = Chip, Scrap Button. 미등록 컴포넌트는 unresolved 로 나오는 게 정상(아래 emit 규칙대로 채움). TABLES 키 = match-ods 가 뱉는 ods 값 = ods-components-index 의 name(공백 포함, 예 'Scrap Button'). 불리언 축(Selected/Disabled 등)은 { axis, bool:true } 로 등록("True"/"False"→boolean).props 그대로 사용. unresolved 있으면 d.ts/번들/Code Connect 확인 후 resolve-ods.js TABLES 에 매핑 추가(components-react.md 번역표·gen-tables.js 와 동기). overrides 적용 위치 주의: 텍스트/아이콘 색은 인라인 style={{color}}, 테두리·배경은 ::before 에 그려져 인라인 무효 → className+::before 규칙(react-gotchas §8).변환 결과는 제공된 Figma 노드가 실제로 보여주는 것 과 1:1이어야 한다. 아래를 어기면 "있지도 않은 요소"가 화면에 새는 흔한 결함이 난다.
visible === false 인 노드(및 그 하위)는 변환하지 않는다. match/dump 가 텍스트를 뱉어도 hidden 이면 무시. (예: 카드 overlay User Information/Scrap Button/댓글 이 visible:false 인데 렌더하면 Figma에 없는 프로필/찜/댓글이 생김.)SLOT(↳ Accessory 등)의 자식은 컴포넌트 기본/미리보기다. 인스턴스가 그 slot 을 실제로 채우지 않았으면 렌더하지 않는다(기본값을 콘텐츠로 착각 금지)."Slot (swap it with your content)", "Section Title Left/Right", "Action Label", "Description" 류는 컴포넌트 자리표시자 → 실제 override 된 값만 사용.✦ Section Title 안의 On Press → [Icon] Chevron Right(=제목 바로 옆 인라인)이지, 우측 끝 별도 액션이 아니다. 헤더 설명은 Center Container의 Bottom(=제목 위)에 올 수 있다. itemSpacing/정렬/순서를 node 에서 실측해 배치.MinimalContentCard)으로 분기.absoluteBoundingBox(위치/크기)·형제 y 비교·색까지 같은 패스에서 읽어 반영한다. 이걸 빼먹으면 색 tint·줄바꿈·요소 위치가 눈대중으로 새어 들어간다(실측 사례에서 반복 발생):
★avg · 리뷰N y=220 / 무료배송 y=239 → 무료배송은 다음 줄). 텍스트 값만 보고 한 줄로 평탄화 금지.#ffffff 로 보임). 아이콘을 회색 텍스트 span 으로 감싸 색을 상속시키지 말고, 토큰으로 색을 명시한다(예 리뷰 별 = accentYellow #FFC300, LIGHT_THEME.colors 에서 확인).각 노드를 4분기로 변환:
ods-matches.json 에 매칭된 노드): 매칭된 ODS 컴포넌트명+variant props 를 ${CLAUDE_PLUGIN_ROOT}/skills/new-ods-ui-builder/assets/ods-components-index.json 에서 조회 → references/components-react.md 로 @bucketplace/design-system JSX+props 매핑 (enum 정규화 d.ts 확정값). via:'name' 으로 매칭된 컴포넌트가 components-react.md 에 없으면 d.ts 확인 후 매핑 추가(추정 금지).
componentProperties(Size/Color/…)를 읽어 components-react.md 의 Figma→npm 번역표로 variant/size 결정 — 이름으로 추측 금지(Figma↔npm 스키마 드리프트). 변환 후 노드 실측 렌더값(stroke 색·두께·height·font-weight)과 ODS 렌더를 대조해 갭 확인. 인스턴스 색 오버라이드는 style 복원 or 갭 보고. 상세: references/react-gotchas.md §8.<div> flex — layoutMode→flexDirection, itemSpacing→gap, padding→padding, 색→LIGHT_THEME.colors.<Text variant={textStyle}> (Figma style→ODS textStyle).@bucketplace/icons (이름 매칭, weight 필수) 또는 <img> 실 URL.references/react-gotchas.md 함정 점검.prototypes/contents-feed/src/screens/<ScreenName>.tsx 생성 — ScreenShell(../prototype-ods/index)로 감쌈. ScreenShell 필수 props: topNavigation(없으면 null), children; 선택 osChrome(기본 'ios')·footer.prototypes/contents-feed/src/screens/index.ts 의 SCREENS 에 <ScreenName> 등록.(a) tsc 게이트 (필수):
cd prototypes/contents-feed && npx tsc --noEmit
에러 0 필수. 실패 시 prop/enum을 references/components-react.md·d.ts와 대조해 수정 후 재실행.
(b) 정합 체크리스트 (필수 합격 기준): checklist.md 항목이 화면에 모두 있는가 + Figma의 ODS 인스턴스가 전부 ODS React 컴포넌트로 변환됐는가(raw <div> 근사 0). 미달 시 self-retry.
(c) pixel-diff (참고용, 게이트 아님):
cd prototypes/contents-feed && (npm run dev > /tmp/cf-dev.log 2>&1 &) && sleep 5
node ${CLAUDE_PLUGIN_ROOT}/skills/new-ods-ui-builder/pixel-diff/diff.js \
--file={fileKey} --node={nodeId} \
--url="http://localhost:5173/?screen=<ScreenName>" \
--token=$FIGMA_TOKEN --viewport=375x812 --scale=2 --out={workdir}/diff-<ScreenName>
pkill -f vite
diffRatio는 참고값으로만 보고.
사용 ODS 컴포넌트(이름+variant+React props, 식별 출처 MCP/오프라인) / 합성한 비-ODS 노드 / 누락·불확실(MCP↔오프라인 충돌 포함) / pixel-diff %(참고) / shared-components 후보.
ODS 미보유 + 공통화 가치가 있는 패턴 → ${CLAUDE_PLUGIN_ROOT}/skills/htmlviaTrueSource/shared-components/ 규약(.tsx + .usage.md + .spec.ts 삼중 + CATALOG.md 등재). 1회성 레이아웃은 화면에 인라인(등록 안 함).
LIGHT_THEME.colors).@bucketplace/icons).references/components-react.md).prototypes/contents-feed/src/App.tsx 수정(스위처 ?screen= 로 노출).bucketplace-product-design 플러그인, 연결 시 1순위): resolve_figma_component(Figma 신호→ODS+props), get_component(import·props스키마·canonicalUsage·compound), check_component_name(BDS/legacy 판별+대체). 미연결이면 오프라인 폴백. 상세 spec §11.references/components-react.md — ODS → @bucketplace React 매핑 (v1 핵심 컴포넌트)references/react-gotchas.md — ODS React 함정${CLAUDE_PLUGIN_ROOT}/skills/new-ods-ui-builder/: assets/ods-components-index.json, pixel-diff/checklist.js, pixel-diff/diff.js(--url 지원), pixel-diff/match-ods.js(ODS 매처 — 이름 폴백 + variant/render 캡처), pixel-diff/resolve-ods.js(variant 번역 + override 추출 + 드리프트 핀, TABLES 확정 매핑 = 현재 Chip), pixel-diff/gen-tables.js(DS Code Connect .figma.tsx → TABLES 자동 생성)docs/superpowers/specs/2026-06-10-figma-to-ods-react-design.mdProvides a checklist for code reviews covering functionality, security, performance, maintainability, tests, and quality. Use for pull requests, audits, team standards, and developer training.
npx claudepluginhub ohouse-product-design/ohouse-design --plugin ohouse-design-plugin