설명
개인정보보호법과 정보통신망법 영향으로 한국 서비스는 약관을 항목별로 받아야 합니다. 그래서 최상단에 '전체 동의' 한 줄을 두고 그 아래에 개인정보와 이용약관, 마케팅, 제3자 제공 같은 4~6개 개별 항목을 두는 형태가 자리 잡았어요. 각 항목 옆에는 필수와 선택을 구분하는 칩이 붙고, 우측 '보기' 버튼을 누르면 약관 전문이 모달로 떠요. '전체 동의'는 모든 하위 체크를 한꺼번에 토글하는데, 필수만 자동 체크하고 선택은 따로 두는 변형도 있습니다.
🖼️ 미니어처
💬 AI에게 이렇게 말하세요
- 한국형 약관 다중 동의 UI를 만들어 주세요. 최상단 '전체 동의' (굵은 큰 텍스트, 큰 체크박스) + 하위 5개 개별 약관 (각 항목에 '필수' 또는 '선택' 칩 + '보기' 텍스트 버튼).
- '전체 동의'를 클릭하면 모든 하위 체크가 토글되도록 처리. 하위 중 하나라도 안 체크되면 '전체 동의'도 자동 해제.
- 약관 보기는 별도 모달로 띄우고, 모달 안에는 약관 전문 + '동의'/'동의 안 함' 버튼.
최소 5개 항목
- [필수] 만 14세 이상입니다
- [필수] 이용약관 동의
- [필수] 개인정보 수집·이용 동의
- [선택] 마케팅 정보 수신 동의 (이메일·SMS 별도 분리 권장)
- [선택] 제3자 정보 제공 동의 (해당 시)
⚡ 사용 예 (한 줄)
const allChecked = terms.every(t => t.checked); const onAllChange = (v) => setTerms(terms.map(t => ({...t, checked: v}))); 🧩 컴포넌트 매핑
shadcn/ui Checkbox와 자체 TermsAggregator 패턴을 조합해요. react-hook-form의 useFieldArray와 결합하는 방식을 권장합니다. Headless UI Switch는 체크박스 시각이 표준이라 부적합이에요.
'전체 동의'를 누르면 모든 약관에 자동 동의가 되고 약관 전문은 작은 회색 hyperlink로만 두는 구성은 위험해요. 사용자가 무엇에 동의했는지 모르고, 법적으로도 신뢰 측면에서도 문제가 됩니다.
선택 약관(마케팅 동의)은 처음에 체크되지 않은 상태로 보여 주는 게 기본이에요. 미리 체크해 두면 다크 패턴으로 분류되고, 분쟁이 생기면 법적으로 불리해집니다. '필수' 라벨은 빨강, '선택'은 회색이 일반적이에요. 약관별로 동의한 시점과 이력은 백엔드에 따로 남겨야 분쟁이 생겼을 때 증빙이 가능합니다.
각 체크박스에 명확한 label을 붙입니다. htmlFor 또는 wrapping으로 라벨 클릭만으로 토글이 가능하도록 만들어요. '전체 동의'는 aria-controls로 하위 ID 묶음을 가리키고, 일부만 체크된 indeterminate 상태도 시각과 aria 양쪽에서 함께 표현해야 합니다.