# 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 (
);
}
```