Playground로 바로 이동
Components

Checkbox

목록이나 폼에서 항목의 선택 여부를 제어합니다. Control은 16px 단일 크기이며 20px Label 첫 줄 안에서 중앙 정렬됩니다. 선택 상태는 Brand 표현을 사용합니다.

명세 문서 보기

🚩 Playground

현재 구현된 선택, 부분 선택과 비활성 상태를 조합해 확인합니다.

Appearance

Shape
Layout
Flipped

State

Disabled
Read only

Content

Checked
Indeterminate

Elements

Right description
Bottom description
Parent item

Anatomy

현재 Checkbox를 구성하는 실제 요소입니다.

  1. 1.Field
  2. 2.Checkbox control
  3. 3.Selection indicator
  4. 4.Label
  1. 5.Content container
  2. 6.Leading element(Optional)
  3. 7.Right Description(Optional)
  4. 8.Trailing element(Optional)
  5. 9.Bottom Description(Optional)

Structure map

Field
├─ Checkbox control
│  └─ Selection indicator
└─ Content container
   ├─ Leading element (Optional)
   ├─ Label
   ├─ Right Description (Optional)
   ├─ Trailing element (Optional)
   └─ Bottom Description (Optional)

Properties · Shape

Rounded를 기본값으로 사용하며, 박스 없이 Indicator만 표시하는 Ghost를 선택할 수 있습니다.

Square

Rounded

Ghost

Properties · Elements

Label 위계와 교체 가능한 Leading·Trailing element를 확인합니다.

Parent item

여러 하위 선택 항목을 대표하거나 전체 선택을 제어하는 부모 항목에만 Semibold Label을 사용합니다. 일반 항목의 Label은 Regular입니다.

Leading element

텍스트 Content 앞의 Swap 영역입니다. 아래 Remix 아이콘은 배치 가능한 콘텐츠 예시이며 고정 요소가 아닙니다.

Trailing element

텍스트 Content 뒤의 Swap 영역입니다. 아래 Badge는 배치 가능한 콘텐츠 예시이며 고정 요소가 아닙니다.

Properties · State

선택값은 고정하고 Focus와 Pressed 피드백은 실제로 확인합니다.

Rounded

4px radius를 사용하는 기본 Checkbox Appearance입니다. 선택·부분 선택·Focus와 Disabled 상태를 모두 제공합니다.

Unchecked

Checked

Indeterminate

Focus visible

Disabled · Unchecked

Disabled · Checked

Read only · Checked

Ghost

박스 없이 Check Indicator의 색상으로 선택 상태를 구분합니다. Ghost는 Indeterminate와 Disabled 상태를 제공하지 않습니다.

Unchecked

Checked

Focus visible

Layout

여러 Checkbox를 함께 사용할 때의 가로 줄바꿈과 세로 배열을 비교합니다.

Horizontal · Wrap

여러 항목을 가로로 나열하고 사용할 수 있는 너비가 부족하면 다음 줄로 이어집니다.

Vertical · Block

각 항목이 부모 너비를 채우며 36px 최소 행 높이로 이어집니다.

Guidelines

Checkbox를 구성하고 배치할 때 적용하는 기준입니다.

Target area 확보하기

16px Control

Row composition

  • 16px Indicator만 보이더라도 CheckboxField는 최소 36px 높이의 조작 영역을 확보합니다.
  • 목록이나 행과 결합하면 Indicator만이 아니라 Label을 포함한 전체 CheckboxField를 선택 영역으로 사용합니다.

부모–자식 선택 표현하기

Do

부모 항목은 위계를 구분하고 일부 선택을 Indeterminate로 표시합니다.

Don’t

부모 항목을 일반 항목과 같은 위계로 표현하지 않습니다.

  • 부모 항목의 Label에만 Semibold를 사용합니다.
  • 일부 하위 항목만 선택되면 부모 Indicator를 Indeterminate로 표시합니다.

