NativeSelect

NativeSelect

Input 기반의 네이티브 select 요소 컴포넌트예요.

출처: 문서

본문

사용법 (Usage)

NativeSelect 컴포넌트는 Input 및 Input.Wrapper 컴포넌트 기능과 모든 select 요소 prop을 지원해요. NativeSelect 문서에는 컴포넌트가 지원하는 모든 기능이 포함되지는 않아요. 사용 가능한 모든 기능은 Input 문서를 참고해요.

import { NativeSelect } from '@mantine/core';

function Demo() {
  return <NativeSelect label="Input label" description="Input description" data={['React', 'Angular', 'Vue']} />;
}

variant, size, radius, label, description, error 등의 표준 Input prop을 지원해요.

로딩 상태 (Loading state)

loading prop을 설정하면 로딩 인디케이터가 표시돼요. 기본적으로 로더는 인풋 오른쪽에 표시돼요. loadingPosition prop을 'left' 또는 'right'로 바꿔 위치를 변경할 수 있어요. API 호출, 검색, 검증 같은 비동기 작업에 유용해요.

import { NativeSelect } from '@mantine/core';

function Demo() {
  return <NativeSelect label="Your favorite framework" loading loadingPosition="right" data={['React', 'Angular', 'Vue', 'Svelte']} />;
}

제어 방식 (Controlled)

import { useState } from 'react';
import { NativeSelect } from '@mantine/core';

function Demo() {
  const [value, setValue] = useState('');

  return (
    <NativeSelect value={value} onChange={(event) => setValue(event.currentTarget.value)} data={['React', 'Angular', 'Svelte', 'Vue']} />
  );
}

비제어 방식 (Uncontrolled)

NativeSelect은 네이티브 select 요소와 같은 방식으로 비제어 폼에서 사용할 수 있어요. 폼 제출 시 FormData 객체에 네이티브 셀렉트 값을 포함하려면 name 속성을 설정해요. 비제어 폼에서 초기 값을 제어하려면 defaultValue prop을 사용해요.

FormData와 함께 비제어 NativeSelect을 사용하는 예시:

import { NativeSelect } from '@mantine/core';

function Demo() {
  return (
    <form
      onSubmit={(event) => {
        event.preventDefault();
        const formData = new FormData(event.currentTarget);
        console.log('Select value:', formData.get('framework'));
      }}
    >
      <NativeSelect name="framework" data={['React', 'Angular', 'Vue']} />
      <button type="submit">Submit</button>
    </form>
  );
}

옵션 추가 (Adding options)

NativeSelect은 두 가지 방식으로 옵션을 전달할 수 있어요.

  • data prop 배열
  • option 컴포넌트가 들어간 children prop

children을 사용하면 data는 무시돼요.

data prop

data prop은 다음 형식 중 하나의 값을 받아요.

  • 문자열 배열:
import { NativeSelect } from '@mantine/core';

function Demo() {
  return <NativeSelect data={['React', 'Angular', 'Vue']} />;
}
  • label, value, disabled 키를 가진 객체 배열:
import { NativeSelect } from '@mantine/core';

function Demo() {
  return (
    <NativeSelect
      data={[
        { value: 'react', label: 'React' },
        { value: 'angular', label: 'Angular' },
        { value: 'vue', label: 'Vue', disabled: true },
      ]}
    />
  );
}
  • 그룹화된 옵션 배열(문자열 형식):
import { NativeSelect } from '@mantine/core';

function Demo() {
  return (
    <NativeSelect
      data={[
        { group: 'Frontend', items: ['React', 'Angular', 'Vue'] },
        { group: 'Backend', items: ['Express', 'Koa', 'Django'] },
      ]}
    />
  );
}
  • 그룹화된 옵션 배열(객체 형식):
import { NativeSelect } from '@mantine/core';

function Demo() {
  return (
    <NativeSelect
      data={[
        { group: 'Frontend', items: [{ label: 'React', value: 'react' }, { label: 'Angular', value: 'angular' }] },
        { group: 'Backend', items: [{ label: 'Express', value: 'express' }, { label: 'Koa', value: 'koa' }] },
      ]}
    />
  );
}

children 옵션

children prop으로 옵션을 추가하려면 option 요소로 옵션을, optgroup 요소로 그룹을 만들어요.

import { NativeSelect } from '@mantine/core';

function Demo() {
  return (
    <NativeSelect label="With children options" defaultValue="react">
      <optgroup label="Frontend">
        <option value="react">React</option>
        <option value="angular">Angular</option>
      </optgroup>
      <optgroup label="Backend">
        <option value="express">Express</option>
        <option value="koa">Koa</option>
        <option value="django">Django</option>
      </optgroup>
    </NativeSelect>
  );
}

