Radio

서로 배타적인 항목 중 하나를 선택합니다.

Live preview
컴포넌트를 조작하면 여기에 결과가 표시됩니다.
코드 보기
HTML
<sy-radio-group
  defaultvalue="monthly"
  position="horizontal"
  size="medium"
  variant="outlined"
  name="billing"
  id="sample"
>
  <sy-radio value="monthly">월간</sy-radio>
  <sy-radio value="yearly">연간</sy-radio>
</sy-radio-group>

사용 가이드

#

서로 배타적인 항목 중 하나만 선택하게 합니다. sy-radio-group 안에 항목을 배치하고 각 항목에 고유한 value를 지정하세요.

  1. 오류 문구는 error 슬롯에 작성합니다.

    컴포넌트 안에 <span slot="error">오류 메시지</span>을 넣으세요. 글자뿐 아니라 링크 등 필요한 안내도 넣을 수 있습니다. noNativeValidity를 지원하는 입력은 이를 켜면 브라우저 팝업 대신 이 안내를 표시합니다. Switch는 항상 컴포넌트 아래에 오류를 표시합니다.

  2. 업무 규칙의 실패는 setCustomError()로 알립니다.

    예를 들어 서버가 중복된 값을 거절하면 error 슬롯의 문구를 바꾸고 setCustomError()를 호출하세요. 이 메서드에는 메시지 인자를 전달하지 않습니다. 사용자 지정 오류가 있으면 폼 제출도 차단됩니다.

  3. 해결 후 해제하고 제출 가능 여부를 확인합니다.

    clearCustomError()로 업무 규칙 오류를 해제하세요. required나 입력 형식 검사까지 해제되지는 않습니다. await checkValidity()는 true/false를, reportValidity()는 검사 결과와 오류 표시를 함께 제공합니다. name을 지정한 유효한 값은 제출 시 FormData로 읽습니다.

일반 선택 목록

설명을 읽고 값을 고르는 폼에는 기본 Radio를 사용하세요.

버튼형 선택

기간·보기 방식처럼 짧은 선택지는 sy-radio-button으로 보여줄 수 있습니다. 그룹의 방향·크기·스타일을 함께 조절하세요.

예제

#

하나만 선택

같은 그룹 안에서는 한 항목만 선택됩니다.

코드 보기
HTML
<sy-radio-group defaultvalue="email" name="contact">
  <sy-radio value="email">이메일</sy-radio>
  <sy-radio value="sms">문자</sy-radio>
  <sy-radio value="push">푸시 알림</sy-radio>
</sy-radio-group>

버튼형 선택

같은 단일 선택을 도구 모음처럼 표현합니다.

코드 보기
HTML
<sy-radio-group defaultvalue="week" variant="solid">
  <sy-radio-button value="day">일</sy-radio-button>
  <sy-radio-button value="week">주</sy-radio-button>
  <sy-radio-button value="month">월</sy-radio-button>
</sy-radio-group>

세로와 개별 비활성화

항목 설명이 길거나 선택지가 많으면 세로로 배치합니다.

코드 보기
HTML
<sy-radio-group position="vertical" defaultvalue="standard">
  <sy-radio value="standard">일반 배송</sy-radio>
  <sy-radio value="express">빠른 배송</sy-radio>
  <sy-radio value="pickup" disabled>방문 수령 준비 중</sy-radio>
</sy-radio-group>

이벤트와 전달 값

컴포넌트를 조작하고 최근 이벤트의 이름과 detail 값을 확인하세요. 코드에는 이 컴포넌트와 하위 구성 요소가 보내는 이벤트의 구독 방법이 모두 포함되어 있습니다.

코드 보기
HTML
<sy-radio-group
  defaultvalue="monthly"
  position="horizontal"
  size="medium"
  variant="outlined"
  name="billing"
  id="sample"
>
  <sy-radio value="monthly">월간</sy-radio>
  <sy-radio value="yearly">연간</sy-radio>