Disabled 상태를 명확하게 표시하기

현재 선택할 수 없는 항목

Do

Indicator와 Label 전체에 Disabled 표현을 적용합니다.

Don’t

Indicator만 비활성화하고 Label은 활성 상태처럼 남기지 않습니다.

  • 사용할 수 없는 이유가 필요하면 Field의 설명이나 주변 안내로 제공합니다.
  • Disabled 상태에서도 기존 Checked 값은 보존합니다.

Checkbox 나열하기

  • 여러 Checkbox는 기본적으로 줄바꿈을 허용해 항목이 잘리지 않게 배치합니다.
  • 짧은 항목을 빠르게 비교하는 밀도 높은 관리자 화면에서는 16px 간격의 가로 배열을 권장합니다.
  • 세로 배열은 별도 간격 없이 CheckboxField의 36px 최소 높이로 수직 리듬을 확보합니다.

Checkbox Indicator 재사용하기

Indicator only · 36px target

콘텐츠 결합 예시

  • CheckboxIndicator는 Checkbox의 16px 시각 base이며 Checked, Indeterminate와 Disabled 표현을 공유합니다.
  • Combobox Option처럼 상위 컴포넌트가 선택 동작을 소유하면 상호작용 가능한 Checkbox 전체를 중첩하지 않고 Indicator만 사용합니다.
  • 값 변경, Focus와 키보드 동작은 Indicator를 사용하는 상위 컴포넌트가 담당합니다.

결과를 모아 제출할 때 사용하기

Do

나중에 저장하거나 제출하는 선택에는 Checkbox를 사용합니다.

Don’t

즉시 반영되지 않는 선택에 Switch를 사용하지 않습니다.

  • Checkbox는 여러 선택값을 모아 마지막 행동으로 확정하는 흐름에 적합합니다.
  • 누르는 즉시 설정이 바뀌어야 하는 경우에는 Switch를 사용합니다.

Property map

현재 구현된 Base UI Checkbox 속성과 ooee가 확정한 시각 범위입니다.

PropertyValuesDefault
checkedfalse | truefalse
defaultCheckedfalse | truefalse
indeterminatefalse | true (Rounded)false
disabledfalse | true (Rounded)false
shapesquare | rounded | ghost (Checkbox / Field)rounded
labelReactNode (Field)required
isParentfalse | truefalse
rightDescriptionReactNodeundefined
bottomDescriptionReactNodeundefined
leadingElementReactNodeundefined
trailingElementReactNodeundefined
layouthug | fill (Field only)hug
flippedfalse | truefalse
readOnlyfalse | truefalse
requiredfalse | truefalse
name / value / formstringundefined
onCheckedChange(checked: boolean) => voidundefined

명세 문서

docs/system/components/checkbox.md

Checkbox

packages/ui/src/checkbox.tsx

항목의 선택 여부를 표시하고 제어한다. 선택 표현은 Brand를 사용하고 상태는 oe semantic token 규칙을 따른다.

Anatomy

Basic anatomy

  1. Field: Control과 Content를 포함하는 전체 클릭 영역
  2. Checkbox control: 선택 상태, Border와 Focus를 표시하는 16px Checkbox 본체
  3. Selection indicator: Square와 Rounded의 Checked 상태에서는 Remix Check icon, Indeterminate에서는 Remix Minus icon을 표시한다. Ghost는 Check icon을 항상 표시하고 색상으로 선택 여부를 구분한다.
  4. Label: 선택 항목의 필수 텍스트

Extended anatomy

Basic 구조는 반복해 번호를 표시하지 않는다. 단일 Label과 범위가 겹쳐 보이는 Content container는 여러 텍스트 요소가 표시되는 Extended 예시에서 그룹 영역으로 설명한다.

  1. Content container: Label과 선택적 Description, Leading/Trailing element를 묶는 영역
  2. Leading element: Content 앞에 교체 가능한 선택적 Slot
  3. Right Description: Label 우측의 선택적 설명
  4. Trailing element: Content 뒤에 교체 가능한 선택적 Slot
  5. Bottom Description: Label 아래의 선택적 설명