구분선과 함께 (With dividers)

옵션 사이에 구분선을 추가하려면 hr 태그를 사용해요.

import { NativeSelect } from '@mantine/core';

function Demo() {
  return (
    <NativeSelect label="Select library">
      <option value="react">React</option>
      <option value="angular">Angular</option>
      <option value="vue">Vue</option>
      <hr />
      <option value="express">Express</option>
      <option value="koa">Koa</option>
      <option value="django">Django</option>
    </NativeSelect>
  );
}

왼쪽·오른쪽 섹션 (Left and right sections)

NativeSelect은 leftSection과 rightSection prop을 지원해요. 이 섹션들은 인풋 래퍼 안에서 절대 위치로 렌더링돼요. 아이콘, 인풋 컨트롤 또는 다른 요소를 표시하는 데 사용할 수 있어요.

섹션 스타일과 콘텐츠를 제어하려면 다음 prop을 사용할 수 있어요.

  • rightSection/leftSection – 인풋의 해당 쪽에 렌더링할 React 노드
  • rightSectionWidth/leftSectionWidth – 오른쪽 섹션의 너비와 인풋 해당 쪽의 패딩을 제어해요. 기본적으로 컴포넌트 size prop에 의해 제어돼요.
  • rightSectionPointerEvents/leftSectionPointerEvents – 섹션의 pointer-events 속성을 제어해요. 비대화형 요소를 렌더링하고 싶다면 none으로 설정해 클릭이 인풋으로 통과하게 해요.
import { NativeSelect } from '@mantine/core';
import { CaretDownIcon, HashIcon } from '@phosphor-icons/react';

function Demo() {
  return (
    <>
      <NativeSelect
        leftSection={<HashIcon size={16} />}
        leftSectionPointerEvents="none"
        label="Left section"
        data={['React', 'Angular']}
      />
      <NativeSelect
        rightSection={<CaretDownIcon size={16} />}
        label="Right section"
        data={['React', 'Angular']}
        mt="md"
      />
    </>
  );
}

비활성 상태 (Disabled state)

import { NativeSelect } from '@mantine/core';

function Demo() {
  return <NativeSelect label="Disabled NativeSelect" disabled data={['React', 'Angular']} />;
}

오류 상태 (Error state)

import { NativeSelect } from '@mantine/core';

function Demo() {
  return (
    <>
      <NativeSelect error data={['React', 'Angular']} />
      <NativeSelect error="Error message" data={['React', 'Angular']} mt="md" />
    </>
  );
}

성공 상태 (Success state)

import { NativeSelect } from '@mantine/core';

function Demo() {
  return <NativeSelect label="Native Select" error="Looks good!" data={['React', 'Angular', 'Vue', 'Svelte']} />;
}

Styles API

NativeSelect은 Styles API를 지원해요. classNames prop으로 컴포넌트의 내부 요소에 스타일을 추가할 수 있어요.

Styles API 셀렉터:

  • root – 루트 요소
  • label – 라벨 요소
  • required – 라벨 안에 렌더링되는 필수 별표 요소
  • description – 설명 요소
  • error – 오류 요소
  • success – 성공 요소
  • wrapper – Input의 루트 요소
  • input – 인풋 요소
  • section – 왼쪽·오른쪽 섹션
  • bottomSection – 인풋 테두리 하단 안쪽에 렌더링되는 아래쪽 섹션 요소

접근성 (Accessibility)

label prop 없이 NativeSelect을 사용하면 스크린 리더가 제대로 알리지 못해요.

// Inaccessible input – screen reader will not announce it properly
import { NativeSelect } from '@mantine/core';
function Demo() { return <NativeSelect data={['React', 'Angular']} />; }

aria-label을 설정하면 인풋을 접근 가능하게 만들 수 있어요. 이 경우 라벨은 보이지 않지만 스크린 리더가 알려줘요.

// Accessible input – it has aria-label
import { NativeSelect } from '@mantine/core';
function Demo() { return <NativeSelect aria-label="Select framework" data={['React', 'Angular']} />; }

label prop이 설정되어 있으면 인풋은 접근 가능하며 aria-label을 설정할 필요가 없어요.

// Accessible input – it has associated label element
import { NativeSelect } from '@mantine/core';
function Demo() { return <NativeSelect label="Select framework" data={['React', 'Angular']} />; }

더 알아보기 (Learn more)