</sy-radio-group>
<output id="demo-events" aria-live="polite">컴포넌트를 조작하면 최근 이벤트와 전달 값이 표시됩니다.
</output>

<script type="module">
  const describeResult = value => JSON.stringify(value, (_key, item) => {
    if (item instanceof File) return {
      name: item.name,
      size: item.size,
      type: item.type
    };
    if (item instanceof Element) return `<${item.localName}>`;
    return item;
  }) ?? '완료';
  for (const name of ["changed", "selected"]) {
    document.addEventListener(name, event => {
      document.querySelector('#demo-events').textContent =
        `${event.target.localName} · ${name}: ${describeResult(event.detail)}`;
    });
  }
</script>

채워진 버튼 선택

연간 결제 옵션의 선택 상태를 채워진 라디오 버튼으로 표시합니다.

코드 보기
HTML
<sy-radio-group
  defaultvalue="yearly"
  position="horizontal"
  size="medium"
  variant="solid"
  name="billing"
  id="sample"
>
  <sy-radio-button value="monthly">월간</sy-radio-button>
  <sy-radio-button value="yearly">연간</sy-radio-button>
</sy-radio-group>

<script type="module">
  const component1 = document.querySelector("#sample");
  Object.assign(component1, {
    "variant": "solid",
    "defaultValue": "yearly"
  });
</script>

폼과 유효성 검사

값을 비운 채 제출하면 필수 입력 검사가 동작합니다. 값을 입력한 뒤 제출해 폼 데이터를 확인하고, 사용자 지정 오류도 켜고 꺼보세요.

코드 보기
HTML
<form style="display:grid;gap:16px">
  <sy-radio-group
    name="field"
    required
    id="sample"
  >
    <sy-radio value="yes">동의</sy-radio>
    <sy-radio value="no">동의하지 않음</sy-radio><span slot="error">하나를 선택하세요.</span>
  </sy-radio-group>
  <div style="display:flex;flex-wrap:wrap;gap:8px">
    <sy-button type="submit" variant="primary">제출</sy-button>
    <sy-button type="reset">초기화</sy-button>
  </div>
</form>
<div class="demo-actions"
  style="display:flex;flex-wrap:wrap;gap:8px;margin-top:16px"
>
  <sy-button id="action-0" size="small">유효성 확인</sy-button>
  <sy-button id="action-1" size="small">오류 표시</sy-button>
  <sy-button id="action-2" size="small">오류 해제</sy-button>
</div>
<output id="demo-result" aria-live="polite"></output>