원자적인 Checkbox는 Control만 제공한다. CheckboxField는 Label, 선택적 Description과 Leading/Trailing element를 결합한다.

CheckboxIndicator는 Checkbox의 16px 비상호작용 시각 base다. Checked, Indeterminate와 Disabled 표현을 소유하고 Checkbox가 이를 내부에서 사용한다. Combobox Option처럼 상위 컴포넌트가 이미 선택 동작을 소유하는 경우에는 상호작용 가능한 Checkbox를 중첩하지 않고 CheckboxIndicator만 재사용한다. 값 변경, Focus와 키보드 동작은 이를 사용하는 상위 컴포넌트가 담당한다.

Checkbox와 Label 전체를 카드형 Surface로 묶는 Container 변형은 제공하지 않는다. 짧은 항목을 밀도 있게 나열할 때는 CheckboxField를 사용하고, 설명이나 시각 정보가 포함된 선택지를 넓은 조작 영역에서 비교할 때는 Multiple selection의 SelectBox를 사용한다.

Properties

  • checked: boolean, 기본값 false
  • defaultChecked: boolean, 기본값 false
  • indeterminate: boolean, 기본값 false. Square와 Rounded에서 지원하며 Ghost에는 제공하지 않음
  • disabled: boolean, 기본값 false. Square와 Rounded에서 지원하며 Ghost에는 제공하지 않음
  • readOnly: boolean, 기본값 false
  • required: boolean, 기본값 false
  • name, value, form: native form 연결 값
  • onCheckedChange: 선택 값 변경 callback
  • shape: square | rounded | ghost, 기본값 rounded
  • isParent: boolean, 기본값 false. 하위 선택 항목을 대표하거나 전체 선택을 제어하는 부모 항목의 Label에만 Semibold 적용
  • rightDescription: ReactNode, Label 우측에 선택적으로 표시
  • bottomDescription: ReactNode, Label 아래에 선택적으로 표시
  • leadingElement: ReactNode, 텍스트 Content 앞에 표시하는 선택적 Slot
  • trailingElement: ReactNode, 텍스트 Content 뒤에 표시하는 선택적 Slot
  • layout: hug | fill, 기본값 hug. 값의 뜻은 interaction.md의 「공통 너비 Layout」이 소유한다
  • flipped: boolean, 기본값 false. false는 Control을 Label 왼쪽에, true는 오른쪽에 배치
  • checkboxClassName: Control에만 적용하는 class다. Field에는 className을 사용한다

Seed Checkbox의 Label과 Shape 구조를 참고해 OOEE 컴포넌트로 대응한다. Control은 16px다. Square Indicator는 0px radius, Rounded Indicator는 4px radius이며 둘 다 10px icon을 사용한다. 박스 없이 Indicator 자체로 구분하는 Ghost icon은 15px다. Ghost는 Default · Unchecked에서도 체크 아이콘을 oe-foreground-placeholder로 표시하고, Checked에서 Brand foreground로 강조한다. Focus ring을 소유하는 Control은 세 Shape 모두 4px radius를 유지하므로 Square에서도 Focus ring은 각지지 않는다. CheckboxField 행은 OOEE Regular form control과 같은 최소 36px다. Control은 Label의 20px 첫 줄 안에서 수직 중앙에 오도록 2px 보정한다. 기본 Label은 Regular이며 하위 항목을 대표하는 부모 항목만 Semibold다. Indeterminate와 Disabled 상태는 Square와 Rounded에 제공하고 Ghost에는 제공하지 않는다.

CheckboxField의 전체 조작 영역은 항상 투명하며 선택 여부와 관계없이 값 변경이 가능한 Field의 Hover에만 옅은 oe-interaction-hover-subtle을 사용한다. 선택 상태는 Indicator의 Brand 표현으로 전달하고 Disabled와 Read only Field는 Hover 반응을 제공하지 않는다.

Checkbox Group 위에 보이는 질문이나 제목은 Field의 전체 조작 영역이 아니라 실제 Checkbox Indicator의 왼쪽 시작점에 맞춘다. 화면 또는 Surface의 20px 바깥 여백과 제목 시작점은 그대로 유지하고, CheckboxField의 8px 내부 조작 여백은 Field를 왼쪽으로 8px 보정해 바깥 방향으로 확보한다.

이 보정은 Group만의 규칙이 아니다. CheckboxField가 Indicator의 왼쪽 시작점을 다른 요소와 맞춰야 하는 자리라면 단독으로 쓸 때도 같은 8px을 바깥으로 보정한다. Group의 제목이 그 사례 중 하나이고, 같은 폼 안에서 Input이나 Button과 왼쪽 끝을 맞추는 자리도 같다. 여백 자체를 없애지 않는다. 그 8px은 장식이 아니라 행의 조작 영역이므로, 지우면 한 화면의 정렬을 맞추려고 모든 화면에서 누를 수 있는 영역을 깎게 된다. 맞출 기준이 없는 자리에서는 보정하지 않는다.

hugfill은 모두 같은 flex layout을 유지한다. hugfit-content, fillwidth: 100%에 해당하며 전환 시 Checkbox와 Label의 시작 위치가 바뀌지 않는다. Right와 Bottom Description은 각각 독립적인 optional slot이며 동시에 사용할 수 있다. Label과 Right Description의 첫 행은 20px 고정 높이이며 Right Description은 한 줄로 표시하고 넘치면 줄임 처리한다. Bottom Description은 상단 행 아래에 배치하고 Leading element와 같은 왼쪽 시작점을 사용한다. Right Description 유무와 관계없이 Bottom Description의 시작 위치와 control 정렬은 바뀌지 않는다.

Leading과 Trailing element는 텍스트 Content의 앞뒤에 놓이는 교체 가능한 Slot이다. 두 Slot은 optional이며 제공되지 않으면 해당 영역을 렌더링하지 않는다.

Workbench는 Leading element와 Trailing element의 독립 카드를 제공한다. Leading에는 공용 oe-icon-small(16px)을 참조하는 Remix Icon, Trailing에는 공용 Badge를 넣고 두 카드 모두 실제 Label과 Bottom description을 함께 표시한다. 아이콘과 Badge는 Swap content에 들어갈 수 있는 구성 예시이며 고정 요소나 기본값이 아니다.

Trailing element가 있으면 Label 또는 Right description 뒤에 바로 이어서 배치하며 남은 가로 공간의 끝으로 밀지 않는다. Trailing element는 20px Label 첫 행 안에서 수직 중앙 정렬한다. Workbench의 Leading·Trailing 사례는 Label을 Medium으로 강조하며, 자동 분배 Label 바로 뒤에 Red tonal XSmall NEW Badge를 표시한다.

flipped=true이면 Control과 Content의 순서만 반전해 Control을 오른쪽에 둔다. Label, Right Description과 Bottom Description의 내부 정렬은 그대로 유지한다.

Right와 Bottom Description은 Label보다 낮은 위계인 oe-foreground-tertiary를 사용한다. 이 semantic token은 neutral-500에 연결된다.

State

  • Rounded: Unchecked, Checked, Indeterminate, Focus visible, Disabled · Unchecked, Disabled · Checked, Read only · Checked
  • Ghost: Unchecked, Checked, Focus visible. Indeterminate와 Disabled는 제공하지 않음

Square는 Rounded와 같은 상태 동작과 색상 규칙을 사용한다.

