Cascader
Cascader (캐스케이드 선택기)
Cascader는 연관된 데이터 집합(예: 시/도/구역, 회사 레벨, 사물 분류)에서 선택할 때 사용하는 컴포넌트예요. 단일 플로트 레이어에서 캐스케이드 항목을 골라 더 나은 사용자 경험을 제공해요.
출처: 문서
본문
언제 사용하나요
- 연관된 데이터 집합에서 선택해야 할 때. 예: 시/도/구역, 회사 레벨, 사물 분류.
- 큰 데이터 집합에서 선택할 때, 쉽게 선택하도록 다단계 분류로 나뉘어 있을 때.
- 하나의 플로트 레이어에서 캐스케이드 항목을 선택해 더 나은 사용자 경험을 제공할 때.
예제 (Examples)
기본 (Basic)
시/도/구역을 선택하는 캐스케이드 선택 상자예요.
import React from 'react';
import type { CascaderProps } from 'antd';
import { Cascader } from 'antd';
import type { HTMLAriaDataAttributes } from 'antd/es/_util/aria-data-attrs';
type Option = {
value: string;
label: string;
children?: Option[];
} & HTMLAriaDataAttributes;
const options: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
'aria-label': 'Zhejiang',
'data-title': 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
'aria-label': 'Hangzhou',
'data-title': 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
'aria-label': 'West Lake',
'data-title': 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
'aria-label': 'Jiangsu',
'data-title': 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
'aria-label': 'Nanjing',
'data-title': 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
'aria-label': 'Zhong Hua Men',
'data-title': 'Zhong Hua Men',
},
],
},
],
},
];
const onChange: CascaderProps<Option>['onChange'] = (value) => {
console.log(value);
};
const App: React.FC = () => (
<Cascader options={options} onChange={onChange} placeholder="Please select" />
);
export default App;
기본값 (Default value)
배열로 기본값을 지정해요.
import React from 'react';
import type { CascaderProps } from 'antd';
import { Cascader } from 'antd';
interface Option {
value: string;
label: string;
children?: Option[];
}
const options: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
const onChange: CascaderProps<Option>['onChange'] = (value) => {
console.log(value);
};
const App: React.FC = () => (
<Cascader defaultValue={['zhejiang', 'hangzhou', 'xihu']} options={options} onChange={onChange} />
);
export default App;
커스텀 트리거 (Custom trigger)
트리거 버튼과 결과를 분리해요.
import React, { useState } from 'react';
import type { CascaderProps } from 'antd';
import { Cascader } from 'antd';
interface Option {
value: string;
label: string;
children?: Option[];
}
const options: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
},
],
},
];
const App: React.FC = () => {
const [text, setText] = useState('Unselect');
const onChange: CascaderProps<Option>['onChange'] = (_, selectedOptions) => {
setText(selectedOptions.map((o) => o.label).join(', '));
};
return (
<span>
{text}
<Cascader options={options} onChange={onChange}>
<a>Change city</a>
</Cascader>
</span>
);
};
export default App;
호버 (Hover)
호버로 하위 메뉴를 펼치고, 클릭으로 옵션을 선택해요.
import React from 'react';
import type { CascaderProps } from 'antd';
import { Cascader } from 'antd';
interface Option {
value: string;
label: string;
children?: Option[];
}
const options: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
const onChange: CascaderProps<Option>['onChange'] = (value) => {
console.log(value);
};
// Just show the latest item.
const displayRender = (labels: string[]) => labels[labels.length - 1];
const App: React.FC = () => (
<Cascader
options={options}
expandTrigger="hover"
displayRender={displayRender}
onChange={onChange}
/>
);
export default App;
비활성 옵션 (Disabled option)
options의 disabled 속성을 지정해 옵션을 비활성화해요.
import React from 'react';
import type { CascaderProps } from 'antd';
import { Cascader } from 'antd';
interface Option {
value: string;
label: string;
disabled?: boolean;
children?: Option[];
}
const options: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
disabled: true,
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
const onChange: CascaderProps<Option>['onChange'] = (value) => {
console.log(value);
};
const App: React.FC = () => <Cascader options={options} onChange={onChange} />;
export default App;
선택 시 변경 (Change on select)
부모 옵션만 선택할 수 있게 해요.
import React from 'react';
import type { CascaderProps } from 'antd';
import { Cascader } from 'antd';
interface Option {
value: string;
label: string;
children?: Option[];
}
const options: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hanzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
const onChange: CascaderProps<Option>['onChange'] = (value) => {
console.log(value);
};
const App: React.FC = () => <Cascader options={options} onChange={onChange} changeOnSelect />;
export default App;
다중 선택 (Multiple)
여러 옵션을 선택해요. disableCheckbox 속성을 추가하고 특정 항목을 선택해 checkbox를 비활성화할 수 있어요. 비활성 스타일은 className으로 수정할 수 있어요.
import React from 'react';
import type { CascaderProps } from 'antd';
import { Cascader } from 'antd';
interface Option {
value: string | number;
label: string;
children?: Option[];
disableCheckbox?: boolean;
}
const options: Option[] = [
{
label: 'Light',
value: 'light',
children: Array.from({ length: 20 }).map((_, index) => ({
label: `Number ${index}`,
value: index,
})),
},
{
label: 'Bamboo',
value: 'bamboo',
children: [
{
label: 'Little',
value: 'little',
children: [
{
label: 'Toy Fish',
value: 'fish',
disableCheckbox: true,
},
{
label: 'Toy Cards',
value: 'cards',
},
{
label: 'Toy Bird',
value: 'bird',
},
],
},
],
},
];
const onChange: CascaderProps<Option, 'value', true>['onChange'] = (value) => {
console.log(value);
};
const App: React.FC = () => (
<Cascader
style={{ width: '100%' }}
options={options}
onChange={onChange}
multiple
maxTagCount="responsive"
/>
);
export default App;
ShowCheckedStrategy
showCheckedStrategy로 상자에 선택 항목을 표시하는 방식을 결정해요.
import React from 'react';
import type { CascaderProps } from 'antd';
import { Cascader } from 'antd';
const { SHOW_CHILD } = Cascader;
interface Option {
value: string | number;
label: string;
children?: Option[];
}
const options: Option[] = [
{
label: 'Light',
value: 'light',
children: Array.from({ length: 20 }).map((_, index) => ({
label: `Number ${index}`,
value: index,
})),
},
{
label: 'Bamboo',
value: 'bamboo',
children: [
{
label: 'Little',
value: 'little',
children: [
{
label: 'Toy Fish',
value: 'fish',
},
{
label: 'Toy Cards',
value: 'cards',
},
{
label: 'Toy Bird',
value: 'bird',
},
],
},
],
},
];
const App: React.FC = () => {
const onChange: CascaderProps<Option, 'value', true>['onChange'] = (value) => {
console.log(value);
};
return (
<>
<Cascader
style={{ width: '100%' }}
options={options}
onChange={onChange}
multiple
maxTagCount="responsive"
showCheckedStrategy={SHOW_CHILD}
defaultValue={[
['bamboo', 'little', 'fish'],
['bamboo', 'little', 'cards'],
['bamboo', 'little', 'bird'],
]}
/>
<br />
<br />
<Cascader
style={{ width: '100%' }}
options={options}
onChange={onChange}
multiple
maxTagCount="responsive"
defaultValue={[['bamboo']]}
/>
</>
);
};
export default App;
크기 (Size)
다양한 크기의 캐스케이드 선택 상자예요.
import React from 'react';
import type { CascaderProps } from 'antd';
import { Cascader } from 'antd';
interface Option {
value: string;
label: string;
children?: Option[];
}
const options: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
const onChange: CascaderProps<Option>['onChange'] = (value) => {
console.log(value);
};
const App: React.FC = () => (
<>
<Cascader size="large" options={options} onChange={onChange} />
<br />
<br />
<Cascader options={options} onChange={onChange} />
<br />
<br />
<Cascader size="small" options={options} onChange={onChange} />
<br />
<br />
</>
);
export default App;
커스텀 렌더 (Custom render)
예를 들어 선택된 값 뒤에 외부 링크를 추가해요.
import React from 'react';
import { Cascader } from 'antd';
import type { CascaderProps, GetProp } from 'antd';
type DefaultOptionType = GetProp<CascaderProps, 'options'>[number];
interface Option {
value: string;
label: string;
children?: Option[];
code?: number;
}
const options: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
code: 752100,
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
code: 453400,
},
],
},
],
},
];
const handleAreaClick = (
e: React.MouseEvent<HTMLAnchorElement>,
label: string,
option: DefaultOptionType,
) => {
e.stopPropagation();
console.log('clicked', label, option);
};
const displayRender: CascaderProps<Option>['displayRender'] = (labels, selectedOptions = []) =>
labels.map((label, i) => {
const option = selectedOptions[i];
if (i === labels.length - 1) {
return (
<span key={option.value}>
{label} (<a onClick={(e) => handleAreaClick(e, label, option)}>{option.code}</a>)
</span>
);
}
return <span key={option.value}>{label} / </span>;
});
const App: React.FC = () => (
<Cascader
options={options}
defaultValue={['zhejiang', 'hangzhou', 'xihu']}
displayRender={displayRender}
style={{ width: '100%' }}
// `optionRender` is supported since 5.16.0
optionRender={(option) => (
<>
{option.label} ({option.value})
</>
)}
/>
);
export default App;
검색 (Search)
검색하고 옵션을 직접 선택해요.
현재
Cascader[showSearch]는 서버에서의 검색을 지원하지 않아요. 자세한 내용: #5547
import React from 'react';
import { Cascader } from 'antd';
import type { CascaderProps, GetProp } from 'antd';
type DefaultOptionType = GetProp<CascaderProps, 'options'>[number];
interface Option {
value: string;
label: string;
children?: Option[];
disabled?: boolean;
}
const options: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
{
value: 'xiasha',
label: 'Xia Sha',
disabled: true,
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua men',
},
],
},
],
},
];
const onChange: CascaderProps<Option>['onChange'] = (value, selectedOptions) => {
console.log(value, selectedOptions);
};
const filter = (inputValue: string, path: DefaultOptionType[]) =>
path.some((option) => (option.label as string).toLowerCase().includes(inputValue.toLowerCase()));
const App: React.FC = () => (
<Cascader
options={options}
onChange={onChange}
placeholder="Please select"
showSearch={{ filter, onSearch: (value) => console.log(value) }}
/>
);
export default App;
옵션 지연 로드 (Load Options Lazily)
loadData로 옵션을 지연 로드해요.
참고:
loadData는showSearch와 함께 동작할 수 없어요.
import React, { useState } from 'react';
import type { CascaderProps } from 'antd';
import { Cascader } from 'antd';
interface Option {
value?: string | number | null;
label: React.ReactNode;
children?: Option[];
isLeaf?: boolean;
}
const optionLists: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
isLeaf: false,
},
{
value: 'jiangsu',
label: 'Jiangsu',
isLeaf: false,
},
];
const App: React.FC = () => {
const [options, setOptions] = useState<Option[]>(optionLists);
const onChange: CascaderProps<Option>['onChange'] = (value, selectedOptions) => {
console.log(value, selectedOptions);
};
const loadData = (selectedOptions: Option[]) => {
const targetOption = selectedOptions[selectedOptions.length - 1];
// load options lazily
setTimeout(() => {
targetOption.children = [
{
label: `${targetOption.label} Dynamic 1`,
value: 'dynamic1',
},
{
label: `${targetOption.label} Dynamic 2`,
value: 'dynamic2',
},
];
setOptions([...options]);
}, 1000);
};
return <Cascader options={options} loadData={loadData} onChange={onChange} changeOnSelect />;
};
export default App;
커스텀 필드 이름 (Custom Field Names)
커스텀 필드 이름을 지정해요.
import React from 'react';
import type { CascaderProps } from 'antd';
import { Cascader } from 'antd';
interface Option {
code: string;
name: string;
items?: Option[];
}
const options: Option[] = [
{
code: 'zhejiang',
name: 'Zhejiang',
items: [
{
code: 'hangzhou',
name: 'Hangzhou',
items: [
{
code: 'xihu',
name: 'West Lake',
},
],
},
],
},
{
code: 'jiangsu',
name: 'Jiangsu',
items: [
{
code: 'nanjing',
name: 'Nanjing',
items: [
{
code: 'zhonghuamen',
name: 'Zhong Hua Men',
},
],
},
],
},
];
const onChange: CascaderProps<Option>['onChange'] = (value) => {
console.log(value);
};
const App: React.FC = () => (
<Cascader
fieldNames={{ label: 'name', value: 'code', children: 'items' }}
options={options}
onChange={onChange}
placeholder="Please select"
/>
);
export default App;
Prefix와 Suffix
prefix로 prefix 콘텐츠를, suffixIcon으로 선택 상자 suffix 아이콘을, expandIcon으로 현재 항목 확장 아이콘을 커스터마이즈해요.
import React from 'react';
import { SmileOutlined } from '@ant-design/icons';
import type { CascaderProps } from 'antd';
import { Cascader } from 'antd';
interface Option {
value: string;
label: string;
children?: Option[];
}
const options: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
const onChange: CascaderProps<Option>['onChange'] = (value) => {
console.log(value);
};
const App: React.FC = () => (
<>
<Cascader
suffixIcon={<SmileOutlined />}
options={options}
onChange={onChange}
placeholder="Please select"
/>
<br />
<br />
<Cascader suffixIcon="ab" options={options} onChange={onChange} placeholder="Please select" />
<br />
<br />
<Cascader
expandIcon={<SmileOutlined />}
options={options}
onChange={onChange}
placeholder="Please select"
/>
<br />
<br />
<Cascader expandIcon="ab" options={options} onChange={onChange} placeholder="Please select" />
<br />
<br />
<Cascader
prefix={<SmileOutlined />}
options={options}
onChange={onChange}
placeholder="Please select"
/>
</>
);
export default App;
커스텀 드롭다운 (Custom dropdown)
popupRender로 드롭다운 메뉴를 커스터마이즈해요.
import React from 'react';
import { Cascader, Divider } from 'antd';
interface Option {
value: string;
label: string;
children?: Option[];
}
const options: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
const popupRender = (menus: React.ReactNode) => (
<div>
{menus}
<Divider style={{ margin: 0 }} />
<div style={{ padding: 8 }}>The footer is not very short.</div>
</div>
);
const App: React.FC = () => (
<Cascader options={options} popupRender={popupRender} placeholder="Please select" />
);
export default App;
배치 (Placement)
placement로 팝업의 위치를 수동으로 지정할 수 있어요.
import React, { useState } from 'react';
import type { RadioChangeEvent } from 'antd';
import { Cascader, Radio } from 'antd';
interface Option {
value: string;
label: string;
children?: Option[];
}
const options: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
const App: React.FC = () => {
const [placement, setPlacement] = useState<'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight'>(
'topLeft',
);
const placementChange = (e: RadioChangeEvent) => {
setPlacement(e.target.value);
};
return (
<>
<Radio.Group value={placement} onChange={placementChange}>
<Radio.Button value="topLeft">topLeft</Radio.Button>
<Radio.Button value="topRight">topRight</Radio.Button>
<Radio.Button value="bottomLeft">bottomLeft</Radio.Button>
<Radio.Button value="bottomRight">bottomRight</Radio.Button>
</Radio.Group>
<br />
<br />
<Cascader options={options} placeholder="Please select" placement={placement} />
</>
);
};
export default App;
변형 (Variants)
Cascader의 변형으로 outlined filled borderless underlined 네 가지가 있어요.
import React from 'react';
import { Cascader, Flex } from 'antd';
const App: React.FC = () => (
<Flex vertical gap="medium">
<Cascader placeholder="Please select" variant="borderless" />
<Cascader placeholder="Please select" variant="filled" />
<Cascader placeholder="Please select" variant="outlined" />
<Cascader placeholder="Please select" variant="underlined" />
</Flex>
);
export default App;
상태 (Status)
status로 Cascader에 상태를 추가해요. error나 warning일 수 있어요.
import React from 'react';
import { Cascader, Space } from 'antd';
const App: React.FC = () => (
<Space vertical>
<Cascader status="error" placeholder="Error" />
<Cascader status="warning" multiple placeholder="Warning multiple" />
</Space>
);
export default App;
커스텀 시맨틱 DOM 스타일링
classNames와 styles에 객체/함수를 전달해 Cascader의 시맨틱 DOM 스타일을 커스터마이즈할 수 있어요.
import React from 'react';
import { Cascader, Flex } from 'antd';
import type { CascaderProps, GetProp } from 'antd';
import { createStyles } from 'antd-style';
const useStyles = createStyles(({ token }) => {
return {
root: {
borderRadius: token.borderRadiusLG,
},
};
});
interface Option {
value: string;
label: string;
children?: Option[];
}
const options: Option[] = [
{
value: 'meet-student',
label: 'meet-student',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
const stylesObject: CascaderProps['styles'] = {
prefix: {
color: '#ccc',
},
suffix: {
color: '#ccc',
},
};
const stylesFn: CascaderProps['styles'] = (info): GetProp<CascaderProps, 'styles', 'Return'> => {
if (info.props.variant === 'filled') {
return {
prefix: {
color: '#1890ff',
},
suffix: {
color: '#1890ff',
},
popup: {
listItem: {
color: '#1890ff',
},
},
};
}
return {};
};
const onChange: CascaderProps<Option>['onChange'] = (value) => {
console.log(value);
};
const App: React.FC = () => {
const { styles: classNames } = useStyles();
return (
<Flex vertical gap="medium">
<Cascader
options={options}
onChange={onChange}
placeholder="Object styles"
classNames={classNames}
styles={stylesObject}
prefix="🏠"
/>
<Cascader
options={options}
onChange={onChange}
placeholder="Function styles"
variant="filled"
classNames={classNames}
styles={stylesFn}
prefix="✅"
/>
</Flex>
);
};
export default App;
5.10.0+ Panel
인라인 뷰 케이스에 사용해요.
import React, { useState } from 'react';
import type { CascaderProps } from 'antd';
import { Cascader, Flex, Switch } from 'antd';
interface Option {
value: string | number;
label: string;
children?: Option[];
}
const options: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
const onChange: CascaderProps<Option>['onChange'] = (value) => {
console.log(value);
};
const onMultipleChange: CascaderProps<Option, 'value', true>['onChange'] = (value) => {
console.log(value);
};
const App: React.FC = () => {
const [disabled, setDisabled] = useState(false);
return (
<Flex vertical gap="small" align="flex-start">
<Switch
checked={disabled}
checkedChildren="Enabled"
unCheckedChildren="Disabled"
onChange={setDisabled}
aria-label="disabled switch"
/>
<Cascader.Panel options={options} onChange={onChange} disabled={disabled} />
<Cascader.Panel multiple options={options} onChange={onMultipleChange} disabled={disabled} />
<Cascader.Panel />
</Flex>
);
};
export default App;
API
공통 props 참고: Common props
<Cascader options={options} onChange={onChange} />
| 속성 | 설명 | 타입 | 기본값 | 버전 | 전역 설정 |
|---|---|---|---|---|---|
| allowClear | clear 버튼 표시 | boolean | { clearIcon?: ReactNode } | true | 5.8.0: Object 타입 지원 | clearIcon: 6.4.0 |
항목을 선택할 때 현재 검색을 지울지 여부. multiple이 true일 때만 적용 |
boolean | true | 5.9.0 | × | |
테두리 스타일 여부, variant를 사용하세요 |
boolean | true | - | × | |
| changeOnSelect | true로 설정하면 각 선택마다 값을 변경, 위 데모 참고 | boolean | false | × | |
| classNames | 컴포넌트 내부 각 시맨틱 구조의 클래스 커스터마이즈. 객체 또는 함수 지원 | Record<SemanticDOM, string> | (info: { props })=> Record<SemanticDOM, string> | - | 5.25.0 | |
| defaultOpen | 캐스케이드 팝업의 초기 표시 | boolean | - | × | |
| defaultValue | 초기 선택값 | string[] | number[] | [] | × | |
| disabled | select 비활성화 여부 | boolean | false | × | |
| displayRender | 선택된 옵션을 표시하는 렌더 함수 | (label, selectedOptions) => ReactNode | label => label.join(/) |
multiple: 4.18.0 |
× |
| tagRender | multiple 모드에서 태그의 커스텀 렌더 함수 |
(label: string, onClose: function, value: string) => ReactNode | - | × | |
팝업 오버레이의 추가 className, classNames.popup.root를 사용하세요 |
string | - | 4.23.0 | × | |
팝업 오버레이의 추가 className, classNames.popup.root를 사용하세요 |
string | - | - | × | |
드롭다운 콘텐츠 커스터마이즈, popupRender를 사용하세요 |
(menus: ReactElement) => ReactNode | - | 4.4.0 | × | |
| popupRender | 드롭다운 콘텐츠 커스터마이즈 | (menus: ReactElement) => ReactNode | - | × | |
드롭다운 메뉴의 스타일, styles.popup.root를 사용하세요 |
CSSProperties | - | × | ||
| expandIcon | 현재 항목 확장 아이콘 커스터마이즈 | ReactNode | - | 4.4.0 | 6.3.0 |
| expandTrigger | 클릭 또는 호버 시 현재 항목 확장, click hover 중 하나 |
string | click |
× | |
| fieldNames | label, value, children의 커스텀 필드 이름 | object | { label: label, value: value, children: children } |
× | |
| getPopupContainer | 셀렉터가 렌더링될 부모 노드. 기본은 body. 위치 문제 발생 시 스크롤 가능한 콘텐츠로 바꿔 그에 상대적으로 위치 지정해 보세요 |
function(triggerNode) | () => document.body | × | |
| loadData | 옵션을 지연 로드, showSearch와 함께 동작할 수 없음 |
(selectedOptions) => void | - | × | |
| loadingIcon | 로딩 아이콘 커스터마이즈 | ReactNode | - | 6.3.0 | |
| maxTagCount | 표시할 최대 태그 개수. responsive는 렌더 성능을 소모 |
number | responsive |
- | 4.17.0 | × |
| maxTagPlaceholder | 표시되지 않는 태그의 placeholder | ReactNode | function(omittedValues) | - | 4.17.0 | × |
| maxTagTextLength | 표시할 최대 태그 텍스트 길이 | number | - | 4.17.0 | × |
| notFoundContent | 일치하는 결과가 없을 때 표시할 콘텐츠 | ReactNode | No data |
× | |
| open | 캐스케이드 팝업 표시 설정 | boolean | - | 4.17.0 | × |
| options | 캐스케이드 데이터 옵션 | Option[] | - | × | |
| placeholder | 입력 placeholder | string | - | × | |
| placement | builtinPlacements의 프리셋 팝업 정렬 설정 사용 | bottomLeft bottomRight topLeft topRight |
bottomLeft |
4.17.0 | × |
| prefix | 커스텀 prefix | ReactNode | - | 5.22.0 | × |
화살표 아이콘 표시 여부, suffixIcon={null}을 사용하세요 |
boolean | true | - | × | |
| showSearch | 단일 모드에서 검색 입력 표시 여부 | boolean | Object | false | searchIcon: 6.4.0 |
|
| size | 입력 크기 | large | medium | small |
medium |
× | |
| status | 검증 상태 설정 | 'error' | 'warning' | - | 4.19.0 | × |
| styles | 컴포넌트 내부 각 시맨틱 구조의 인라인 스타일 커스터마이즈. 객체 또는 함수 지원 | Record<SemanticDOM, CSSProperties> | (info: { props })=> Record<SemanticDOM, CSSProperties> | - | 5.25.0 | |
| suffixIcon | 커스텀 suffix 아이콘 | ReactNode | - | 6.4.0 | |
| value | 선택된 값 | string[] | number[] | - | × | |
| variant | 셀렉터의 변형 | outlined | borderless | filled | underlined |
outlined |
5.13.0 | underlined: 5.24.0 |
5.19.0 |
| onChange | 캐스케이드 선택 완료 시 콜백 | (value, selectedOptions) => void | - | × | |
| onClear | 지울 때 호출 | () => void | - | - | × |
팝업 표시/숨김 콜백, onOpenChange를 사용하세요 |
(value) => void | - | 4.17.0 | × | |
| onOpenChange | 팝업 표시/숨김 콜백 | (open: boolean) => void | - | × | |
팝업 표시/숨김 콜백, onOpenChange를 사용하세요 |
(value) => void | - | - | × | |
| multiple | 다중 선택 지원 여부 | boolean | - | 4.17.0 | × |
| removeIcon | 커스텀 제거 아이콘 | ReactNode | - | 6.4.0 | |
| showCheckedStrategy | 상자에 선택 항목 표시 방식 (multiple이 true일 때만 유효). Cascader.SHOW_CHILD: 자식 트리노드만 표시. Cascader.SHOW_PARENT: 부모 트리노드만 표시 (부모 노드 아래 모든 자식 트리노드가 체크됐을 때) |
Cascader.SHOW_PARENT | Cascader.SHOW_CHILD |
Cascader.SHOW_PARENT |
4.20.0 | × |
검색값 설정, showSearch와 함께 필요 |
string | - | 4.17.0 | × | |
| 입력이 바뀔 때 트리거되는 콜백 함수 | (search: string) => void | - | 4.17.0 | × | |
드롭다운 메뉴 컬럼 스타일, styles.popup.listItem을 사용하세요 |
CSSProperties | - | × | ||
드롭다운 메뉴 컬럼 스타일, styles.popup.listItem을 사용하세요 |
CSSProperties | - | × | ||
| optionRender | 드롭다운 옵션 렌더링 커스터마이즈 | (option: Option) => React.ReactNode | - | 5.16.0 | × |
showSearch
| 속성 | 설명 | 타입 | 기본값 | 버전 |
|---|---|---|---|---|
| autoClearSearchValue | 항목을 선택할 때 현재 검색을 지울지 여부. multiple이 true일 때만 적용 |
boolean | true | 5.9.0 |
| filter | 함수는 inputValue와 option 두 인자를 받고, true를 반환하면 옵션이 필터 집합에 포함 | function(inputValue, path): boolean | - | |
| limit | 필터링된 항목의 개수 설정 | number | false | 50 | |
| matchInputWidth | 리스트의 너비가 입력과 일치하는지 | boolean | true | |
| render | 필터링된 옵션 렌더링에 사용 | function(inputValue, path): ReactNode | - | |
| sort | 필터링된 옵션 정렬에 사용 | function(a, b, inputValue) | - | |
| searchValue | 검색값 설정, showSearch와 함께 필요 |
string | - | 4.17.0 |
| onSearch | 입력이 바뀔 때 트리거되는 콜백 함수 | (search: string) => void | - | 4.17.0 |
| searchIcon | 검색 아이콘 커스터마이즈 | ReactNode | - | 6.3.0 |
Option
interface Option {
value: string | number;
label?: React.ReactNode;
disabled?: boolean;
children?: Option[];
// Determines if this is a leaf node(effective when `loadData` is specified).
// `false` will force trade TreeNode as a parent node.
// Show expand icon even if the current node has no children.
isLeaf?: boolean;
}
메서드 (Methods)
| 이름 | 설명 | 버전 |
|---|---|---|
| blur() | 포커스 제거 | |
| focus() | 포커스 얻기 |
시맨틱 DOM (Semantic DOM)
https://ant.design/components/cascader/semantic.md
디자인 토큰 (Design Token)
컴포넌트 토큰 (Cascader)
| 토큰 이름 | 설명 | 타입 | 기본값 |
|---|---|---|---|
| controlItemWidth | 항목의 너비 | string | number | 111 |
| controlWidth | Cascader의 너비 | string | number | 184 |
| dropdownHeight | 드롭다운의 높이 | string | number | 180 |
| menuPadding | 메뉴 항목(단일 컬럼)의 패딩 | Padding<string | number> | undefined | 4 |
| optionPadding | 메뉴 항목의 패딩 | Padding<string | number> | undefined | 5px 12px |
| optionSelectedBg | 선택된 항목의 배경색 | string | #e6f4ff |
| optionSelectedColor | 옵션이 선택됐을 때 텍스트 색 | string | rgba(0,0,0,0.88) |
| optionSelectedFontWeight | 선택된 항목의 폰트 두께 | FontWeight | undefined | 600 |
전역 토큰 (Global Token)
| 토큰 이름 | 설명 | 타입 | 기본값 |
|---|---|---|---|
| borderRadiusSM | SM 크기 테두리 반지름, Button, Input, Select 등 작은 입력 컴포넌트에 사용 | number | |
| colorBgContainer | 컨테이너 배경색. 예: 기본 버튼, 입력박스 등. colorBgElevated와 혼동하지 말 것. |
string | |
| colorBgContainerDisabled | 비활성 상태 컨테이너의 배경색 제어. | string | |
| colorBorder | 기본 테두리색, 요소를 구분하는 데 사용. 예: 폼 구분선, 카드 구분선 등 | string | |
| colorHighlight | 페이지 요소의 하이라이트 색 제어. | string | |
| colorIcon | 약한 액션. 예: allowClear 또는 Alert 닫기 버튼 |
string | |
| colorPrimary | 브랜드 색. 제품의 특성과 커뮤니케이션을 반영하는 가장 직접적인 시각 요소. 선택하면 완전한 색 팔레트가 자동 생성 | string | |
| colorPrimaryBorder | 기본 색 그라데이션 아래의 스트로크 색. Slider 같은 컴포넌트의 스트로크에 사용 | string | |
| colorPrimaryHover | 기본 색 그라데이션 아래의 호버 상태. | string | |
| colorSplit | 구분선 색. colorBorderSecondary와 같지만 투명도가 있음. | string | |
| colorText | W3C 표준을 준수하는 기본 텍스트 색. 가장 어두운 중성색이기도 함. | string | |
| colorTextDisabled | 비활성 상태 텍스트의 색 제어. | string | |
| colorWhite | 테마에 의해 바뀌지 않는 순수 흰색 | string | |
| controlInteractiveSize | 컨트롤 컴포넌트의 인터랙티브 크기 제어. | number | |
| controlItemBgHover | 컨트롤 컴포넌트 항목의 호버 배경색 제어. | string | |
| fontFamily | 시스템 기본 인터페이스 폰트와 화면 표시에 적합한 대체 폰트 라이브러리 세트 제공 | string | |
| fontSize | 디자인 시스템에서 가장 널리 사용되는 폰트 크기. | number | |
| fontSizeIcon | Select, Cascader 등의 동작 아이콘 폰트 크기 제어. 보통 fontSizeSM과 같음. | number | |
| fontSizeLG | 큰 폰트 크기 | number | |
| lineHeight | 텍스트의 줄 높이. | number | |
| lineType | 기본 컴포넌트의 테두리 스타일 | string | |
| lineWidth | 기본 컴포넌트의 테두리 너비 | number | |
| lineWidthBold | Button, Input, Select 등 아웃라인 계열 컴포넌트의 기본 선 너비 | number | |
| lineWidthFocus | 컴포넌트가 포커스 상태일 때 선 너비 제어. | number | |
| marginXS | 요소의 여백 제어, 작은 크기. | number | |
| motionDurationFast | 모션 속도, 빠른 속도. 작은 요소 애니메이션 상호작용에 사용. | string | |
| motionDurationMid | 모션 속도, 중간 속도. 중간 요소 애니메이션 상호작용에 사용. | string | |
| motionDurationSlow | 모션 속도, 느린 속도. 대형 요소 애니메이션 상호작용에 사용. | string | |
| motionEaseInBack | 프리셋 모션 곡선. | string | |
| motionEaseOutBack | 프리셋 모션 곡선. | string | |
| paddingXS | 요소의 매우 작은 패딩 제어. | number | |
| paddingXXS | 요소의 매우 작은 여분의 패딩 제어. | number |
더 알아보기 (Learn more)
- Select 컴포넌트 — 캐스케이드 vs 선택
- TreeSelect 컴포넌트 — 트리 구조 선택
- Ant Design 시작하기 — 프로젝트 설정