사용자가 여러 옵션 중 하나 이상을 선택할 수 있게 하는 체크박스 컴포넌트입니다.
npx @seed-design/cli add ui:checkbox pnpm dlx @seed-design/cli add ui:checkbox yarn dlx @seed-design/cli add ui:checkbox bun x @seed-design/cli add ui:checkbox
의존성 설치
npm install @karrotmarket/lynx-monochrome-icon @seed-design/lynx-react yarn add @karrotmarket/lynx-monochrome-icon @seed-design/lynx-react pnpm add @karrotmarket/lynx-monochrome-icon @seed-design/lynx-react bun add @karrotmarket/lynx-monochrome-icon @seed-design/lynx-react 아래 코드를 복사 후 붙여넣고 사용하세요 /**
* @file ui:checkbox
* @requires @seed-design/lynx-react@>=0.1.0 <1.0.0
* @requires @seed-design/lynx-css@>=0.1.0 <1.0.0
**/
import * as React from "@lynx-js/react" ;
import IconCheckmarkFatFill from "@karrotmarket/lynx-monochrome-icon/IconCheckmarkFatFill" ;
import IconMinusFatFill from "@karrotmarket/lynx-monochrome-icon/IconMinusFatFill" ;
import { Checkbox as SeedCheckbox } from "@seed-design/lynx-react" ;
export interface CheckboxProps extends SeedCheckbox . RootProps {
label ?: React . ReactNode ;
}
/**
* @see https://seed-design.io/lynx/components/checkbox
*/
export const Checkbox = React. forwardRef < unknown , CheckboxProps >(
({ label , children , ... otherProps }, ref ) => {
return (
< SeedCheckbox.Root ref = {ref} { ... otherProps}>
< SeedCheckbox.Control >
< SeedCheckbox.Indicator
unchecked = {otherProps.variant === "ghost" ? < IconCheckmarkFatFill /> : undefined }
checked = {< IconCheckmarkFatFill />}
indeterminate = {< IconMinusFatFill />}
/>
</ SeedCheckbox.Control >
{label != null ? < SeedCheckbox.Label >{label}</ SeedCheckbox.Label > : null }
{children}
</ SeedCheckbox.Root >
);
},
);
Checkbox.displayName = "Checkbox" ;
export interface CheckmarkProps extends Omit < SeedCheckbox . RootProps , "children" > {}
/**
* @see https://seed-design.io/lynx/components/checkbox
*/
export const Checkmark = React. forwardRef < unknown , CheckmarkProps >(( props , ref ) => {
return (
< SeedCheckbox.Root ref = {ref} { ... props}>
< SeedCheckbox.Control >
< SeedCheckbox.Indicator
unchecked = {props.variant === "ghost" ? < IconCheckmarkFatFill /> : undefined }
checked = {< IconCheckmarkFatFill />}
indeterminate = {< IconMinusFatFill />}
/>
</ SeedCheckbox.Control >
</ SeedCheckbox.Root >
);
});
Checkmark.displayName = "Checkmark" ;
export const CheckboxGroup = SeedCheckbox.Group;
export type CheckboxGroupProps = SeedCheckbox . GroupProps ;
/**
* This file is a snippet from SEED Design, helping you get started quickly with @seed-design/* packages.
* You can extend this snippet however you want.
*/
설치한 snippet은 compound 구성 요소와 Lynx 아이콘을 한데 묶은 Checkbox, 본체만 필요할 때 쓰는 Checkmark, 여러 항목을 세로로 묶는 CheckboxGroup을 함께 export 합니다.
import { Checkbox } from "@/components/ui/checkbox" ;
export function App () {
return < Checkbox label = "알림 받기" defaultChecked />;
}
Controlled 모드는 checked와 onCheckedChange를 함께 전달합니다.
import { useState } from "@lynx-js/react" ;
import { Checkbox } from "@/components/ui/checkbox" ;
export function ControlledCheckbox () {
const [ checked , setChecked ] = useState ( false );
return (
< Checkbox
label = {checked ? "선택됨" : "선택 안 됨" }
checked = {checked}
onCheckedChange = {setChecked}
/>
);
}
일부 항목만 선택된 상태를 표현할 때 indeterminate prop을 사용합니다. Indeterminate 상태에서 tap하면 checked 값만 토글되며, indeterminate 값은 소비자가 직접 해제해야 합니다.
import { useState } from "@lynx-js/react" ;
import { Checkbox } from "@/components/ui/checkbox" ;
export function SelectAllCheckbox () {
const [ checked , setChecked ] = useState ( false );
const [ indeterminate , setIndeterminate ] = useState ( true );
return (
< Checkbox
label = "전체 선택"
checked = {checked}
indeterminate = {indeterminate}
onCheckedChange = {( nextChecked ) => {
setChecked (nextChecked);
setIndeterminate ( false );
}}
/>
);
}
여러 Checkbox를 수직 간격과 함께 묶을 때 CheckboxGroup을 사용합니다. 자식 Checkbox 사이의 상태 공유는 하지 않고 레이아웃만 제공합니다.
import { Checkbox, CheckboxGroup } from "@/components/ui/checkbox" ;
export function NotificationSettings () {
return (
< CheckboxGroup >
< Checkbox label = "채팅 알림" defaultChecked />
< Checkbox label = "관심 키워드 알림" />
< Checkbox label = "마케팅 정보 수신" />
</ CheckboxGroup >
);
}
Label 없이 본체만 쓰고 싶다면 Checkmark를 사용합니다.
import { Checkmark } from "@/components/ui/checkbox" ;
export function App () {
return < Checkmark variant = "ghost" tone = "brand" defaultChecked />;
}
Checkbox와 Checkmark는 snippet API에서 tone, variant를 그대로 전달받습니다.
import { Checkbox, Checkmark } from "@/components/ui/checkbox" ;
export function CheckboxVariants () {
return (
<>
< Checkbox label = "브랜드 체크박스" tone = "brand" defaultChecked />
< Checkmark variant = "ghost" tone = "brand" defaultChecked />
</>
);
}
label?React.ReactNode
checked?boolean | undefined
defaultChecked?boolean | undefined
indeterminate?boolean | undefined
onCheckedChange?(( checked : boolean ) => void ) | undefined
style?CSSProperties | undefined
children?React.ReactNode
className?string | undefined
checked?boolean | undefined
indeterminate?boolean | undefined
className?string | undefined
defaultChecked?boolean | undefined
onCheckedChange?(( checked : boolean ) => void ) | undefined
style?CSSProperties | undefined
style?CSSProperties | undefined
children?React.ReactNode
className?string | undefined
Lynx Checkbox는 React Checkbox와 다음과 같은 차이가 있습니다.
아이콘 주입 방식 : snippet의 Checkbox와 Checkmark는 @karrotmarket/lynx-monochrome-icon의 check / minus icon을 자동으로 주입합니다. compound component를 직접 조합할 때는 Checkbox.Indicator에 Lynx monochrome icon을 전달해야 합니다. raw <svg> 주입은 Lynx 범위 밖입니다.
이벤트 핸들링 : onChange 대신 onCheckedChange만 노출합니다. tap 핸들러는 Root 내부에서 소유합니다.
Pressed 상태 : 웹의 data-active 대신 내부 press state를 checkmark recipe의 pressed boolean variant로 전달합니다.
렌더링 요소 : HTML <label> / <input> 대신 네이티브 <view> / <text> 요소를 렌더링합니다.
Compound 구조 : Checkbox.Root → Checkbox.Control → Checkbox.Indicator + Checkbox.Label 구성과 Context로 상태/variant를 공유하는 흐름은 동일합니다.
ref forwarding : Checkbox, Checkmark, CheckboxGroup은 Root view로 ref를 전달합니다. 웹 snippet처럼 hidden input ref를 제공하지 않습니다.
현재 Lynx 플랫폼 제약으로 다음 기능이 지원되지 않습니다.
기능 웹 대응 설명 CheckboxHiddenInput<input type="checkbox">Lynx에 HTML form 제출 모델 없음 inputPropshidden input props Lynx snippet은 hidden input을 렌더링하지 않음 name / value / required / invalidform field props Lynx에 native form 제출 모델 없음 focus / focusVisible키보드 포커스 Lynx에 키보드 포커스 개념 없음 onChange (raw DOM event)React.ChangeEvent의미 없음. onCheckedChange로 대체 weight="default" / "stronger"deprecated 호환 매핑 Lynx 신규 컴포넌트이므로 처음부터 "regular" / "bold" 만 노출