Input

이름, 이메일, 검색어처럼 한 줄의 값을 입력받습니다.

Live preview
컴포넌트를 조작하면 여기에 결과가 표시됩니다.
코드 보기
HTML
<sy-input
  label="이름"
  placeholder="이름을 입력하세요"
  type="text"
  size="medium"
  status="default"
  clearable
  id="sample"
  name="name"
></sy-input>

사용 가이드

#

짧은 한 줄의 값을 입력받을 때 사용합니다. Label로 목적을 설명하고, Placeholder는 입력 예시를 보여주는 데 사용하세요.

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

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

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

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

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

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

일반 텍스트

text, search, password 등 입력 목적에 맞는 type을 선택하세요.

연락처·주소

email, tel, url로 입력할 값의 종류를 알려주세요.

숫자 입력

number를 사용할 수 있습니다. 범위·증감·정밀도 제어가 필요하면 Input Number를 사용하세요.

예제

#

이메일과 비밀번호

type에 따라 입력 방식과 기본 검증 규칙이 바뀝니다.

코드 보기
HTML
<div style="display:grid;gap:16px;width:100%">
  <sy-input
    type="email"
    label="이메일"
    placeholder="name@example.com"
  ></sy-input>
  <sy-input
    type="password"
    label="비밀번호"
    value="syidax-demo"
  ></sy-input>
</div>

앞뒤 보조 요소

prefix·suffix 슬롯으로 단위나 문맥을 더합니다. 실제 값에는 슬롯 내용이 포함되지 않습니다.

코드 보기
HTML
<sy-input
  label="웹사이트"
  placeholder="example.com"
  clearable
><span slot="prefix">https://</span><span slot="suffix">↗</span></sy-input>

입력 상태

성공·경고·오류를 시각적으로 표시합니다. status만 바꾸는 것은 폼 검증을 대신하지 않습니다.

코드 보기
HTML
<div style="display:grid;gap:16px;width:100%">
  <sy-input
    status="default"
    label="default"
    value="Syidax"
  ></sy-input>
  <sy-input
    status="success"
    label="success"
    value="Syidax"
  ></sy-input>
  <sy-input
    status="warning"
    label="warning"
    value="Syidax"
  ></sy-input>
  <sy-input
    status="error"
    label="error"
    value="Syidax"
  ></sy-input>
</div>

비활성화와 읽기 전용

위에서부터 기본 상태, 비활성화, 읽기 전용입니다. 비활성화 항목은 포커스와 입력이 차단됩니다. 읽기 전용은 값을 유지하면서 수정을 막습니다.

코드 보기
HTML
<div style="display:grid;gap:16px;width:100%">
  <sy-input
    label="이름"
    value="Alex Kim"
    clearable
  ></sy-input>
  <sy-input
    label="이름"
    value="Alex Kim"
    clearable
    disabled
  ></sy-input>
  <sy-input
    label="이름"
    value="Alex Kim"
    clearable
    readonly
  ></sy-input>
</div>

값과 입력 유형 변경

동일한 입력에서 type·value를 변경해도 실제 입력과 검증 상태가 함께 갱신됩니다.

코드 보기
HTML
<sy-input
  type="password"
  value="syidax-demo"
  label="외부에서 제어하는 입력"
  clearable
  id="sample"
></sy-input>
<div class="demo-actions">
  <sy-button id="as-text">텍스트로 전환</sy-button>
  <sy-button id="invalid-email">잘못된 이메일 적용</sy-button>
  <sy-button id="valid-email">올바른 이메일 적용</sy-button>
</div>
<output id="controlled-result" aria-live="polite"></output>

<script type="module">
  await (root => {
    const input = root.querySelector('#sample');
    const result = root.querySelector('#controlled-result');
    const apply = async (type, value) => {
      input.type = type;
      input.value = value;
      result.textContent =
        `${type} · ${await input.checkValidity() ? _msg("m_c5619d3358dc") : _msg("m_05b136149408")} · ${await input.getStatus() || _msg("m_79ca43ef8a7f")}`;
    };
    root.querySelector('#as-text').addEventListener('click', () => apply('text', 'Syidax'));
    root.querySelector('#invalid-email').addEventListener('click', () => apply('email',
      'invalid'));
    root.querySelector('#valid-email').addEventListener('click', () => apply('email',
      'name@example.com'));
  })(document);
</script>

포커스 제어

외부 동작 후 setFocus로 입력란에 포커스를 보내고 setBlur로 해제할 수 있습니다.