<script type="module">
  const describeResult = value => JSON.stringify(value, (_key, item) => {
    if (item instanceof File) return {
      name: item.name,
      size: item.size,
      type: item.type
    };
    if (item instanceof Element) return `<${item.localName}>`;
    return item;
  }) ?? '완료';
  const actionTarget0 = document.querySelector("#sample");
  document.querySelector('#action-0').addEventListener('click', async () => {
    const result = await actionTarget0.checkValidity();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget1 = document.querySelector("#sample");
  document.querySelector('#action-1').addEventListener('click', async () => {
    const result = await actionTarget1.setCustomError();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget2 = document.querySelector("#sample");
  document.querySelector('#action-2').addEventListener('click', async () => {
    const result = await actionTarget2.clearCustomError();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  document.querySelector('form').addEventListener('submit', event => {
    event.preventDefault();
    document.querySelector('#demo-result').textContent = describeResult([...new FormData(event
      .currentTarget)]);
  });
</script>

검사 결과와 오류 상태 읽기

제출 전에 검사하거나 오류를 화면에 표시할 수 있습니다. 필수 값을 비워 두고 검사한 다음, 값을 채워 반환 값이 어떻게 달라지는지 확인하세요. 상태 조회는 사용자 지정 오류와 필수 입력 오류를 구분하는 데 사용합니다.

코드 보기
HTML
<form style="display:grid;gap:16px">
  <sy-radio-group
    name="field"
    required
    id="sample"
  >
    <sy-radio value="yes">동의</sy-radio>
    <sy-radio value="no">동의하지 않음</sy-radio><span slot="error">하나를 선택하세요.</span>
  </sy-radio-group>
  <div style="display:flex;flex-wrap:wrap;gap:8px">
    <sy-button type="submit" variant="primary">제출</sy-button>
    <sy-button type="reset">초기화</sy-button>
  </div>
</form>
<div class="demo-actions"
  style="display:flex;flex-wrap:wrap;gap:8px;margin-top:16px"
>
  <sy-button id="action-0" size="small">유효성 확인</sy-button>
  <sy-button id="action-1" size="small">오류 표시</sy-button>
  <sy-button id="action-2" size="small">오류 해제</sy-button>
  <sy-button id="action-3" size="small">오류와 함께 검사</sy-button>
  <sy-button id="action-4" size="small">검증 상태 조회</sy-button>
</div>
<output id="demo-result" aria-live="polite"></output>

<script type="module">
  const describeResult = value => JSON.stringify(value, (_key, item) => {
    if (item instanceof File) return {
      name: item.name,
      size: item.size,
      type: item.type
    };
    if (item instanceof Element) return `<${item.localName}>`;
    return item;
  }) ?? '완료';
  const actionTarget0 = document.querySelector("#sample");
  document.querySelector('#action-0').addEventListener('click', async () => {
    const result = await actionTarget0.checkValidity();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget1 = document.querySelector("#sample");
  document.querySelector('#action-1').addEventListener('click', async () => {
    const result = await actionTarget1.setCustomError();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget2 = document.querySelector("#sample");
  document.querySelector('#action-2').addEventListener('click', async () => {
    const result = await actionTarget2.clearCustomError();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget3 = document.querySelector("#sample");
  document.querySelector('#action-3').addEventListener('click', async () => {
    const result = await actionTarget3.reportValidity();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget4 = document.querySelector("#sample");
  document.querySelector('#action-4').addEventListener('click', async () => {
    const result = await actionTarget4.getStatus();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  document.querySelector('form').addEventListener('submit', event => {
    event.preventDefault();
    document.querySelector('#demo-result').textContent = describeResult([...new FormData(event
      .currentTarget)]);
  });
</script>

사용자 지정 오류 메시지

서버 중복 검사나 업무 규칙에 맞지 않을 때 오류 문구를 직접 표시합니다. 아래 문구를 바꿔 보고 제출을 눌러 차단되는지 확인하세요. 오류 해제 후에는 필수 입력 조건까지 만족해야 제출됩니다.

코드 보기
HTML
<label for="error-message">표시할 오류 메시지</label><input
  id="error-message"
  value="서버에서 이 값을 승인하지 않았습니다. 내용을 확인해 주세요."
  type="text"
>
<form style="display:grid;gap:16px">
  <sy-radio-group
    nonativevalidity
    name="field"
    required
    id="sample"
  >
    <sy-radio value="yes">동의</sy-radio>
    <sy-radio value="no">동의하지 않음</sy-radio><span slot="error">하나를 선택하세요.</span>
  </sy-radio-group>
  <div style="display:flex;flex-wrap:wrap;gap:8px">
    <sy-button type="submit" variant="primary">제출</sy-button>
    <sy-button type="reset">초기화</sy-button>
  </div>
</form>
<div class="demo-actions">
  <sy-button id="show-custom-error" variant="primary">오류 표시</sy-button>
  <sy-button id="clear-custom-error">오류 해제</sy-button>
</div>
<output id="custom-error-result" aria-live="polite"></output>
<output id="demo-result" aria-live="polite"></output>

<script type="module">
  const describeResult = value => JSON.stringify(value, (_key, item) => {
    if (item instanceof File) return {
      name: item.name,
      size: item.size,
      type: item.type
    };
    if (item instanceof Element) return `<${item.localName}>`;
    return item;
  }) ?? '완료';
  await (async function customErrorSetup(root) {
    const field = root.querySelector('#sample');
    const message = root.querySelector('[slot="error"]');
    const input = root.querySelector('#error-message');
    const output = root.querySelector('#custom-error-result');
    const update = async () => {
      message.textContent = input.value.trim() || _msg("m_4eea8cef81c6");
      await field.setCustomError();
      output.textContent = _msg("m_e00bd46236d3", [message.textContent]);
    };
    input.addEventListener('input', update);
    root.querySelector('#show-custom-error').addEventListener('click', update);
    root.querySelector('#clear-custom-error').addEventListener('click', async () => {
      await field.clearCustomError();
      output.textContent = await field.checkValidity() ? _msg("m_c454251167b2") : _msg(
        "m_5b8cb48627e5");
    });
    root.querySelector('form').addEventListener('invalid', () => {
      output.textContent = _msg("m_c702c7778166");
    }, true);
    root.querySelector('form').addEventListener('reset', () => {
      output.textContent = _msg("m_b90c2b4dc30f");
    });
    await update();
  })(document);
  document.querySelector('form').addEventListener('submit', event => {
    event.preventDefault();
    document.querySelector('#demo-result').textContent = describeResult([...new FormData(event
      .currentTarget)]);
  });
</script>

API reference

#

이름에 마우스를 올리거나 키보드로 선택하면 적용 코드를 확인할 수 있습니다. 터치 화면에서는 이름을 누르세요.

<sy-radio-group>

Properties

Attribute / PropertyTypeDefaultDescription
booleanfalse사용자 조작과 키보드 포커스를 차단합니다.
string''처음 표시할 선택값입니다.
booleanfalse현재 값을 보여주면서 사용자 수정을 막습니다.
booleanfalse값이 없으면 폼 검증을 실패시킵니다.
'small' | 'medium' | 'large''medium'컴포넌트의 크기입니다.
'horizontal' | 'vertical''horizontal'항목 배치 방향입니다.
'outlined' | 'solid''outlined'컴포넌트의 표시 스타일입니다.
string''FormData에 사용되는 필드 이름입니다.
booleanfalse브라우저의 기본 오류 표시 대신 앱의 오류 UI를 사용할 때 지정합니다. checkValidity 검사 자체는 유지됩니다.

Events

EventDetailDescription
CustomEvent<{ value: string; isValid: boolean; status: string }>값 또는 선택 상태가 바뀔 때 발생합니다.

Methods

MethodReturnsDescription
Promise<boolean>현재 제약 조건에 맞으면 true, 아니면 false를 반환합니다.
Promise<boolean>현재 값을 검사하고 오류를 사용자에게 표시합니다.
Promise<void>사용자 지정 오류 상태를 설정합니다.
Promise<void>사용자 지정 오류 상태를 해제합니다.
Promise<"" | "custom" | "valueMissing">현재 유효성 검사 상태를 반환합니다.

Slots

SlotDescription
컴포넌트의 본문 또는 자식 항목입니다.
유효성 검사 오류 메시지입니다.

<sy-radio>

Properties

Attribute / PropertyTypeDefaultDescription
booleanfalse선택 또는 켜짐 상태입니다.
booleanfalse사용자 조작과 키보드 포커스를 차단합니다.
booleanfalse현재 값을 보여주면서 사용자 수정을 막습니다.
string''현재 값 또는 항목의 식별 값입니다.

Events

EventDetailDescription
CustomEvent<string>사용자가 항목을 선택했을 때 발생합니다.

Slots

SlotDescription
컴포넌트의 본문 또는 자식 항목입니다.

<sy-radio-button>

Properties

Attribute / PropertyTypeDefaultDescription
booleanfalse선택 또는 켜짐 상태입니다.
booleanfalse사용자 조작과 키보드 포커스를 차단합니다.
stringundefined현재 값 또는 항목의 식별 값입니다.
'small' | 'medium' | 'large''medium'컴포넌트의 크기입니다.
'outlined' | 'solid''outlined'컴포넌트의 표시 스타일입니다.

Events

EventDetailDescription
CustomEvent<string>사용자가 항목을 선택했을 때 발생합니다.

Slots

SlotDescription
컴포넌트의 본문 또는 자식 항목입니다.