--- localeCode: en-US order: 28 category: Input title: Select subTitle: Select icon: doc-select width: 60% brief: The user can select one or more options from a set of options through the Select selector and present the final selection result --- ## Demos ### How to import ```jsx import import { Select } from '@douyinfe/semi-ui'; const Option = Select.Option; ``` ### Basic Usage Each Option tag must declare the `value` attribute, and the Option `children` content will be rendered to the drop-down list ```jsx live=true import React from 'react'; import { Select } from '@douyinfe/semi-ui'; () => ( <>



); ``` ### Pass Option as an array You can pass an array of objects directly through `optionList`. Each object must contain the value / label attribute. ```jsx live=true import React from 'react'; import { Select } from '@douyinfe/semi-ui'; () => { const list = [ { value: 'abc', label: 'Semi' }, { value: 'hotsoon', label: 'Hotsoon' }, { value: 'pipixia', label: 'Pipixia' }, { value: 'toutiao', label: 'TooBuzz' }, ]; return ; }; ``` ### Multi-choice Configuration `multiple` properties that can support multi-selection Configuration `maxTagCount`. You can limit the number of options displayed, and the excess will be displayed in the form of + N Configuration `max` Properties can limit the maximum number of options and cannot be selected beyond the maximum limit, while triggering`On Exceed`callback ```jsx live=true import React from 'react'; import { Select } from '@douyinfe/semi-ui'; () => ( <>



); ``` ### With Group Grouping Option with `OptGroup`(Only supports the declaration of children through jsx, and does not support pass in through optionList) ```jsx live=true import React from 'react'; import { Select } from '@douyinfe/semi-ui'; () => ( ); ``` ```jsx live=true import React from 'react'; import { Select } from '@douyinfe/semi-ui'; () => { const data = [ { label: 'Asia', children: [ { value: 'a-1', label: 'China' }, { value: 'a-2', label: 'Koera' }, ], }, { label: 'Europe', children: [ { value: 'b-1', label: 'Germany' }, { value: 'b-2', label: 'France' }, ], }, { label: 'South America', children: [{ value: 'c-1', label: 'Peru' }], }, ]; return ( ); }; ``` ### Different sizes Size: small / default / large ```jsx live=true import React from 'react'; import { Select } from '@douyinfe/semi-ui'; () => ( <>



); ``` ### Different validate status validateStatus: default / warning / error ```jsx live=true import React from 'react'; import { Select } from '@douyinfe/semi-ui'; () => ( <>



); ``` ### Configure Prefix, Suffix, Clear Button - You can pass the selection box prefix through `prefix`, the selection box suffix through `suffix`, for text or React Node The left and right padding is automatically brought when the content passed in by prefix and reactix is text or Icon. If it is a custom ReactNode, the left and right padding is 0. - Whether to show the clear button is displayed by `showClear` - Whether to show the right drop-down arrow is displayed by `showArrow` ```jsx live=true import React from 'react'; import { Select } from '@douyinfe/semi-ui'; import { IconVigoLogo, IconGift } from '@douyinfe/semi-icons'; () => ( <>

); ``` ### Select with inset label By setting`insetLabel`, you can set a label for Select, you can pass in string or ReactNode When the incoming type is ReactNode, you need to handle the padding between the label and the text. ```jsx live=true import React from 'react'; import { Select } from '@douyinfe/semi-ui'; () => { const list = [ { value: 'abc', label: 'Semi' }, { value: 'capcut', label: 'Capcut' }, { value: 'xigua', label: 'BuzzVideo' }, ]; return ( <>

); }; ``` ### Additional items We have reserved two slots at the bottom of the pop-up layer, which you can use when you need to add a custom node to the pop-up layer. Use`innerTopSlot` or `outerTopSlot` to pass the custom node, which will be rendered at the top of the pop-up layer. Use`innerBottomSlot` or `outerBottomSlot` instead at the bottom. - `innerTopSlot` and `innerBottomSlot` will be rendered inside the Option List - `outerTopSlot` and `outerBottomSlot` will be rendered to level with the option List ```jsx live=true import React from 'react'; import { Select } from '@douyinfe/semi-ui'; import { IconClock } from '@douyinfe/semi-icons'; () => { let selectStyle = { width: 180, margin: 20 }; let innerSlotStyle = { backgroundColor: '#FFF', height: '40px', color: '#0077FA', display: 'flex', justifyContent: 'center', alignItems: 'center', cursor: 'pointer', }; let innerSlotNode =
No suitable product?
; let outSlotStyle = { backgroundColor: 'whitesmoke', height: '29px', display: 'flex', justifyContent: 'center', alignItems: 'center', cursor: 'pointer', }; let outSlotNode = (
More recently viewed pages
); return (

outerBottomSlot:

innerBottomSlot:

); }; ``` Using outerTopSlot to insert content ```jsx live=true import React from 'react'; import { Select } from '@douyinfe/semi-ui'; () => { const list = { component: [ { value: 'select', label: 'Select' }, { value: 'tabs', label: 'Tabs' }, { value: 'avatar', label: 'Avatar' }, { value: 'button', label: 'Button' }, ], design: [ { value: 'color', label: 'Color' }, { value: 'dark', label: 'Dark Mode' }, { value: 'icon', label: 'Icon' }, { value: 'font', label: 'Topography' }, ], feedback: [ { value: 'faq', label: 'FAQ' }, { value: 'join', label: 'Join Chat Group' }, { value: 'hornbill', label: 'Hornbill' }, ], }; const [key, setKey] = useState('component'); const [value, setValue] = useState({ value: 'faq', label: 'FAQ' },); const handleTabClick = (itemKey) => { setKey(itemKey); }; const tabStyle = { cursor: 'pointer', marginRight: 12, paddingBottom: 4, }; const tabActiveStyle = { ...tabStyle, borderBottom: '1px solid var(--semi-color-primary)', fontWeight: 700, }; const tabWrapper = { display: 'flex', paddingTop: 8, paddingLeft: 32, borderBottom: '0.5px solid var(--semi-color-border)' }; const tabOptions = [ { itemKey: 'component', label: '组件' }, { itemKey: 'design', label: '设计' }, { itemKey: 'feedback', label: '反馈' }, ]; const outerTopSlotNode = (
{ tabOptions.map((item, index) => { style = item.itemKey === key ? tabActiveStyle : tabStyle; return (
handleTabClick(item.itemKey)}>{item.label}
); }) }
); return ( Semi Capcut BuzzVideo ); }; ``` ### Linkage Select If it is a complex linkage with a hierarchical relationship, it is recommended to use Cascader components directly ```jsx live=true import React from 'react'; import { Select } from '@douyinfe/semi-ui'; class Link extends React.Component { get continents() { return ['Asia', 'Europe']; } get maps() { return { Asia: ['China', 'Korea'], Europe: ['United Kingdom', 'France', 'Germany'], }; } constructor() { super(); this.state = { continents: this.continents, maps: this.maps, countrys: this.maps[this.continents[0]], country: this.maps[this.continents[0]][0], }; this.continentsChange = this.continentsChange.bind(this); this.countryChange = this.countryChange.bind(this); } continentsChange(newContinents) { const { maps } = this.state; this.setState({ countrys: maps[newContinents], country: maps[newContinents][0] }); } countryChange(country) { this.setState({ country }); } render() { const { continents, countrys, country } = this.state; return ( ); } } ``` ### Search You can turn on the search capability by setting `filter` to true. The default search strategy will include comparison of the input value with the label value of option By default, the search keywords will be cleared automatically after multiple selection is selected. If you want to keep it, you can turn off the default behavior by setting `autoClearSearchValue` to false (provided after v2.3) ```jsx live=true import React from 'react'; import { Select } from '@douyinfe/semi-ui'; () => ( <>

); ``` ### Remote search A multi-select example with remote search, request debounce, loading status. - Use `filter` turn on the search capability. - Use `remote` to disabled local filter - Dynamic Update `optionList` after `onSearch` callback - Update `loading` when fetching data / finish - Use controlled value attribute ```jsx live=true import React from 'react'; import { debounce } from 'lodash-es'; import { Select } from '@douyinfe/semi-ui'; () => { const [loading, setLoading] = useState(false); const optionList = [ { value: 'dsm', label: 'Semi DSM', type: 1 }, { value: 'd2c', label: 'Semi DesignToCode', type: 2 }, { value: 'c2d', label: 'Semi CodeToDesign', type: 3 }, { value: 'plugin', label: 'Semi Plugin', type: 4 }, ]; const [list, setList] = useState(optionList); const [value, setValue] = useState(''); const handleMultipleChange = (newValue) => { setValue(newValue); }; const handleSearch = (inputValue) => { setLoading(true); let result = []; if (inputValue) { let length = Math.ceil(Math.random()*100); result = Array.from({ length }, (v, i) => { return { value: inputValue + i, label: `Relative: ${inputValue}${i}`, type: i + 1 }; }); setTimeout(() => { setLoading(false); setList(result); }, 1000); } else { setLoading(false); } }; return ( ); }; ``` ### Custom search strategy By default, the user's search input will be compared with the option's label value as a string include. You can set `filter` as a custom function to customize your filter strategy. ```jsx live=true import React from 'react'; import { Select } from '@douyinfe/semi-ui'; () => { function search(sugInput, option) { // Search for both label and value let label = option.label.toUpperCase(); let value = option.value.toUpperCase(); let sug = sugInput.toUpperCase(); return label.includes(sug) || value.includes(sug); } return ( ); }; ``` ### Custom selection rendering By default, the content of `option.label` or `option.children` will be backfilled into the selection box when the option is selected. But you can customize the rendering of the selection box through the `renderSelectedItem` function - Select: `renderSelectedItem(optionNode: object) => content: ReactNode` - Multiple Select: `renderSelectedItem(optionNode: object, { index: number, onClose: function }) => { isRenderInTag: boolean, content: ReactNode }` - When `isRenderInTag` is true, content will automatically wrapped in `Tag` rendering (with background color and close button) - When `isRenderInTag` is false, it renders the returned content directly ```jsx live=true import React from 'react'; import { Select, Avatar, Tag } from '@douyinfe/semi-ui'; () => { const list = [ { "name": "Keman Xia", "email": "xiakeman@example.com", "avatar": "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bag.jpeg" }, { "name": "Yue Shen", "email": "shenyue@example.com", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg" }, { "name": "Chenyi Qu", "email": "quchenyi@example.com", "avatar": "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/Viamaker.png" }, { "name": "Jiamao Wen", "email": "wenjiamao@example.com", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/6fbafc2d-e3e6-4cff-a1e2-17709c680624.png" }, ]; const renderSelectedItem = optionNode => (
{optionNode.abbr} {optionNode.email}
); // avatarSrc & avatarShape are supported after 1.6.0-beta const renderMultipleWithCustomTag = (optionNode, { onClose }) => { const content = ( {optionNode.name} ); return { isRenderInTag: false, content }; }; const renderMultipleWithCustomTag2 = (optionNode, { onClose }) => { const content = ( {optionNode.name} ); return { isRenderInTag: false, content }; }; const renderCustomOption = (item, index) => { const optionStyle = { display: 'flex', paddingLeft: 24, paddingTop: 10, paddingBottom: 10 }; return (
{item.name}
{item.email}
); }; return ( <> ); }; ``` ### Custom pop-up layer style You can control the style of the pop-up layer through `dropdownClassName`, `dropdownStyle` For example, when you customize the width of the pop-up layer, you can pass the width through `drowndownStyle` ```jsx live=true import React from 'react'; import { Select } from '@douyinfe/semi-ui'; () => ( ); ``` ### Dynamic Modification Options If you need to update Options dynamically, you should use controlled value ```jsx live=true import React from 'react'; import { Select, Button } from '@douyinfe/semi-ui'; () => { let [options, setOptions] = useState([1, 2, 3, 4]); function add() { let length = Math.ceil(Math.random() * 10); let newOptions = Array.from({ length }, (v, i) => i + 1); setOptions(newOptions); } return ( <>

); }; ``` ### Get all attribute of selected option By default, through `onChange` uou can only get value attribute of selected option. If you need to take other attributes of the selected option, you can use `onChangeWithObject` Properties At this time, the argument of `onChange` will be object, containing various attributes of selected option, eg: `onChange({ value, label, ...rest })` Note that when onChange With Object is set to true,`defaultValue`/`Value`it should also be object and must have `value` key ```jsx live=true import React from 'react'; import { Select, TextArea } from '@douyinfe/semi-ui'; () => { const list = [ { value: 'abc', label: 'Semi', type: 1 }, { value: 'capcut', label: 'Capcut', type: 2 }, { value: 'xigua', label: 'BuzzVideo', type: 3 }, ]; const [cbValue, setCbValue] = useState(); const [multipleCbValue, setMultipleCbValue] = useState(); const onChange = value => { setCbValue(value); console.log(value); }; const onMultipleChange = value => { setMultipleCbValue(value); console.log(value); }; return (

onChang callback: