SEED Design

Radio Group

Radio Group 컴포넌트는 사용자가 여러 옵션 중 하나를 선택할 수 있도록 합니다.

import { VStack } from "@seed-design/react";
import { RadioGroup, RadioGroupItem } from "seed-design/ui/radio-group";

export default function RadioGroupPreview() {
  return (
    <RadioGroup defaultValue="apple" aria-label="Fruit selection">
      <VStack>
        <RadioGroupItem value="apple" label="Apple" />
        <RadioGroupItem value="banana" label="Banana" />
        <RadioGroupItem value="orange" label="Orange" />
      </VStack>
    </RadioGroup>
  );
}

Installation

npx @seed-design/cli@latest add radio-group

Props

RadioGroup

PropTypeDefault
disabled?
boolean
-
name?
string
-
form?
string
-
value?
string
-
defaultValue?
string
-
onValueChange?
((value: string) => void)
-
asChild?
boolean
false

RadioGroupItem

PropTypeDefault
label?
ReactNode
-
inputProps?
InputHTMLAttributes<HTMLInputElement>
-
rootRef?
Ref<HTMLLabelElement>
-
weight?
"default" | "stronger"
"default"
size?
"large" | "medium"
"medium"
value?
string
-
disabled?
boolean
-
invalid?
boolean
-
asChild?
boolean
false

RadioMark

PropTypeDefault
size?
"large" | "medium"
"medium"
asChild?
boolean
false

Examples

Size

"use client";

import { RadioGroup, RadioGroupItem } from "../../registry/ui/radio-group";
import { VStack, Text, HStack } from "@seed-design/react";
import { useState } from "react";

export default function RadioGroupSize() {
  const [mediumValue, setMediumValue] = useState("apple");
  const [largeValue, setLargeValue] = useState("red");

  return (
    <VStack gap="x5">
      <VStack gap="x3">
        <Text as="h3" color="fg.neutral" fontSize="t4" fontWeight="bold">
          Medium (기본값)
        </Text>
        <RadioGroup
          value={mediumValue}
          onValueChange={setMediumValue}
          aria-label="과일 선택 (중간 크기)"
        >
          <HStack gap="x3">
            <RadioGroupItem value="apple" label="사과" size="medium" />
            <RadioGroupItem value="banana" label="바나나" size="medium" />
            <RadioGroupItem value="orange" label="오렌지" size="medium" />
          </HStack>
        </RadioGroup>
      </VStack>

      <VStack gap="x3">
        <Text as="h3" color="fg.neutral" fontSize="t4" fontWeight="bold">
          Large
        </Text>
        <RadioGroup
          value={largeValue}
          onValueChange={setLargeValue}
          aria-label="색상 선택 (큰 크기)"
        >
          <HStack gap="x3">
            <RadioGroupItem value="red" label="빨간색" size="large" />
            <RadioGroupItem value="blue" label="파란색" size="large" />
            <RadioGroupItem value="green" label="초록색" size="large" />
          </HStack>
        </RadioGroup>
      </VStack>
    </VStack>
  );
}

Disabled

import { VStack } from "@seed-design/react";
import { RadioGroup, RadioGroupItem } from "seed-design/ui/radio-group";

export default function RadioGroupDisabled() {
  return (
    <RadioGroup defaultValue="option1" aria-label="Options with disabled">
      <VStack>
        <RadioGroupItem value="option1" label="Active option" />
        <RadioGroupItem value="option2" label="Disabled option" disabled />
        <RadioGroupItem value="option3" label="Another active option" />
      </VStack>
    </RadioGroup>
  );
}

Use Cases

React Hook Form

import { HStack, VStack } from "@seed-design/react";
import { useCallback, type FormEvent } from "react";
import { useController, useForm } from "react-hook-form";
import { ActionButton } from "seed-design/ui/action-button";
import { RadioGroup, RadioGroupItem } from "seed-design/ui/radio-group";

const POSSIBLE_COLORS = ["red", "blue", "green"] as const;

interface FormValues {
  color: (typeof POSSIBLE_COLORS)[number];
}

