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은 두 가지 방식으로 옵션을 전달할 수 있어요.
dataprop 배열option컴포넌트가 들어간childrenprop
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– 오른쪽 섹션의 너비와 인풋 해당 쪽의 패딩을 제어해요. 기본적으로 컴포넌트sizeprop에 의해 제어돼요.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']} />; }