개발자가 자꾸 물어본다면? 피그마 기획서에 '컴포넌트 상태(State)' 정의하는 법
개발자가 자꾸 물어본다면? 피그마 기획서에 '컴포넌트 상태' 정의하는 법
기획안을 넘기고 나면 끝날 줄 알았는데, 개발자에게 이런 질문을 자주 받나요?
- “이 버튼 누르면 로딩 중일 때 어떻게 보여요?”
- “값 입력 안 했을 때 비활성화 되나요?”
- “에러 메시지는 어디에 떠요?”
이 질문들이 반복된다면, 기획서에 빠진 건 기능이 아니라 상태(State)입니다.
오늘은 피그마에서 컴포넌트 상태를 ‘한 번만’ 제대로 정의해서, 질문은 줄이고 완성도는 올리는 방법을 정리합니다. (버튼 박스 밀기 대신 퇴근을 밀어봅시다. ✅)
1) 상태(State) 정의, 왜 기획자가 해야 할까?
디자인이 ‘심미성’을 다듬는다면, 기획은 ‘논리’를 설계합니다. 즉, 사용자의 액션에 따라 화면이 어떻게 변해야 하는지를 가장 정확히 아는 사람은 기획자일 때가 많습니다.
- 누락 방지: 상태를 적어두면 개발 시 예외 처리(Disabled/Loading/Error)가 빠질 확률이 낮아집니다.
- 해석 비용 절감: “그때그때 맞추죠”는 대개 재작업으로 돌아옵니다.
- 품질 상승: 동일한 컴포넌트가 화면마다 다르게 동작하는 ‘서비스 다중인격’ 현상을 막습니다.
2) 기획자가 챙겨야 할 5가지 필수 상태(State)
모든 UI를 그릴 필요는 없지만, 핵심 컴포넌트(버튼, 인풋, 탭 등)는 최소 아래 5가지를 갖추는 게 안전합니다.
- Default: 초기 상태(아무 행동도 하지 않았을 때)
- Hover / Pressed: 사용자 피드백(마우스 오버/클릭/탭)
- Disabled: 조건 미충족으로 클릭 불가(예: 필수 입력/약관 동의 전)
- Error / Success: 결과 피드백(검증 실패/성공 완료)
- Loading: 요청 처리 중(중복 클릭 방지 포함)
현실 팁: 기획서에서 Hover는 PC 웹에서만 강조하고, 모바일/앱은 Pressed(탭 피드백)와 Disabled/Loading에 더 힘을 주면 효율이 좋습니다.
3) 피그마로 상태 정의하는 법: Variants + 조건(Logic) 텍스트
3-1. 핵심 전략: 상태를 “그림”이 아니라 “스위치”로 만들기
피그마의 Variants를 쓰면, 같은 컴포넌트를 상태별로 묶어두고 오른쪽 패널에서 상태값만 바꿔가며 배치할 수 있습니다.
즉, 기획자는 화면을 만들 때 “새로 그리기”가 아니라 “상태 바꾸기”만 합니다.
3-2. 만들 순서(딱 이대로)
- 공통 컴포넌트를 하나 정합니다. (예: Primary Button)
- 그 컴포넌트를 상태별로 복제한 뒤 Variants로 묶습니다.
- Variant 속성(Property)을 State로 만들고 값(Value)을 추가합니다.
- State: Default / Hover / Pressed / Disabled / Loading / Error / Success
- 기획 화면(Storyboard)에서는 인스턴스를 배치한 뒤, 오른쪽 패널에서 State 값만 변경합니다.
3-3. 상태 정의의 절반은 ‘조건(Logic)’ 문장이다
상태는 “그림”만 있으면 반쪽입니다. 개발자가 진짜 필요로 하는 건 이거예요.
“언제(조건) 그 상태가 되고, 무엇이(표현) 바뀌며, 다음 행동이(전이) 무엇인지”
3-4. 추천 표기 방식: When / Then / Next
[State] Disabled
- When: 필수 입력값이 비어있음 OR 약관 미동의
- Then: 버튼 비활성화(클릭 불가), 툴팁/문구 노출 여부: (있음/없음)
- Next: 입력 완료 시 Default로 전환
4) 바로 복붙 가능한 상태 정의 템플릿(버튼/인풋)
4-1. 버튼(Button) 상태 정의 템플릿
[Component] Button / Primary
[State: Default]
- When: 진입 시 기본
- Then: 클릭 가능
- Next: 클릭 시 Loading(요청 발생)
[State: Pressed]
- When: 클릭(탭) 순간
- Then: 눌림 피드백(색/그림자/축소 등)
- Next: 손 떼면 Default 또는 Loading
[State: Disabled]
- When: (필수 입력 미완료) OR (약관 미동의) OR (권한 없음)
- Then: 클릭 불가, 시각적 약화(색/투명도)
- Next: 조건 충족 시 Default
[State: Loading]
- When: API 요청 진행 중
- Then: 중복 클릭 불가, 로딩 인디케이터 표시, 라벨 정책(유지/변경) 명시
- Next: 성공 시 Success(또는 화면 전환), 실패 시 Error
[State: Error]
- When: 요청 실패(네트워크/서버/검증 실패 등)
- Then: 에러 노출 위치(버튼 상단? 인풋 하단?), 문구 규칙(서버 메시지 그대로/가공)
- Next: 재시도 가능 여부, Default로 복귀 조건
4-2. 인풋(Input) 상태 정의 템플릿
[Component] Input / Text Field
[State: Default]
- When: 진입 시
- Then: placeholder 노출, 기본 테두리
[State: Focus]
- When: 클릭/탭으로 포커스
- Then: 커서 표시, 포커스 테두리/강조
[State: Error]
- When: 검증 실패(예: 이메일 형식 아님 / 글자수 부족)
- Then: 에러 메시지 위치: 입력창 하단(권장), 테두리 색 변경
- Next: 올바른 값 입력 시 Default 또는 Success
[State: Disabled]
- When: 특정 조건에서 입력 금지(예: 인증 완료 후 수정 불가)
- Then: 입력 불가, 값 선택/복사 가능 여부 명시
[Edge]
- Max length 초과 시: 입력 차단/추가 입력 무시/카운터 표시 여부
- 긴 텍스트: 말줄임/스크롤 정책 명시
실전 팁: 템플릿을 ‘공통 가이드 섹션’에 넣고, 각 화면에서는 “사용 컴포넌트 + 적용 조건”만 링크로 참조하면 문서가 얇아지는데 정보는 더 진해집니다.
5) 예외 케이스(Edge Case) 체크리스트
개발자의 질문이 폭발하는 구간은 보통 “정상 흐름”이 아니라 “예외 흐름”입니다. 아래는 최소 체크리스트예요.
- Empty: 데이터가 0개일 때(첫 진입/검색 결과 없음/장바구니 비었음)
- Network Error: 오프라인/타임아웃/서버 장애
- Permission: 권한 없을 때(유료/관리자/연령 제한 등)
- Long Text: 제목/라벨이 길어졌을 때(줄바꿈/말줄임표/2줄 제한)
- Loading: 스켈레톤/스피너/버튼 로딩(중복 클릭 방지 포함)
이 5개만 적어도 “그럼 이건요?” 질문이 확 줄어듭니다.
6) 개발자가 감동하는 구성: ‘공통 컴포넌트 가이드’ 섹션
화면 정의서(Storyboard)마다 같은 설명을 반복하면, 문서가 무거워지고 업데이트가 늦어집니다.
대신 피그마의 Section을 활용해 파일 상단(또는 별도 페이지)에 아래 구조로 “사전”을 하나 만드세요.
추천 섹션 구조
- Component Index: 버튼/인풋/탭/토스트 목록 + 링크
- State Matrix: 각 컴포넌트별 상태(Variants) 모음
- Logic Rules: Disabled/Loading/Error 조건 문장
- Edge Cases: Empty/Network/Permission/Long Text 정책
운영 규칙(중요)
- Storyboard에서는 “상태 설명”을 길게 쓰지 말고, 공통 가이드 링크 + 조건 한 줄로 끝내기
- 상태명(State 값)은 팀에서 철자 통일(Default/Disabled/Loading…)
- Loading은 반드시 중복 클릭 방지 포함 여부를 명시(진짜 자주 터집니다)
이 구조가 갖춰지면, 개발자는 기획서를 “읽는 문서”가 아니라 “참조하는 사전”으로 쓰기 시작합니다. 그때부터 질문이 “무엇?”에서 “확인”으로 바뀝니다. ✅
결론: 설계의 디테일이 기획의 수준을 결정한다
“나중에 개발하면서 맞추죠”는 대부분 재작업으로 돌아옵니다.
피그마에서 컴포넌트 상태를 한 번 더 고민하는 10분이, 개발자와의 수 시간을 아껴줍니다.
오늘 할 일은 딱 하나입니다. 여러분의 피그마 파일에 Disabled 상태 하나를 추가하고, 그 옆에 조건을 한 줄 적어보세요.
FAQ
Q 상태를 어디까지 정의해야 하나요?
A핵심 컴포넌트(버튼/인풋/탭/토스트)만이라도 Default/Disabled/Loading/Error는 꼭 잡는 편이 안전합니다. Hover는 PC 웹에서 우선순위를 올리고, 모바일은 Pressed 중심으로 두면 효율이 좋습니다.
Q Variants를 디자이너만 쓰는 기능 아닌가요?
A디자이너는 디자인 시스템을 위해 쓰고, 기획자는 “상태를 빠르게 바꿔 보여주기” 위해 씁니다. 기획서에서 Variants는 ‘그림 실력’을 보완하는 게 아니라 ‘수정 속도’를 올려줍니다.
Q Disabled 조건을 어떻게 문장으로 쓰면 좋을까요?
A“When/Then/Next”로 쓰면 개발자가 바로 구현하기 좋습니다. 예: When(필수 입력 미완료) Then(클릭 불가+시각 약화) Next(입력 완료 시 Default 전환).
Q 에러 메시지 위치는 꼭 정해야 하나요?
A네. “어딘가에 뜸”은 구현에서 가장 애매합니다. 인풋 에러는 보통 입력창 하단, 전역 에러는 토스트/다이얼로그처럼 영역을 구분해서 한 줄로 확정해두면 좋습니다.
Q Empty/Network 같은 건 화면마다 달라서 공통화가 어렵지 않나요?
A표현은 달라도 “정책”은 공통화할 수 있습니다. 예: Empty는 안내 문구+CTA 유무, Network는 재시도 버튼 유무, Permission은 접근 차단 메시지 톤 같은 것들이요.
Q 상태 정의를 공통 가이드로 빼면, 화면 기획서는 뭘 남기죠?
A화면 기획서는 “구성(무엇이 어디에)”과 “적용 조건(언제 어떤 상태)”만 남기면 됩니다. 상세 정의는 공통 가이드에서 참조하게 만들면 문서 유지보수가 쉬워집니다.