export default function RadioGroupReactHookForm() {
  const { handleSubmit, reset, setValue, control } = useForm<FormValues>({
    defaultValues: {
      color: "blue",
    },
  });
  const { field } = useController({ name: "color", control });

  const onValid = useCallback((data: FormValues) => {
    window.alert(JSON.stringify(data, null, 2));
  }, []);

  const onReset = useCallback(
    (event: FormEvent) => {
      event.preventDefault();
      reset();
    },
    [reset],
  );

  return (
    <form onSubmit={handleSubmit(onValid)}>
      <VStack gap="x3">
        <RadioGroup
          value={field.value}
          onValueChange={(value) => setValue("color", value as FormValues["color"])}
          aria-label="Color selection"
        >
          <VStack>
            {POSSIBLE_COLORS.map((color) => (
              <RadioGroupItem
                key={color}
                value={color}
                label={color.charAt(0).toUpperCase() + color.slice(1)}
              />
            ))}
          </VStack>
        </RadioGroup>

        <HStack gap="x3">
          <ActionButton type="submit">Submit</ActionButton>
          <ActionButton variant="neutralWeak" onClick={onReset}>
            Reset
          </ActionButton>
        </HStack>
      </VStack>
    </form>
  );
}

RadioGroupItem의 레이아웃

RadioGroup은 여러 옵션 중 하나만 선택할 수 있는 컴포넌트입니다. 각 옵션은 RadioGroupItem으로 구성됩니다.

RadioGroup은 기본적으로 레이아웃을 제공하지 않습니다. HStack 또는 VStack과 같은 레이아웃 컴포넌트와 함께 사용해야 합니다.

import { RadioGroup, RadioGroupItem } from "seed-design/ui/radio-group";

function HorizontalRadioGroup() {
  const [value, setValue] = useState("option1");

  return (
    <RadioGroup value={value} onValueChange={setValue} aria-label="Options">
      <HStack gap="x3">
        <RadioGroupItem value="option1" label="첫 번째 옵션" />
        <RadioGroupItem value="option2" label="두 번째 옵션" />
        <RadioGroupItem value="option3" label="세 번째 옵션" />
      </HStack>
    </RadioGroup>
  );
}

function VerticalRadioGroup() {
  const [value, setValue] = useState("option1");

  return (
    <RadioGroup value={value} onValueChange={setValue} aria-label="Options">
      <VStack>
        <RadioGroupItem value="option1" label="첫 번째 옵션" />
        <RadioGroupItem value="option2" label="두 번째 옵션" />
        <RadioGroupItem value="option3" label="세 번째 옵션" />
      </VStack>
    </RadioGroup>
  );
}

RadioMark 활용하기

RadioMark는 독립적인 라디오 마크 컴포넌트로, 커스텀 레이아웃을 위해 사용할 수 있습니다.

import { HStack, Text, VStack } from "@seed-design/react";
import { RadioMark } from "seed-design/ui/radio-group";
import { RadioGroup } from "@seed-design/react";

function CustomRadioGroupItem({ children, ...props }: RadioGroup.ItemProps) {
  return (
    <RadioGroup.Item {...props}>
      <VStack gap="x2" align="center">
        <RadioMark />
        <RadioGroup.ItemHiddenInput />
        {children}
      </VStack>
    </RadioGroup.Item>
  );
}

export default function RadioGroupRadioMark() {
  return (
    <RadioGroup.Root defaultValue="medium" aria-label="Weight selection">
      <HStack gap="x6">
        <CustomRadioGroupItem value="regular">
          <Text textStyle="t7Regular">regular</Text>
        </CustomRadioGroupItem>
        <CustomRadioGroupItem value="medium">
          <Text textStyle="t7Medium">medium</Text>
        </CustomRadioGroupItem>
        <CustomRadioGroupItem value="bold">
          <Text textStyle="t7Bold">bold</Text>
        </CustomRadioGroupItem>
      </HStack>
    </RadioGroup.Root>
  );
}

Last updated on