State coverage audit

  • Workbench에서 확인: Rounded의 Unchecked, Checked, Indeterminate, Focus visible, Disabled · Unchecked, Disabled · Checked
  • Workbench에서 확인: Ghost의 Unchecked, Checked, Focus visible. Ghost Indeterminate와 Disabled 조합은 없음
  • 실제 동작으로 지원하지만 별도 시각 차이가 없음: Required
  • Pressed: 현재 CheckboxField에는 크기 또는 위치가 변하는 Pressed motion을 적용하지 않는다. Control의 상태색과 Field의 Hover 등 기존 상호작용 피드백만 유지하며, 전체 축소 효과는 모바일 공통 Motion 체계를 정할 때 다른 조작 요소와 함께 다시 검수한다.
  • 현재 정의 없음: Loading
  • 확인 필요: Error/Invalid. Unchecked error의 Danger border와 Checked error의 Brand/Danger 우선순위가 정해지지 않아 임의 구현하지 않음
  • 확인 필요: Leading/Trailing element에 버튼과 같은 인터랙티브 요소를 허용할지 정해지지 않음. 현재는 ReactNode Slot만 제공하며 사용 정책을 임의로 확정하지 않음

Checked와 Indeterminate는 oe-brand-background-bold-primary fill과 oe-foreground-inverse Indicator를 사용한다. Unchecked는 oe-background-primaryoe-border-primary를 사용한다. Disabled는 선택값을 변경하지 않고 조작만 제한한다. 비활성 미선택은 oe-background-disabled를 사용하되 형태가 사라지지 않도록 oe-border-primary를 유지한다. 비활성 선택 및 부분 선택은 oe-background-disabled-selected Neutral fill과 흰색 Indicator를 유지해 선택 여부를 구분한다. Focus visible은 본체와 2px 간격을 둔 2px oe-focus-ring을 사용한다.

Guidelines

Checkbox 나열하기

여러 Checkbox는 기본적으로 줄바꿈을 허용해 사용할 수 있는 너비 안에서 항목이 잘리지 않게 배치한다. 짧은 항목을 빠르게 비교해야 하는 밀도 높은 관리자 화면에서는 가로 배열을 권장한다. 세로로 나열할 때는 별도 간격을 추가하지 않고 CheckboxField의 36px 최소 높이로 클릭 영역과 수직 리듬을 확보한다. 화면 크기에 따른 배열 방향의 자동 전환은 현재 정의하지 않는다.

Checkbox Indicator 재사용하기

상위 컴포넌트가 이미 선택 동작을 소유하는 경우 상호작용 가능한 Checkbox 전체를 중첩하지 않고 CheckboxIndicator만 사용한다. Indicator는 선택 상태를 시각적으로 표시하며 값 변경, Focus와 키보드 동작은 이를 사용하는 상위 컴포넌트가 담당한다.

Behavior

Base UI Checkbox를 구현 기반으로 사용한다. Controlled와 uncontrolled 값을 지원하며 hidden input으로 native form 제출에 참여한다. CheckboxField의 보이는 Label은 aria-labelledby로 Control의 접근 가능한 이름에 연결한다. Label 없이 원자적인 Checkbox만 사용할 때는 소비자가 aria-label 또는 aria-labelledby를 제공해야 한다. disabled가 변경되어도 기존 checked 또는 indeterminate 값은 보존한다. indeterminate는 Square와 Rounded에서 전체 선택 여부가 혼합된 상태를 표시하며 Ghost에서는 적용하지 않는다.

Checked와 Indeterminate 값을 고정해 비교하는 경우에도 Pointer, Focus visible과 키보드 피드백은 차단하지 않는다. Disabled만 실제 조작 불가 상태를 유지한다.

Specification

  • Control: 16 × 16px
  • Indicator: Square·Rounded 10 × 10px / Ghost 15 × 15px
  • Label: 14px / 20px
  • CheckboxField minimum height: 36px (oe-control-regular)
  • Radius: 현재 구현값 4px
  • Label weight: Regular 400 / Parent item Semibold 600
  • Shape: Square / Rounded / Ghost