# Select Box URL: /react/components/select-box Source: https://github.com/daangn/seed-design/blob/dev/docs/content/react/components/select-box.mdx 명확한 테두리를 가진 컨테이너를 활용하여, 정의된 목록 중 하나 이상의 옵션을 선택하는 UI 요소입니다. 사용 가능 버전: @seed-design/react@0.0.1, @seed-design/css@0.0.1 ## Preview ```tsx import { HStack } from "@seed-design/react"; import { CheckSelectBox, CheckSelectBoxCheckmark, CheckSelectBoxGroup, RadioSelectBoxItem, RadioSelectBoxRadiomark, RadioSelectBoxRoot, } from "seed-design/ui/select-box"; export default function SelectBoxPreview() { return ( } /> } /> } /> } /> } /> } /> ); } ``` ## Installation - npm: npx @seed-design/cli@latest add ui:select-box - pnpm: pnpm dlx @seed-design/cli@latest add ui:select-box - yarn: yarn dlx @seed-design/cli@latest add ui:select-box - bun: bun x @seed-design/cli@latest add ui:select-box ## Props ### Check Select Box #### `CheckSelectBoxGroup` #### `CheckSelectBox` #### `CheckSelectBoxCheckmark` ### Radio Select Box #### `RadioSelectBoxRoot` #### `RadioSelectBoxItem` #### `RadioSelectBoxRadiomark` ## Examples ### React Hook Form ```tsx import { HStack, VStack } from "@seed-design/react"; import { useCallback, type FormEvent } from "react"; import { useController, useForm, type Control } from "react-hook-form"; import { ActionButton } from "seed-design/ui/action-button"; import { CheckSelectBox, CheckSelectBoxCheckmark, CheckSelectBoxGroup, RadioSelectBoxItem, RadioSelectBoxRadiomark, RadioSelectBoxRoot, } from "seed-design/ui/select-box"; const POSSIBLE_FRUIT_VALUES = ["apple", "melon", "mango"] as const; type CheckFormValues = Record<(typeof POSSIBLE_FRUIT_VALUES)[number], boolean>; interface RadioFormValues { fruit: (typeof POSSIBLE_FRUIT_VALUES)[number]; } export default function SelectBoxReactHookForm() { // CheckSelectBox Form const checkForm = useForm({ defaultValues: { apple: false, melon: true, mango: false }, }); // RadioSelectBox Form const radioForm = useForm({ defaultValues: { fruit: "melon" }, }); const { field: radioField } = useController({ name: "fruit", control: radioForm.control }); const onCheckValid = useCallback((data: CheckFormValues) => { window.alert(`CheckSelectBox:\n${JSON.stringify(data, null, 2)}`); }, []); const onRadioValid = useCallback((data: RadioFormValues) => { window.alert(`RadioSelectBox:\n${JSON.stringify(data, null, 2)}`); }, []); const onCheckReset = useCallback( (event: FormEvent) => { event.preventDefault(); checkForm.reset(); }, [checkForm], ); const onRadioReset = useCallback( (event: FormEvent) => { event.preventDefault(); radioForm.reset(); }, [radioForm], ); return ( {POSSIBLE_FRUIT_VALUES.map((name) => ( ))} 초기화 제출 {POSSIBLE_FRUIT_VALUES.map((value) => ( } /> ))} 초기화 제출 ); } interface CheckSelectBoxItemProps { name: keyof CheckFormValues; control: Control; } function CheckSelectBoxItem({ name, control }: CheckSelectBoxItemProps) { const { field: { value, ...restProps }, fieldState: { invalid }, } = useController({ name, control }); return ( } /> ); } ``` ### Customizing Label ```tsx import { Badge, HStack } from "@seed-design/react"; import { CheckSelectBox, CheckSelectBoxCheckmark, CheckSelectBoxGroup, RadioSelectBoxItem, RadioSelectBoxRadiomark, RadioSelectBoxRoot, } from "seed-design/ui/select-box"; export default function SelectBoxCustomizingLabel() { return ( } /> Melon New } description="Elit cupidatat dolore fugiat enim veniam culpa." suffix={} /> } /> } /> Melon New } description="Elit cupidatat dolore fugiat enim veniam culpa." suffix={} /> } /> ); } ``` ### Listening to Value Changes `CheckSelectBox`는 `onCheckedChange`를 사용하여 체크박스의 선택 상태 변경을 감지할 수 있습니다. `RadioSelectBoxRoot`는 `onValueChange`를 사용하여 라디오 버튼의 선택 값 변경을 감지할 수 있습니다. ```tsx import { HStack, Text, VStack } from "@seed-design/react"; import { CheckSelectBox, CheckSelectBoxCheckmark, CheckSelectBoxGroup, RadioSelectBoxItem, RadioSelectBoxRadiomark, RadioSelectBoxRoot, } from "seed-design/ui/select-box"; import { useState } from "react"; export default function SelectBoxValueChanges() { const [checkCount, setCheckCount] = useState(0); const [checkLastValue, setCheckLastValue] = useState(null); const [radioCount, setRadioCount] = useState(0); const [radioLastValue, setRadioLastValue] = useState(null); return ( } onCheckedChange={(checked) => { setCheckCount((prev) => prev + 1); setCheckLastValue(checked); }} /> onCheckedChange called: {checkCount} times, last value: {`${checkLastValue ?? "-"}`} { setRadioCount((prev) => prev + 1); setRadioLastValue(value); }} > } /> } /> onValueChange called: {radioCount} times, last value: {radioLastValue ?? "-"} ); } ``` ### Grid Layout (Columns) `columns` prop을 사용하여 여러 열로 배치할 수 있습니다. `columns`가 1보다 크면 하위 요소의 `layout`이 자동으로 `"vertical"`로 설정됩니다. 필요한 경우 `layout` prop을 직접 설정하여 개별 항목의 레이아웃을 오버라이드할 수 있습니다. ```tsx import { IconDiamond, IconIcecreamcone } from "@karrotmarket/react-multicolor-icon"; import { VStack } from "@seed-design/react"; import { CheckSelectBox, CheckSelectBoxCheckmark, CheckSelectBoxGroup, RadioSelectBoxItem, RadioSelectBoxRadiomark, RadioSelectBoxRoot, } from "seed-design/ui/select-box"; export default function SelectBoxColumns() { return ( } label="옵션 1" description="layout=vertical" suffix={} /> } label="옵션 2" description="layout=vertical" suffix={} /> } defaultChecked layout="horizontal" label="layout=horizontal" description="layout을 horizontal로 오버라이드" suffix={} /> } label="옵션 4" description="layout=vertical" suffix={} /> } label="옵션 1" suffix={} /> } label="옵션 2" suffix={} /> } label="layout=horizontal" description="layout을 horizontal로 오버라이드" layout="horizontal" suffix={} /> } label="옵션 4" suffix={} /> } label="옵션 5" suffix={} /> } label="옵션 6" suffix={} /> ); } ``` ### With Suffix `suffix` prop을 사용하여 체크마크, 라디오 마크, 또는 커스텀 요소를 표시할 수 있습니다. `CheckSelectBoxCheckmark`와 `RadioSelectBoxRadiomark`를 사용하거나, 아이콘이나 텍스트 등 자유로운 요소를 전달할 수 있습니다. ```tsx import { IconPersonCircleLine } from "@karrotmarket/react-monochrome-icon"; import { Text, HStack, Box } from "@seed-design/react"; import { CheckSelectBox, CheckSelectBoxCheckmark, CheckSelectBoxGroup, RadioSelectBoxItem, RadioSelectBoxRadiomark, RadioSelectBoxRoot, } from "seed-design/ui/select-box"; export default function SelectBoxWithSuffix() { return ( } /> +1,000원 } /> } /> } /> +1,000원 } /> } /> ); } ``` ### Collapsible Footer `footer` prop으로 추가 콘텐츠를 표시할 수 있습니다. `footerVisibility` prop으로 footer의 표시 조건을 제어할 수 있습니다. - `"when-selected"` (기본값): 항목이 선택되었을 때만 표시 - `"when-not-selected"`: 항목이 선택되지 않았을 때만 표시 - `"always"`: 항상 표시 ```tsx import { Box, HStack, Text } from "@seed-design/react"; import { CheckSelectBox, CheckSelectBoxCheckmark, CheckSelectBoxGroup, RadioSelectBoxItem, RadioSelectBoxRadiomark, RadioSelectBoxRoot, } from "seed-design/ui/select-box"; export default function SelectBoxCollapsibleFooter() { return ( } footer={ 선택되었을 때만 보입니다. } /> } footerVisibility="always" footer={ 항상 보입니다. } /> } footerVisibility="when-not-selected" footer={ 선택되지 않았을 때만 보입니다. } /> } footer={ 선택되었을 때만 보입니다. } /> } footerVisibility="always" footer={ 항상 보입니다. } /> } footerVisibility="when-not-selected" footer={ 선택되지 않았을 때만 보입니다. } /> ); } ``` ### Fieldset/RadioGroupField Integration Fieldset/RadioGroupField 관련 prop을 사용할 수 있습니다. - `label` 및 `labelWeight` - `indicator` 및 `showRequiredIndicator` - `description` 및 `errorMessage` - `disabled`, `invalid`, `name`, `form`: `RadioSelectBoxRoot`에만 지원됩니다. ```tsx import { ActionButton, HStack, VStack, Box, Text } from "@seed-design/react"; import { useState } from "react"; import { CheckSelectBox, CheckSelectBoxCheckmark, CheckSelectBoxGroup, RadioSelectBoxItem, RadioSelectBoxRadiomark, RadioSelectBoxRoot, } from "seed-design/ui/select-box"; export default function SelectBoxFieldset() { const [checkErrors, setCheckErrors] = useState>({}); const [radioErrorMessage, setRadioErrorMessage] = useState(); const handleCheckSubmit = (e: React.FormEvent) => { e.preventDefault(); const formData = new FormData(e.currentTarget); const fruits = formData.getAll("fruit"); if (fruits.includes("apple")) { setCheckErrors({ apple: "Apple은 선택할 수 없습니다." }); return; } setCheckErrors({}); alert(JSON.stringify(fruits, null, 2)); }; const handleRadioSubmit = (e: React.FormEvent) => { e.preventDefault(); const formData = new FormData(e.currentTarget); const color = formData.get("color"); if (color === "red") { setRadioErrorMessage("Red는 선택할 수 없습니다."); return; } setRadioErrorMessage(undefined); alert(JSON.stringify({ color }, null, 2)); }; return (
} footer={ Apple을 선택하고 제출하면 에러 메시지가 표시됩니다. } /> } /> } /> 제출
} footer={ Red를 선택하고 제출하면 에러 메시지가 표시됩니다. } /> } disabled /> } /> 제출
); } ```