코드 보기
HTML
<sy-input label="프로젝트 이름" id="sample"></sy-input>
<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>
</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.setFocus();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget1 = document.querySelector("#sample");
  document.querySelector('#action-1').addEventListener('click', async () => {
    const result = await actionTarget1.setBlur();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
</script>

이벤트와 전달 값

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

코드 보기
HTML
<sy-input
  label="이름"
  placeholder="이름을 입력하세요"
  type="text"
  size="medium"
  status="default"
  clearable
  id="sample"
  name="name"
></sy-input>
<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", "blured", "focused", "clear"]) {
    document.addEventListener(name, event => {
      document.querySelector('#demo-events').textContent =
        `${event.target.localName} · ${name}: ${describeResult(event.detail)}`;
    });
  }
</script>

입력 아이콘과 도움말

prefix-icon과 suffix-icon은 입력 양 끝의 아이콘 영역입니다. message에는 항상 읽을 수 있는 도움말을, error에는 검증 실패 안내를 넣으세요.

코드 보기
HTML
<sy-input
  placeholder="이메일"
  type="email"
  label="연락처"
><span slot="prefix-icon" aria-hidden="true">@</span><span slot="suffix-icon"
    aria-hidden="true"
  >✉</span><span slot="message">업무용 이메일 주소를 입력하세요.</span><span slot="error">이메일
    형식을 확인하세요.</span></sy-input>

폼과 유효성 검사

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

코드 보기
HTML
<form style="display:grid;gap:16px">
  <sy-input
    name="field"
    required
    type="email"
    label="이메일"
    clearable
    id="sample"
  ><span slot="error">올바른 이메일을 입력하세요.</span></sy-input>
  <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>

폼 그룹 비활성화

fieldset으로 그룹을 잠그고 해제할 수 있습니다. 개별 disabled 항목은 계속 비활성화되며 FormData에서 제외됩니다.

코드 보기
HTML
<form>
  <fieldset id="input-group">
    <legend>프로젝트 담당자</legend>
    <sy-input
      label="담당자"
      name="owner"
      value="Alex"
      required
    ></sy-input>
    <sy-input
      label="잠긴 항목"
      name="locked"
      value="Admin"
      disabled
    ></sy-input>
  </fieldset>
  <div class="demo-actions">
    <sy-button id="lock-group">그룹 잠그기</sy-button>
    <sy-button id="unlock-group">그룹 해제</sy-button>
    <sy-button type="submit">제출</sy-button>
    <sy-button type="reset">초기화</sy-button>
  </div>
</form>
<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 (root => {
    const group = root.querySelector('#input-group');
    root.querySelector('#lock-group').addEventListener('click', () => group.disabled = true);
    root.querySelector('#unlock-group').addEventListener('click', () => group.disabled = false);
  })(document);
  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-input
    name="field"
    required
    type="email"
    label="이메일"
    clearable
    id="sample"
  ><span slot="error">올바른 이메일을 입력하세요.</span></sy-input>
  <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-input
    nonativevalidity
    name="field"
    required
    type="email"
    label="이메일"
    clearable
    id="sample"
  ><span slot="error">올바른 이메일을 입력하세요.</span></sy-input>
  <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-input>

Properties

Attribute / PropertyTypeDefaultDescription
booleanfalse처음 연결될 때 입력란에 포커스를 보냅니다.
booleanfalse기본 테두리를 숨깁니다.
booleanfalse현재 값을 비우는 버튼을 표시합니다.
booleanfalse사용자 조작과 키보드 포커스를 차단합니다.
string""항목을 설명하는 레이블입니다.
numberundefined허용하는 최대 문자열 길이입니다.
numberundefined허용하는 최소 문자열 길이입니다.
string""FormData에 사용되는 필드 이름입니다.
string""값이 비어 있을 때 표시할 안내 문구입니다.
booleanfalse현재 값을 보여주면서 사용자 수정을 막습니다.
booleanfalse값이 없으면 폼 검증을 실패시킵니다.
"small" | "medium" | "large""medium"컴포넌트의 크기입니다.
'default' | 'warning' | 'error' | 'success''default'기본·성공·경고·오류 상태를 시각적으로 표현합니다.
string""현재 값 또는 항목의 식별 값입니다.
"password" | "search" | "text""text"이전 버전과 호환되는 입력 유형입니다. 새 코드에서는 type을 사용하세요.
booleanfalse브라우저의 기본 오류 표시 대신 앱의 오류 UI를 사용할 때 지정합니다. checkValidity 검사 자체는 유지됩니다.
'text' | 'password' | 'email' | 'number' | 'tel' | 'url' | 'search''text'HTML 입력 종류 또는 버튼 동작 유형입니다.
string""입력 상태에 대한 안내 문구입니다.

Events

EventDetailDescription
CustomEvent<{ value: string; isValid: boolean; status: string }>값 또는 선택 상태가 바뀔 때 발생합니다.
CustomEvent<{ value: string; isValid: boolean; status: string }>포커스를 잃으면 발생합니다.
CustomEvent<{ value: string; isValid: boolean; status: string }>포커스를 받으면 발생합니다.
CustomEvent<void>입력값을 지우면 발생합니다.

Methods

MethodReturnsDescription
Promise<void>입력 또는 동작 요소에 키보드 포커스를 보냅니다.
Promise<void>입력 요소에서 포커스를 해제합니다.
Promise<boolean>현재 제약 조건에 맞으면 true, 아니면 false를 반환합니다.
Promise<boolean>현재 값을 검사하고 오류를 사용자에게 표시합니다.
Promise<void>사용자 지정 오류 상태를 설정합니다.
Promise<void>사용자 지정 오류 상태를 해제합니다.
Promise<"" | "custom" | "valueMissing" | "tooShort" | "tooLong" | "typeMismatch" | "badInput" | "stepMismatch">현재 유효성 검사 상태를 반환합니다.

Slots

SlotDescription
입력값 앞의 보조 내용입니다.
입력값 앞의 아이콘입니다.
유효성 검사 오류 메시지입니다.
입력 안내 메시지입니다.
입력값 뒤의 보조 내용입니다.
입력값 뒤의 아이콘입니다.