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}
      &nbsp;
      <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;

검색하고 옵션을 직접 선택해요.

현재 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
autoClearSearchValue 항목을 선택할 때 현재 검색을 지울지 여부. multiple이 true일 때만 적용 boolean true 5.9.0 ×
bordered 테두리 스타일 여부, 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 - ×
popupClassName 팝업 오버레이의 추가 className, classNames.popup.root를 사용하세요 string - 4.23.0 ×
dropdownClassName 팝업 오버레이의 추가 className, classNames.popup.root를 사용하세요 string - - ×
dropdownRender 드롭다운 콘텐츠 커스터마이즈, popupRender를 사용하세요 (menus: ReactElement) => ReactNode - 4.4.0 ×
popupRender 드롭다운 콘텐츠 커스터마이즈 (menus: ReactElement) => ReactNode - ×
dropdownStyle 드롭다운 메뉴의 스타일, 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 ×
showArrow 화살표 아이콘 표시 여부, 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 - - ×
onDropdownVisibleChange 팝업 표시/숨김 콜백, onOpenChange를 사용하세요 (value) => void - 4.17.0 ×
onOpenChange 팝업 표시/숨김 콜백 (open: boolean) => void - ×
onPopupVisibleChange 팝업 표시/숨김 콜백, 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 ×
searchValue 검색값 설정, showSearch와 함께 필요 string - 4.17.0 ×
onSearch 입력이 바뀔 때 트리거되는 콜백 함수 (search: string) => void - 4.17.0 ×
dropdownMenuColumnStyle 드롭다운 메뉴 컬럼 스타일, styles.popup.listItem을 사용하세요 CSSProperties - ×
popupMenuColumnStyle 드롭다운 메뉴 컬럼 스타일, 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)