Input · Select

Select

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

<script lang="ts">
    import { Select } from '@fibrae/semi-ui-svelte';
</script>

The Svelte version has no Select.Option or Select.OptGroup: the data of child components is not available in the first server render, in keyboard navigation, in filtering or in select all. The options come only from optionList, and groups are written on the group field of an entry.

Basic Usage

Write the options in optionList. Each entry must declare value, and label is the text of the option. A one-way value="douyin" only seeds the selection; use bind:value to read and write it





Code
<script lang="ts">
    import { Select } from '@fibrae/semi-ui-svelte';

    const optionList = [
        { value: 'douyin', label: '抖音' },
        { value: 'ulikecam', label: '轻颜相机' },
        { value: 'jianying', label: '剪映', disabled: true },
        { value: 'xigua', label: '西瓜视频' },
    ];
</script>

<Select aria-label="业务线" {optionList} style="width: 120px" value="douyin" />
<br />
<br />
<Select aria-label="业务线" disabled optionList={optionList.filter((option) => !option.disabled)} style="width: 120px" value="douyin" />
<br />
<br />
<Select aria-label="业务线" {optionList} placeholder="请选择业务线" style="width: 120px" />

Pass Option as an array

You can pass an array of objects directly through optionList. Each object must contain the value / label attribute.

label accepts a string or a number; option text with markup uses the optionLabel snippet, see "Custom Option Render" below.

Code
<script lang="ts">
    import { Select } from '@fibrae/semi-ui-svelte';

    const list = [
        { value: 'douyin', label: '抖音', otherKey: 0 },
        { value: 'ulikecam', label: '轻颜相机', disabled: true, otherKey: 1 },
        { value: 'jianying', label: '剪映', otherKey: 2 },
        { value: 'toutiao', label: '今日头条', otherKey: 3 },
    ];
</script>

<Select aria-label="业务线" optionList={list} placeholder="请选择业务线" style="width: 180px" />

Multi-choice

Since v2.28, the selector will have its own maxHeight 270, and the content can be viewed by scrolling vertically after it exceeds.

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

Configure ellipsisTrigger (>= v2.28.0) to do adaptive processing on the overflow part of the tag. When the width is insufficient, the last tag content will be truncated. After enabling this function, there will be a certain performance loss, and it is not recommended to use it in large form scenarios

Configure expandRestTagsOnClick (>= v2.28.0) to display all remaining tags by clicking when maxTagCount is set

Use showRestTagsPopover (>= v2.22.0) to set whether hover +N displays Popover after exceeding maxTagCount, the default is false. Also, popovers can be configured in the restTagsPopoverProps property

Configuration max Properties can limit the maximum number of options and cannot be selected beyond the maximum limit, while triggering the onExceed callback







Code
<script lang="ts">
    import { Select, Toast } from '@fibrae/semi-ui-svelte';

    const optionList = [
        { value: 'douyin', label: '抖音' },
        { value: 'ulikecam', label: '轻颜相机' },
        { value: 'jianying', label: '剪映' },
        { value: 'xigua', label: '西瓜视频' },
    ];
    const onExceed = () => Toast.warning('最多只允许选择两项');
</script>

<Select aria-label="Select 示例" multiple {optionList} style="width: 320px" value={['douyin', 'ulikecam']} />
<br />
<br />
<Select aria-label="Select 示例" maxTagCount={2} multiple {optionList} restTagsPopoverProps={{ position: 'top' }} showRestTagsPopover style="width: 320px" value={['douyin', 'ulikecam', 'jianying']} />
<br />
<br />
<Select aria-label="Select 示例" max={2} multiple {onExceed} {optionList} style="width: 320px" value={['douyin']} />
<br />
<br />
<Select aria-label="Select 示例" ellipsisTrigger expandRestTagsOnClick maxTagCount={2} multiple {optionList} restTagsPopoverProps={{ position: 'top' }} showRestTagsPopover style="width: 220px" value={['xigua', 'ulikecam', 'jianying', 'douyin']} />

With Group

Group entries by writing group: { key, label } on the optionList entries. Entries of one group must be adjacent: adjacent entries with the same key form one group, and label is the group title; a group without a label renders no title. A group renders as role="group" named by its title. While searching, a group with no visible option is hidden entirely, and a keyword that matches a group title shows all options of that group. Customize the title with the groupLabel snippet, whose parameter is { group }; without it group.label is shown. With virtualize no group titles or role="group" are rendered and the options are laid out flat in order

Code
<script lang="ts">
    import { Select } from '@fibrae/semi-ui-svelte';

    const asia = { key: 'asia', label: 'Asia' };
    const europe = { key: 'europe', label: 'Europe' };
    const southAmerica = { key: 'south-america', label: 'South America' };

    const optionList = [
        { value: 'a-1', label: 'China', group: asia },
        { value: 'a-2', label: 'Korea', group: asia },
        { value: 'b-1', label: 'Germany', group: europe },
        { value: 'b-2', label: 'France', group: europe },
        { value: 'c-1', label: 'Peru', group: southAmerica },
    ];
</script>

<Select aria-label="地区" filter {optionList} placeholder="" style="width: 180px" />
Code
<script lang="ts">
    import { Select } from '@fibrae/semi-ui-svelte';

    const data = [
        {
            label: 'Asia',
            children: [
                { value: 'a-1', label: 'China' },
                { value: 'a-2', label: 'Korea' },
            ],
        },
        {
            label: 'Europe',
            children: [
                { value: 'b-1', label: 'Germany' },
                { value: 'b-2', label: 'France' },
            ],
        },
        {
            label: 'South America',
            children: [{ value: 'c-1', label: 'Peru' }],
        },
    ];

    const optionList = data.flatMap(({ label, children }) => children.map((option) => ({ ...option, group: { key: label, label } })));
</script>

<Select aria-label="地区" filter {optionList} placeholder="" style="width: 180px">
    {#snippet groupLabel({ group })}
        <strong>{group.label}</strong>
    {/snippet}
</Select>

Different sizes

Size: small / default / large





Code
<script lang="ts">
    import { Select } from '@fibrae/semi-ui-svelte';

    const optionList = [{ value: 'ulikecam', label: '轻颜相机' }];
</script>

<Select aria-label="small" {optionList} placeholder="请选择业务线" size="small" style="width: 180px" />
<br />
<br />
<Select aria-label="default" {optionList} placeholder="请选择业务线" style="width: 180px" />
<br />
<br />
<Select aria-label="large" {optionList} placeholder="请选择业务线" size="large" style="width: 180px" />

Different validate status

validateStatus: default / warning / error





Code
<script lang="ts">
    import { Select } from '@fibrae/semi-ui-svelte';

    const optionList = [{ value: 'ulikecam', label: '轻颜相机' }];
</script>

<Select aria-label="default" {optionList} style="width: 180px" />
<br />
<br />
<Select aria-label="warning" {optionList} style="width: 180px" validateStatus="warning" />
<br />
<br />
<Select aria-label="error" {optionList} style="width: 180px" validateStatus="error" />

Configure Prefix, Suffix, Clear Button

  • You can pass the selection box prefix through the prefix snippet, the selection box suffix through the suffix snippet, for text or a node
    The left and right padding is automatically brought when the snippet content is text or Icon. If it is a custom node, 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


Code
<script lang="ts">
    import { IconGift, IconVigoLogo } from '@fibrae/semi-icons-svelte';
    import { Select } from '@fibrae/semi-ui-svelte';

    const optionList = [
        { value: 'douyin', label: '抖音' },
        { value: 'ulikecam', label: '轻颜相机' },
        { value: 'jianying', label: '剪映' },
        { value: 'xigua', label: '西瓜视频' },
    ];
</script>

<Select aria-label="Select 示例" {optionList} showClear style="width: 320px" value="ulikecam">
    {#snippet prefix()}
        <IconVigoLogo />
    {/snippet}
</Select>
<br />
<br />
<Select aria-label="Select 示例" {optionList} showArrow={false} style="width: 320px" value="ulikecam">
    {#snippet prefix()}
        <IconVigoLogo />
    {/snippet}
    {#snippet suffix()}
        <IconGift />
    {/snippet}
</Select>

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.
UseinnerTopSlot or outerTopSlot to pass the custom node, which will be rendered at the top of the pop-up layer. UseinnerBottomSlot or outerBottomSlot instead at the bottom.

In Svelte they are snippets of the same names, written as {#snippet innerBottomSlot()}...{/snippet}, and likewise for the other three.

  • innerTopSlot and innerBottomSlot will be rendered inside the Option List
  • outerTopSlot and outerBottomSlot will be rendered to level with the option List

outerBottomSlot:

innerBottomSlot:

Code
<script lang="ts">
    import { Select } from '@fibrae/semi-ui-svelte';

    const optionList = [
        { value: 'douyin', label: '抖音' },
        { value: 'ulikecam', label: '轻颜相机' },
        { value: 'jianying', label: '剪映' },
        { value: 'duoshan', label: '多闪' },
        { value: 'xigua', label: '西瓜视频' },
    ];
    const innerSlotStyle = 'background-color: var(--color-white); height: 36px; display: flex; align-items: center; cursor: pointer; padding-left: 32px; border-top: 1px solid var(--semi-color-border); border-radius: 0 0 6px 6px; color: var(--semi-color-link)';
    const outSlotStyle = 'background-color: var(--semi-color-fill-0); height: 36px; display: flex; padding-left: 32px; color: var(--semi-color-link); align-items: center; cursor: pointer; border-top: 1px solid var(--semi-color-border); border-radius: 0 0 6px 6px';
</script>

<div>
    <p>outerBottomSlot:</p>
    <Select aria-label="outerBottomSlot" autoAdjustOverflow={false} defaultOpen dropdownStyle="width: 180px" maxHeight={150} {optionList} placeholder="自定义外侧底部slot,始终显示" position="bottom" style="width: 300px">
        {#snippet outerBottomSlot()}
            <div style={outSlotStyle}>
                <span style="color: var(--semi-color-link)">未找到应用?</span>
            </div>
        {/snippet}
    </Select>
    <p style="margin-top: 200px">innerBottomSlot:</p>
    <Select aria-label="innerBottomSlot" dropdownStyle="width: 180px" maxHeight={150} {optionList} placeholder="自定义内侧底部slot,滚动至底部显示" style="width: 300px">
        {#snippet innerBottomSlot()}
            <div style={innerSlotStyle}>点击加载更多</div>
        {/snippet}
    </Select>
</div>

Using outerTopSlot to insert content

Code
<script lang="ts">
    import { RadioGroup, Select, type RadioChangeEvent, type SelectValue } from '@fibrae/semi-ui-svelte';

    interface Item {
        value: string;
        label: string;
    }

    const list: Record<string, Item[]> = {
        component: [
            { value: 'select', label: '选择器' },
            { value: 'tabs', label: '标签' },
            { value: 'avatar', label: '头像' },
            { value: 'button', label: '按钮' },
        ],
        design: [
            { value: 'color', label: '颜色' },
            { value: 'dark', label: '暗色模式' },
            { value: 'icon', label: '图标' },
            { value: 'font', label: '字体' },
        ],
        feedback: [
            { value: 'faq', label: '常见问题' },
            { value: 'join', label: '加入用户群' },
            { value: 'hornbill', label: '犀鸟反馈问题' },
        ],
    };
    const categoryOptions = [
        { value: 'component', label: '组件' },
        { value: 'design', label: '设计' },
        { value: 'feedback', label: '反馈' },
    ];

    let key = $state('component');
    let value = $state<SelectValue>({ value: 'faq', label: '常见问题' });

    const changeCategory = (event: RadioChangeEvent) => {
        key = String(event.target.value);
    };
</script>

<Select aria-label="选项" autoAdjustOverflow={false} bind:value defaultOpen onChangeWithObject optionList={list[key]} style="width: 200px">
    {#snippet outerTopSlot()}
        <!-- The radio group switches with arrow keys, so categories need no tabpanel association -->
        <div style="padding: 8px 12px; border-bottom: 0.5px solid var(--semi-color-border)">
            <RadioGroup aria-label="选项分类" buttonSize="small" onChange={changeCategory} options={categoryOptions} type="button" value={key} />
        </div>
    {/snippet}
</Select>

Controlled component

Use bind:value={x} to keep the selected value in sync both ways; with the function binding bind:value={() => x, (next) => { ... }} Select is fully controlled and the setter may reject or rewrite the value. A one-way value={x} only seeds the selection. There is no defaultValue.

Code
<script lang="ts">
    import { Select } from '@fibrae/semi-ui-svelte';

    const optionList = [
        { value: 'douyin', label: '抖音' },
        { value: 'ulikecam', label: '轻颜相机' },
        { value: 'jianying', label: '剪映' },
        { value: 'xigua', label: '西瓜视频' },
    ];

    let value = $state<string | undefined>('xigua');
</script>

<Select aria-label="业务线" bind:value {optionList} placeholder="受控的Select" style="width: 300px" />

Dynamic Modification Options

If you need to update Options dynamically, you should use bind:value, or write the value back in onChange



Code
<script lang="ts">
    import { Button, Select } from '@fibrae/semi-ui-svelte';

    let options = $state([1, 2, 3, 4]);

    const optionList = $derived(options.map((option) => ({ value: option, label: String(option) })));

    const add = () => {
        const length = Math.ceil(Math.random() * 10);
        options = Array.from({ length }, (_, i) => i + 1);
    };
</script>

<Select aria-label="数字" {optionList} placeholder="请选择" style="width: 180px" value={4} />
<br />
<br />
<Button onclick={add}>changeOptions Dynamic</Button>

Linkage Select

Use bind:value, or write the value back in onChange, to link different Selects. If it is a complex linkage with a hierarchical relationship, it is recommended to use Cascader components directly

Code
<script lang="ts">
    import { Select, type SelectValue } from '@fibrae/semi-ui-svelte';

    const provinces = ['四川', '广东'];
    const maps: Record<string, string[]> = {
        四川: ['成都', '都江堰'],
        广东: ['广州', '深圳', '东莞'],
    };

    let province = $state(provinces[0]);
    let city = $state<string | undefined>(maps[provinces[0]][0]);

    const provinceList = provinces.map((item) => ({ value: item, label: item }));
    const cityList = $derived(maps[province].map((item) => ({ value: item, label: item })));

    const changeProvince = (next: SelectValue) => {
        if (typeof next !== 'string') {
            return;
        }
        province = next;
        city = maps[next][0];
    };
</script>

<Select aria-label="省份" onChange={changeProvince} optionList={provinceList} style="width: 150px; margin: 10px" value={province} />
<Select aria-label="城市" bind:value={city} optionList={cityList} style="width: 150px; margin: 10px" />

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)

Search position

The default search input is displayed on the Select Trigger. You can specify different positions through searchPosition, and you can choose dropdown or trigger. Available after v2.61.0
If you want to customize the placeholder of the Input search box in the dropdown, you can control it through searchPlaceholder
If the searchPosition is trigger, when showClear=true, clicking the clear button of the input will clear the selected items and the search text in the input at the same time
If the searchPosition is dropdown, when showClear=true, clicking the clear button of the trigger will clear the selected items, clicking the clear button in the dropdown input will clear search text



Code
<script lang="ts">
    import { Select } from '@fibrae/semi-ui-svelte';

    const businessList = [
        { value: 'douyin', label: '抖音' },
        { value: 'ulikecam', label: '轻颜相机' },
        { value: 'jianying', label: '剪映' },
        { value: 'xigua', label: '西瓜视频' },
    ];
    const semiList = Array.from({ length: 5 }, (_, i) => ({ value: `semi-${i}`, label: `Semi-${i}` }));
</script>

<Select aria-label="单选" filter optionList={businessList} placeholder="我的搜索框在下拉菜单中" searchPlaceholder="带搜索功能的单选" searchPosition="dropdown" style="width: 200px" value="ulikecam" />
<br />
<br />
<Select aria-label="多选" autoClearSearchValue={false} filter multiple optionList={semiList} placeholder="我的搜索框在下拉菜单中" searchPlaceholder="带搜索功能的多选" searchPosition="dropdown" style="width: 300px" value={['semi-1']} />

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 bind:value, and get the keyword from onSearch; pass emptyContent={null} to hide the empty state

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.

Code
<script lang="ts">
    import { Select, type SelectOptionProps } from '@fibrae/semi-ui-svelte';

    const optionList = [
        { value: 'douyin', label: 'douyin' },
        { value: 'ulikecam', label: 'HOTSOON' },
        { value: 'jianying', label: 'PIPIXIA' },
        { value: 'xigua', label: 'XIGUA' },
    ];

    const searchLabel = (sugInput: string, option: SelectOptionProps) => {
        const label = String(option.label).toUpperCase();
        const sug = sugInput.toUpperCase();
        return label.includes(sug);
    };
</script>

<Select aria-label="业务线" filter={searchLabel} {optionList} placeholder="try douyin" style="width: 180px" />

Custom selection rendering

By default, the label of the selected option is backfilled into the selection box.
But you can customize the rendering of the selection box through snippets, whose parameters are { option, index, disabled, onClose }

  • selectedItem: in a single Select it replaces the content shown in the selection box; in a multiple Select it replaces only the content inside the built-in tag, which keeps its background color and close button
  • tag: in a multiple Select it replaces the whole tag, and takes precedence over selectedItem when both are given
  • Call onClose to remove the option; in a single Select it clears the value
  • Other fields written on the optionList entries (such as email and avatar in the demo) are passed in with option
Code
<script lang="ts">
    import { Avatar, Select, Tag, type SelectOptionProps, type SelectValue } from '@fibrae/semi-ui-svelte';

    const optionStyle = 'display: flex; padding-left: 24px; padding-top: 10px; padding-bottom: 10px';

    const list = [
        {
            name: '夏可漫',
            email: 'xiakeman@example.com',
            avatar: '/assets/placeholder/avatar-a.svg',
        },
        {
            name: '申悦',
            email: 'shenyue@example.com',
            avatar: '/assets/root-web-sites/bag.jpeg',
        },
        {
            name: '曲晨一',
            email: 'quchenyi@example.com',
            avatar: '/assets/placeholder/avatar-c.svg',
        },
        {
            name: '文嘉茂',
            email: 'wenjiamao@example.com',
            avatar: '/assets/root-web-sites/6fbafc2d-e3e6-4cff-a1e2-17709c680624.png',
        },
    ].map((item) => ({ ...item, value: item.name, label: item.name, showTick: true, style: optionStyle }));

    const onChange = (value: SelectValue) => console.log(value);
</script>

{#snippet optionLabel({ option }: { option: SelectOptionProps })}
    <Avatar alt="" size="small" src={option.avatar} />
    <div style="margin-left: 8px">
        <div style="font-size: 14px">{option.name}</div>
        <div style="color: var(--color-text-2); font-size: 12px; line-height: 16px; font-weight: normal">
            {option.email}
        </div>
    </div>
{/snippet}

<Select aria-label="单选" {onChange} {optionLabel} optionList={list} placeholder="请选择" style="width: 280px; height: 40px" value="申悦">
    {#snippet selectedItem({ option })}
        <div style="display: flex; align-items: center">
            <Avatar alt="" size="small" src={option.avatar} />
            <span style="margin-left: 8px">{option.email}</span>
        </div>
    {/snippet}
</Select>
<Select aria-label="多选圆形头像" maxTagCount={2} multiple {onChange} {optionLabel} optionList={list} placeholder="请选择" style="width: 280px; margin-top: 20px" value={['申悦', '曲晨一']}>
    {#snippet tag({ option, onClose })}
        <Tag avatarShape="circle" avatarSrc={option.avatar} closable {onClose} size="large">
            {option.name}
        </Tag>
    {/snippet}
</Select>
<Select aria-label="多选方形头像" maxTagCount={2} multiple {onChange} {optionLabel} optionList={list} placeholder="请选择" style="width: 280px; margin-top: 20px" value={['申悦', '曲晨一']}>
    {#snippet tag({ option, onClose })}
        <Tag avatarShape="square" avatarSrc={option.avatar} closable {onClose} size="large">
            {option.name}
        </Tag>
    {/snippet}
</Select>

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

Code
<script lang="ts">
    import { Select } from '@fibrae/semi-ui-svelte';

    const optionList = [
        { value: 'douyin', label: '抖音' },
        { value: 'ulikecam', label: '轻颜相机' },
        { value: 'jianying', label: '剪映' },
        { value: 'xigua', label: '西瓜视频' },
    ];
</script>

<Select aria-label="业务线" dropdownClassName="test" dropdownStyle="width: 250px" {optionList} placeholder="自定义弹出层样式的" style="width: 180px" />

Get all attribute of selected option

By default, through onChange you 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 })

onChange回调:

onChange回调:

Code
<script lang="ts">
    import { Select, TextArea, type SelectValue } from '@fibrae/semi-ui-svelte';

    interface Item {
        value: string;
        label: string;
        type: number;
    }

    const list: Item[] = [
        { value: 'douyin', label: '抖音', type: 1 },
        { value: 'ulikecam', label: '轻颜相机', type: 2 },
        { value: 'jianying', label: '剪映', type: 3 },
        { value: 'toutiao', label: '今日头条', type: 4 },
    ];

    let cbValue = $state<SelectValue>();
    let multipleCbValue = $state<SelectValue>();

    const onChange = (value: SelectValue) => {
        cbValue = value;
        console.log(value);
    };

    const onMultipleChange = (value: SelectValue) => {
        multipleCbValue = value;
        console.log(value);
    };
</script>

<div>
    <div>
        <Select aria-label="单选" {onChange} onChangeWithObject optionList={list} placeholder="单选" style="width: 150px" value={{ ...list[0] }} />
        <h4 id="select-on-change-with-object-single">onChange回调:</h4>
        <TextArea aria-labelledby="select-on-change-with-object-single" autosize rows={2} style="width: 320px; margin-bottom: 48px" value={JSON.stringify(cbValue)} />
    </div>
    <div>
        <Select aria-label="多选" multiple onChange={onMultipleChange} onChangeWithObject optionList={list} placeholder="多选" style="width: 320px" value={[]} />
        <h4 id="select-on-change-with-object-multiple">onChange回调:</h4>
        <TextArea aria-labelledby="select-on-change-with-object-multiple" autosize style="width: 320px" value={JSON.stringify(multipleCbValue)} />
    </div>
</div>

Create entries

You can create and select entries that do not exist in the options by setting allowCreate=true

You can customize the content display when creating the label through the createItem snippet (note that you need to customize the style, and with virtualization you must apply style to the custom element). Its parameter is { inputValue, focus, style }. Without it the locale text for "Create" followed by the input is shown. onCreate fires when an option is created

In addition, can be used with the defaultActiveFirstOption property to automatically select the first item. When you enter directly and press Enter, you can immediately create an Option



With createItem
Code
<script lang="ts">
    import { Select } from '@fibrae/semi-ui-svelte';

    const optionList = [
        { value: 'douyin', label: '抖音' },
        { value: 'ulikecam', label: '轻颜相机' },
        { value: 'jianying', label: '剪映' },
        { value: 'toutiao', label: '今日头条' },
    ];
</script>

<Select allowCreate aria-label="业务线" defaultActiveFirstOption filter multiple onChange={(value) => console.log(value)} {optionList} style="width: 400px" />
<br />
<br />
<Select allowCreate aria-label="业务线" defaultActiveFirstOption filter multiple onChange={(value) => console.log(value)} {optionList} placeholder="With createItem" style="width: 400px">
    {#snippet createItem({ inputValue, style })}
        <div style={`padding: 10px; ${style ?? ''}`}>Create Item:{inputValue}</div>
    {/snippet}
</Select>

Virtualize

Turn on list virtualization when passing in virtualize to optimize performance when there are a large number of Option nodes virtualize is an object containing the following values:

  • height: Option list height value, default 270 (before v2.20.8 was 300)
  • width: Option list width value, default 100%
  • itemSize: The height of each line of Option, must be passed
Code
<script lang="ts">
    import { Select } from '@fibrae/semi-ui-svelte';

    const options = Array.from({ length: 3000 }, (_, i) => ({ label: `option-${i}`, value: i }));
    const virtualize = {
        height: 270,
        width: '100%',
        itemSize: 36,
    };
</script>

<Select aria-label="virtualize" filter optionList={options} placeholder="拥有3k个Option的Select" style="width: 260px" {virtualize} />

Custom Trigger

If the default layout style of the selection box does not meet your needs, you can use the trigger snippet to customize the content of the selection box

If you want to keep the search and filter ability without rendering the Input structure yourself, you can also set searchPosition='dropdown' to put the default search box in the dropdown list

The parameters of trigger are as follows

interface SelectTriggerSnippetProps {
    value: SelectOptionProps[]; // All currently selected options
    inputValue: string; // The current search keyword
    placeholder?: string; // Select placeholder
    disabled: boolean; // Whether to disable Select
    onSearch: (inputValue: string) => void; // Updates the search keyword. Call it when the value of your custom Input changes, to synchronize the state to the Select internal. filter needs to be set too
    onClear: (event?: MouseEvent) => void; // Clears the selection. When bound to a control inside the trigger, pass the click event so that click does not reopen the dropdown
    onRemove: (option: SelectOptionProps) => void; // Removes a single selected option, which needs at least label and value
}

不同背景色的触发器



使用 circle Tag 作为触发器

Code
<script lang="ts">
    import { IconAppCenter, IconChevronDown } from '@fibrae/semi-icons-svelte';
    import { Select, Tag, type SelectValue } from '@fibrae/semi-ui-svelte';

    let valList = $state<SelectValue>(['douyin', 'ulikecam']);

    const list = [
        { value: 'douyin', label: '抖音' },
        { value: 'ulikecam', label: '轻颜相机' },
        { value: 'jianying', label: '剪映' },
        { value: 'toutiao', label: '今日头条' },
    ];
</script>

<div>
    <h4>不同背景色的触发器</h4>
    <Select aria-label="不同背景色的触发器" bind:value={valList} filter multiple optionList={list} searchPosition="dropdown" style="width: 240px">
        {#snippet trigger({ value })}
            <div style="min-width: 112px; background-color: var(--semi-color-primary-light-default); height: 32px; display: flex; align-items: center; padding-left: 12px; border-radius: 3px; color: var(--semi-color-primary)">
                <div style="font-weight: 600; flex-shrink: 0; font-size: 14px">业务线</div>
                <div style="margin: 4px; white-space: nowrap; text-overflow: ellipsis; flex-grow: 1; overflow: hidden">
                    {value.map((item) => item.label).join(' , ')}
                </div>
                <IconAppCenter style="margin-right: 8px; flex-shrink: 0" />
            </div>
        {/snippet}
    </Select>
    <br />
    <br />
    <h4>使用 circle Tag 作为触发器</h4>
    <Select aria-label="circle Tag 触发器" bind:value={valList} filter multiple optionList={list} searchPosition="dropdown" style="width: 240px; margin-top: 20px; outline: 0">
        {#snippet trigger({ value })}
            <div style="margin: 4px; white-space: nowrap; text-overflow: ellipsis; flex-grow: 1; overflow: hidden; display: flex; align-items: center">
                <Tag color="cyan" shape="circle" size="large">
                    {value.map((item) => item.label).join(' / ')}
                    {#snippet suffixIcon()}
                        <IconChevronDown />
                    {/snippet}
                </Tag>
            </div>
        {/snippet}
    </Select>
</div>

The following is a more complex example: Reusing the drag-and-sort capability of TagInput and adding sorting to Select through a custom trigger.

可对已选项拖拽重新排序的 Select

Code
<script lang="ts">
    import { Select, TagInput, type SelectValue } from '@fibrae/semi-ui-svelte';

    let valList = $state<SelectValue>(['douyin', 'ulikecam']);
    let inputVal = $state('');

    const list = [
        { value: 'douyin', label: '抖音' },
        { value: 'ulikecam', label: '轻颜相机' },
        { value: 'jianying', label: '剪映' },
        { value: 'toutiao', label: '今日头条' },
    ];

    const handleSort = (currentLabels: string[]) => {
        valList = currentLabels.flatMap((item) => list.find((i) => i.label === item)?.value ?? []);
    };
</script>

<h4>可对已选项拖拽重新排序的 Select</h4>
<Select aria-label="可拖拽排序的 Select" bind:value={valList} filter multiple optionList={list} style="width: 240px">
    {#snippet trigger({ value, onSearch })}
        <div role="presentation" onkeydown={(event) => event.stopPropagation()}>
            <TagInput
                allowDuplicates={false}
                draggable
                inputValue={inputVal}
                onChange={handleSort}
                onInputChange={(word) => {
                    onSearch(word);
                    inputVal = word;
                }}
                showClear
                value={value.map((item) => String(item.label))}
            />
        </div>
    {/snippet}
</Select>

Custom Option Render

  • Simple customization: Use the optionLabel snippet to replace only the text inside an option row; its parameter is { option }. The tick icon, the role="option" of the row, its selected and disabled states, and its click and keyboard behavior stay the same, and the content automatically brings styles such as padding, background color, etc. The label of the option is still used for search, for the trigger text and for the accessible name; the content of optionLabel does not highlight the search keyword
  • Complete customization: Through the optionItem snippet, you can completely take over the rendering of the candidates in the list, and get the relevant state values from the snippet parameters. Achieve a higher degree of freedom of structural rendering
    The parameters are { id, value, label, selected, focused, disabled, inputValue, class, style, onclick, onmouseenter } plus any other fields written on the optionList entry. Notice:
    1. The style in the parameters needs to be consumed on wrapper dom, otherwise it will not be able to be used normally in virtualization scenarios
    2. The class and onmouseenter in the parameters need to be bound on the wrapper dom, otherwise the display will be problematic when the upper and lower keyboards are operated
    3. The styles of selected, focused, disabled, etc. state need to be added by yourself, and you can get the relative boolean value from the parameters
    4. Bind the onclick in the parameters to the wrapper dom so that a click selects the option
    5. Put the id in the parameters on the wrapper dom with role="option", aria-selected and aria-disabled: the Select points aria-activedescendant at that id, so screen readers announce the option reached with the arrow keys; Select also uses this id to scroll the option into view when the dropdown opens or the arrow keys move


多选
Code
<script lang="ts">
    import { Checkbox, Highlight, Select, type SelectOptionItemSnippetProps } from '@fibrae/semi-ui-svelte';

    let inputValue = $state('');

    const optionList = [
        { value: 'douyin', label: '抖音', otherKey: 0 },
        { value: 'ulikecam', label: '轻颜相机', disabled: true, otherKey: 1 },
        { value: 'jianying', label: '剪映', otherKey: 2 },
        { value: 'toutiao', label: '今日头条', otherKey: 3 },
    ];
</script>

<!--
    Put style on the outer DOM or the virtual list breaks; add selected/focused/disabled styles from the snippet
    params; bind onmouseenter and class on the outer DOM or arrow keys display wrongly; put id there so screen
    readers announce the option the arrow keys reach
-->
{#snippet optionItem({ id, disabled, selected, label, focused, class: className, style, onclick, onmouseenter }: SelectOptionItemSnippetProps)}
    <div
        aria-disabled={disabled}
        aria-selected={selected}
        class={[
            'custom-option-render',
            {
                'custom-option-render-focused': focused,
                'custom-option-render-disabled': disabled,
                'custom-option-render-selected': selected,
            },
            className,
        ]}
        {id}
        role="option"
        {style}
        {onclick}
        {onmouseenter}
    >
        <Checkbox checked={selected} />
        <div class="option-right">
            <Highlight searchWords={[inputValue]} sourceString={String(label)} />
        </div>
    </div>
{/snippet}

<Select aria-label="单选" dropdownClassName="components-select-demo-renderOptionItem" filter onSearch={(value) => (inputValue = value)} {optionItem} {optionList} placeholder="单选" style="width: 180px" />
<br />
<br />
<Select aria-label="多选" dropdownClassName="components-select-demo-renderOptionItem" filter multiple onSearch={(value) => (inputValue = value)} {optionItem} {optionList} placeholder="多选" style="width: 320px" />
.components-select-demo-renderOptionItem {
    .custom-option-render {
        display: flex;
        font-size: 14px;
        line-height: 20px;
        word-break: break-all;
        padding-left: 12px;
        padding-right: 12px;
        padding-top: 8px;
        padding-bottom: 8px;
        color: var(--semi-color-text-0);
        position: relative;
        display: flex;
        align-items: center;
        cursor: pointer;
        box-sizing: border-box;
        .option-right {
            margin-left: 8px;
            display: inline-flex;
            align-items: center;
        }
        &:active {
            background-color: var(--semi-color-fill-1);
        }
        &-focused {
            background-color: var(--semi-color-fill-0);
        }
        &-selected {
            //font-weight: 700;
        }
        &-disabled {
            color: var(--semi-color-disabled-text);
            cursor: not-allowed;
        }
        &:first-of-type {
            margin-top: 4px;
        }
        &:last-of-type {
            margin-bottom: 4px;
        }
    }
}

API reference

Select Props

Props

PropertyDescriptionTypeDefault
allowCreateWhether options that are not in the list can be created; use it with filter.booleanfalse
arrowIconCustom dropdown arrow, a snippet.Snippet-
autoAdjustOverflowWhether the dropdown layer flips automatically when it overflows the viewport.booleantrue
autoClearSearchValueWhether the search keyword is cleared after an option is selected in multiple mode.booleantrue
autofocusWhether to focus on mount.booleanfalse
borderlessWhether the trigger has no border.booleanfalse
clearIconCustom clear button icon, a snippet.Snippet-
clickToHideWhether the dropdown list closes after an option is clicked in multiple mode.booleanfalse
createItemContent of the row that creates an option, a snippet with { inputValue, focus, style }; with virtualization apply style to the custom element.TypeSnippet<[SelectCreateItemSnippetProps]>-
defaultActiveFirstOptionWhether the first enabled option is highlighted by default.booleantrue
defaultOpenWhether the dropdown list opens on mount. Select has no controlled open state.booleanfalse
disabledWhether the component is disabled.boolean-
dropdownClassNameClass name of the dropdown layer.string-
dropdownMatchSelectWidthWhether the minimum width of the dropdown layer follows the trigger width.booleantrue
dropdownStyleStyle of the dropdown layer, a string.string-
ellipsisTriggerWhether overflowing tags adapt: when the width is short the last tag is truncated. It has a performance cost and is not recommended in large forms.booleanfalse
emptyContentContent when there are no options, a snippet; null hides the empty state.Snippet | null-
expandRestTagsOnClickWith maxTagCount, whether the collapsed tags expand while the dropdown list is open.booleanfalse
filterWhether to enable search. true compares the input case-insensitively with the option label or the group title; a function customizes the match.Typeboolean | ((inputValue: string, option: SelectOptionProps) => boolean)false
groupLabelReplaces the content of a group title, a snippet with { group } (key and label); without it group.label is shown.TypeSnippet<[SelectGroupLabelSnippetProps]>-
idid of the trigger; the option ids derive from it.string-
innerBottomSlotContent inside the bottom of the option list, a snippet; visible when the list is scrolled to the bottom.Snippet-
innerTopSlotContent inside the top of the option list, a snippet; visible when the list is scrolled to the top.Snippet-
inputPropsExtra props of the search Input; class and style land on the Input wrapper.SelectInputProps-
insetLabelInset label, a snippet. Rendered without a prefix, and the name source of the combobox.Snippet-
insetLabelIdid of the inset label container, for aria-labelledby; when left out and insetLabel is rendered, one is generated.string-
loadingWhether the options are loading; the dropdown list shows a spinner instead of the options.booleanfalse
maxMaximum number of selected options in multiple mode; onExceed fires beyond it.number-
maxHeightMaximum height of the dropdown list.string | number270
maxTagCountMaximum number of tags shown in multiple mode; the rest are shown as +N.number-
motionWhether the dropdown layer animates.booleantrue
multipleWhether multiple options can be selected.booleanfalse
onBlurCalled once when the focus leaves the Select; a press outside the open dropdown passes its mousedown event.Type(event: FocusEvent | MouseEvent) => void-
onChangeCalled when the selection changes, with the new value (option objects with onChangeWithObject).Type(value: SelectValue) => void-
onChangeWithObjectWhether onChange and value carry option objects instead of option values.booleanfalse
onClearCalled when the clear button is clicked.Type() => void-
onCreateCalled when an option is created.Type(option: SelectOptionProps) => void-
onDeselectCalled when an option is deselected in multiple mode.Type(value: string | number, option: SelectOptionProps) => void-
onDropdownVisibleChangeCalled when the dropdown list opens or closes.Type(visible: boolean) => void-
onExceedCalled when the selection would exceed max.Type(option: SelectOptionProps) => void-
onFocusCalled once when the focus enters the Select.Type(event: FocusEvent) => void-
onListScrollCalled when the dropdown list scrolls.Type(event: Event) => void-
onSearchCalled when the search keyword changes; there is no event when it comes from search() or the onSearch of the trigger snippet.Type(value: string, event?: Event) => void-
onSelectCalled when an option is selected.Type(value: string | number, option: SelectOptionProps) => void-
optionItemReplaces a whole option row, a snippet. Its parameter has id, value, label, selected, focused, disabled, inputValue, class, style, onclick, onmouseenter and the other fields of the entry. Put id on the element with role="option".TypeSnippet<[SelectOptionItemSnippetProps]>-
optionLabelReplaces only the text inside an option row, a snippet with { option }. The tick icon, the role="option" of the row, its states and keyboard behavior stay; label still serves search and the accessible name, and the search keyword is not highlighted in the content.TypeSnippet<[SelectOptionLabelSnippetProps]>-
optionListThe option data. An entry has value, label, disabled, showTick, class, style and an optional group: { key, label }; other fields travel with the option record. Entries of one group must be adjacent.SelectOptionProps[]-
outerBottomSlotContent at the bottom of the dropdown layer, level with the option list, a snippet; always visible while the list scrolls.Snippet-
outerTopSlotContent at the top of the dropdown layer, level with the option list, a snippet; always visible while the list scrolls.Snippet-
placeholderPlaceholder while nothing is selected.string-
positionPlacement of the dropdown layer relative to the trigger.Position-
prefixPrefix of the selection box, a snippet. The side padding is added when the content is text or an Icon.Snippet-
preventScrollWhether focusing stops the browser from scrolling the element into view.boolean-
remoteWhether the search is remote. When on, the options are not filtered locally and the caller updates optionList.booleanfalse
restTagsPopoverPropsPopover props of the +N popover.PopoverProps-
searchPlaceholderPlaceholder of the search input when it is in the dropdown list (searchPosition="dropdown").string-
searchPositionWhere the search input sits: trigger or dropdown.'trigger' | 'dropdown'"trigger"
selectedItemThe selected content, a snippet with { option, index, disabled, onClose }. In single mode it replaces the selection box content, in multiple mode the content of each tag.TypeSnippet<[SelectSelectedItemSnippetProps]>-
showArrowWhether to show the dropdown arrow.booleantrue
showClearWhether to show the clear button.booleanfalse
showRestTagsPopoverWhether hovering +N shows the remaining tags in a Popover once maxTagCount is exceeded.booleanfalse
sizeSize: small, default or large.SelectSize-
spacingGap between the dropdown layer and the trigger.number | { x: number; y: number }-
stopPropagationWhether clicks inside the dropdown layer are stopped from bubbling out.booleantrue
suffixSuffix of the selection box, a snippet. The side padding is added when the content is text or an Icon.Snippet-
tagReplaces each tag in multiple mode, a snippet with the parameters of selectedItem; it takes precedence over selectedItem.TypeSnippet<[SelectSelectedItemSnippetProps]>-
triggerReplaces the trigger content, a snippet with { value, inputValue, placeholder, disabled, onSearch, onClear, onRemove }.TypeSnippet<[SelectTriggerSnippetProps]>-
validateStatusValidation status: default, warning or error; it only affects styles such as the background color.ValidateStatus-
valueThe selected value, supports bind:value. A single value in single mode, an array in multiple mode, and option objects with onChangeWithObject. Left out, the component manages it; a one-way value={x} only seeds it, and for a fully controlled Select use the function binding bind:value={get, set}. Binding it to undefined clears the selection. There is no defaultValue.SelectValue-
virtualizeTurns on list virtualization; itemSize is required. Group titles and role="group" are not rendered with it, and the options are laid out flat in order.SelectVirtualize-

Methods

MethodDescriptionType
clearInputClears the value of the search input.Type() => void
closeCloses the dropdown list.Type() => void
deselectAllClears all selected options.Type() => void
focusFocuses the trigger, or the search input with the dropdown list opened when searchable.Type() => void
openOpens the dropdown list.Type() => void
rePositionRecomputes the dropdown position from the trigger's current position at once; rarely needed.Type() => void
searchSearches as if the keyword were typed into the search input.Type(keyword: string, event?: Event) => void
selectAllSelects every shown, enabled option; multiple mode only.Type() => void

class, style, data-* and native attributes and listeners land on the root element, and style does not reach the dropdown popup (use dropdownStyle); with trigger the root no longer carries the style classes of Select itself. aria-label, aria-labelledby, aria-describedby, aria-errormessage, aria-invalid and aria-required land on the combobox; once the search input is mounted it is the combobox, and these attributes move to it.

Option Props

An option is identified by its value, which should not repeat within one Select; labels may repeat

The Svelte version has no Select.Option child component: an option is an optionList entry, with the fields below. class, style and data-* land on the option row; other fields never reach the DOM and travel with the option record to onSelect, onDeselect, selectedItem, tag, optionItem and optionLabel, and to onChange once onChangeWithObject is on.

FieldInstructionsTypeDefault
valueThe value of the option, which identifies itstring | number-
labelThe text of the option, used for display, search and callbacksstring | number-
disabledWhether the option is disabledbooleanfalse
showTickWhether to show the tick icon when selectedbooleantrue
groupThe group of the option; entries of one group must be adjacent, and a group without a label renders no title{ key: string | number; label?: string | number }-
classClass of the option rowClassValue-
styleStyle of the option row, a stringstring-

OptGroup Props

The Svelte version has no Select.OptGroup: groups are written on the group field of the optionList entries (see "With Group" above), and the group title is customized with the groupLabel snippet. The title element carries x-semi-prop="groupLabel".

Methods

Get the component instance of Select through bind:this and call the methods below:

MethodInstructions
open()Manually open dropdown list
close()Manually close dropdown list
focus()Manually focus: a searchable Select focuses the search input and opens the dropdown list, otherwise it focuses the trigger without opening
clearInput()Manually clear value of the search input
selectAll()Select every shown, enabled option; multiple mode only
deselectAll()Manually clear selected options
search(value: string, event?: Event)Searches as if the value were typed into the search input, and the value is set to the input; without an event, the second parameter of onSearch is undefined
rePosition()Recomputes the dropdown position from the trigger's current position at once; the dropdown already follows scrolling, window resizing, trigger moves and size changes of the trigger or list, so this is rarely needed; following a trigger move lands a frame late, so call this to align within the same frame
<script lang="ts">
    import { Select } from '@fibrae/semi-ui-svelte';

    let select = $state<Select>();
</script>

<Select bind:this={select} />
<button onclick={() => select?.open()}>Open</button>

Accessibility

ARIA

  • Following the ARIA 1.2 combobox pattern, exactly one element is the combobox at any time; the popup layer is a listbox and each option an option:
    • Without search, or with the search input in the dropdown (searchPosition="dropdown"), the Select trigger is a select-only combobox and the selected content is its value
    • With the search input in the trigger, the input itself is the combobox, with aria-autocomplete="list", and the trigger has no role and no Tab stop. In single mode the input appears only while searching, so the trigger is the combobox otherwise; the input is empty until the user types, so the selected text is linked to it as its description with aria-describedby. In multiple mode the input is always there
    • A search input in the dropdown stays a text box with aria-controls, aria-autocomplete and aria-activedescendant, named like the combobox
  • The combobox takes its name from, in order: aria-labelledby, aria-label, the rendered insetLabel (the combobox's aria-labelledby points at it, with an id the component generates when insetLabelId is not given; with a prefix the insetLabel is not rendered and does not name it), and otherwise "Select" from the locale. Pass a name that matches the form label. The listbox and a search input in the dropdown use the same name source, never the combobox itself. The selected content is the value of the combobox and is not part of the name
  • The combobox has aria-haspopup, aria-expanded, and aria-controls properties, indicating its relationship with the popup layer
  • When multiple selections are made, listbox aria-multiselectable is true, indicating that multiple selections are currently available
  • aria-selected is true when Option is selected; aria-disabled is true when Option is disabled
  • The options of a group with a label (Select.OptGroup, or group of optionList in Svelte) sit in a role="group" named by the group title (aria-labelledby), so screen readers announce the group of an option; a virtualized list shows no group titles and has no groups
  • While the dropdown is open, aria-activedescendant points at the option focused from the keyboard, which ensures that it is recognized when the narration is spoken; with a fully custom option rendering, put the id from the parameters on the option element (for more information, please refer to Managing Focus in Composites Using aria-activedescendant)

Keyboard and Focus

Select without Filter, or with the search box in the dropdown (searchPosition="dropdown"):

  • After Select is focused, keyboard users can open the dropdown menu with Space, Up Arrow, Down Arrow (including Alt + Down Arrow) or Enter. With a selected value the focus goes to the first selected option, so pressing Enter right away keeps the value; without one the current highlight stays, starting on the first enabled option (defaultActiveFirstOption defaults to true)
  • Home and End open the dropdown menu and move the focus to the first and the last enabled option
  • Typing a character opens the dropdown menu and moves the focus to the next option that starts with it; characters typed in quick succession match as a whole, and typing the same character again cycles through the options that start with it
  • When the dropdown menu is open:
    • Use Esc key or Tab key to close the menu
    • Use Up Arrow or Down Arrow to toggle options, Home and End to move to either end, and a typed character to move to an option that starts with it
    • Enter or Space selects the focused option: a single Select selects it and collapses the panel, a multiple Select toggles it and stays open. While characters are being typed in quick succession, Space joins the search string instead of selecting. With the focus in the search box inside the dropdown, Home, End, Space and characters edit the search text without moving the option focus
  • In a multiple Select with the focus on a selected tag, keys act on the tag only: Backspace and Delete remove it, and Enter and Space neither open the dropdown menu nor change the value
  • When the focus is on the dropdown menu and the user uses an innerBottomSlot or outerBottomSlot attribute with a custom slot with an interactive element:
    • You can use the Tab key to switch to these interactive elements
    • When the focus is on the first interactive element of the custom slot, use Shift + Tab to return the focus to the Select box

Select with Filter function:

  • When Select is focused, keyboard users can open dropdown menus with Up Arrow or Down Arrow or Enter keys. At this point, the focus is still on the Select box, the user can enter content, and can also use the up arrow or down arrow to switch options
  • When the dropdown menu is open: Up Arrow and Down Arrow switch options; Enter selects the focused option, collapsing the panel in a single Select and toggling it while staying open in a multiple Select; Esc or Tab closes the menu. Home, End, Space and characters belong to the input in the Select box and edit the search text without moving the option focus
  • When the focus is on the Select box, and the user uses an innerBottomSlot or outerBottomSlot property with a custom slot with an interactive element:
    • You can use the Tab key to switch to these interactive elements
    • When the focus is on the first interactive element of the custom slot, use Shift + Tab to return the focus to the Select box

Clear button:

  • With showClear, a selected value or search text, and no disabled, the trigger renders a clear button. It is a native button named "Clear selection" from the locale, shown on hover, while the dropdown is open, or while focus is inside the Select
  • From the Select box, Tab moves to the clear button; Enter or Space clears, as a mouse click does, and the focus goes back to the Select box

Content Guidelines

  • Selector trigger
    • Describe in 1-3 words the input that the user needs to make
    • Use statement writing conventions (first letter uppercase, rest lowercase)
    • Avoid punctuation and prepositions ("the", "an", "a")
    • Labels need to be independent statements. Don't let the label be the first half of the statement and the option the second half of the statement.
    • Use descriptive sentences, not indicative ones. Help text is available under the select box if the option needs more explanation.
  • Selector options
    • If there is no default option, use "Select" as placeholder copy
    • Options should be in alphabetical order or other logical order to make it easier for users to find options
    • Use statement writing conventions (first letter uppercase, rest lowercase), avoid commas and semicolons at the end of sentences
    • Clearly articulate the purpose of the choice indicated by the option

Design Tokens

These are the component's internal Sass variables and cannot be overridden. To customize styles, override the --semi-* CSS variables (see the Design Token page) or write unlayered CSS rules.
Sass variableValueUsage
$transition_duration-select-bgvar(--semi-transition_duration-none)选择器-背景色-动画持续时间
$transition_function-select-bgvar(--semi-transition_function-easeIn)选择器-背景色-过渡曲线
$transition_delay-select-bgvar(--semi-transition_delay-none)选择器-背景色-延迟时间
$transition_duration-select-bordervar(--semi-transition_duration-none)选择器-边框-动画持续时间
$transition_function-select-bordervar(--semi-transition_function-easeIn)选择器-边框-过渡曲线
$transition_delay-select-bordervar(--semi-transition_delay-none)选择器-边框-延迟时间
$transition_duration-select_option-bgvar(--semi-transition_duration-none)选择器-选项-动画持续时间
$transition_function-select_option-bgvar(--semi-transition_function-easeIn)选择器-选项-过渡曲线
$transition_delay-select_option-bgvar(--semi-transition_delay-none)选择器-选项-延迟时间
$transform_scale-selectvar(--semi-transform_scale-none)选择框-变大
$transform_rotate-select-arrowvar(--semi-transform_rotate-none)选择框-箭头-旋转
$color-select-bg-defaultvar(--semi-color-fill-0)选择器输入框背景色 - 默认态
$color-select-bg-hovervar(--semi-color-fill-1)选择器输入框背景色 - 悬停态
$color-select-bg-activevar(--semi-color-fill-2)选择器输入框背景色 - 按下态
$color-select-bg-focusvar(--semi-color-fill-0)选择器输入框背景色 - 聚焦态
$color-select-border-defaulttransparent选择器输入框描边颜色
$color-select-border-hover$color-select-border-default选择器输入框描边颜色 - 悬浮
$color-select-border-activevar(--semi-color-focus-border)选择器输入框描边颜色 - 按下态
$color-select-border-focus$color-select-border-active选择器输入框描边颜色 - 选中态
$color-select_dropdown_input-border$color-select-border-default下拉搜索框底部描边颜色
$color-select_warning-bg-defaultvar(--semi-color-warning-light-default)警示选择器输入框背景色 - 默认态
$color-select_warning-border-defaultvar(--semi-color-warning-light-default)警示选择器输入框描边颜色 - 默认态
$color-select_warning-bg-hovervar(--semi-color-warning-light-hover)警示选择器输入框背景色 - 悬停态
$color-select_warning-border-hovervar(--semi-color-warning-light-hover)警示选择器输入框描边颜色 - 悬停态
$color-select_warning-bg-focusvar(--semi-color-warning-light-default)警示选择器输入框背景色 - 选中态
$color-select_warning-border-focusvar(--semi-color-warning)警示选择器输入框描边颜色 - 选中态
$color-select_warning-bg-activevar(--semi-color-warning-light-active)警示选择器输入框背景色 - 按下态
$color-select_warning-border-activevar(--semi-color-warning-light-active)警示选择器输入框描边颜色 - 按下态
$color-select_danger-bg-defaultvar(--semi-color-danger-light-default)报错选择器输入框背景色 - 默认态
$color-select_danger-border-defaultvar(--semi-color-danger-light-default)报错选择器输入框描边颜色 - 默认态
$color-select_danger-bg-hovervar(--semi-color-danger-light-hover)报错选择器输入框背景色 - 悬停态
$color-select_danger-border-hovervar(--semi-color-danger-light-hover)报错选择器输入框描边颜色 - 悬停态
$color-select_danger-bg-focusvar(--semi-color-danger-light-default)报错选择器输入框背景色 - 选中态
$color-select_danger-border-focusvar(--semi-color-danger)报错选择器输入框描边颜色 - 选中态
$color-select_danger-bg-activevar(--semi-color-danger-light-active)报错选择器输入框背景色 - 按下态
$color-select_danger-border-activevar(--semi-color-danger-light-active)报错选择器输入框描边颜色 - 按下态
$color-select_default-border-focusvar(--semi-color-focus-border)默认选择器输入框描边颜色 - 选中态
$color-select_main-text-defaultvar(--semi-color-text-0)选择器输入框回填内容文本颜色
$color-select-icon-defaultvar(--semi-color-text-2)选择器输入框图标颜色
$color-select_clearBtn-text-defaultvar(--semi-color-text-2)选择器输入框清空按钮颜色 - 默认态
$color-select_clearBtn-text-hovervar(--semi-color-primary)选择器输入框清空按钮颜色 - 悬停态
$color-select_input_disabled-bgvar(--semi-color-disabled-fill)禁用选择器输入框背景色
$color-select_input_disabled-border-focustransparent禁用选择器输入框描边颜色 - 聚焦态
$color-select_input_disabled-textvar(--semi-color-disabled-text)禁用选择器输入框回填内容文字颜色
$color-select_input_disabled-bg-hovervar(--semi-color-disabled-fill)禁用选择器输入框背景色 - 悬停态
$color-select_input_disabled-bg-focusvar(--semi-color-disabled-fill)禁用选择器输入框背景色 - 聚焦态
$color-select_input_placeholder-textvar(--semi-color-text-2)选择器输入框占位文本文字颜色
$color-select_option_main-textvar(--semi-color-text-0)选择器下拉菜单选项文本颜色
$color-select_option_keyword-textvar(--semi-color-primary)选择器下拉菜单选项匹配搜索结果文本颜色
$color-select_option-icon-defaulttransparent选择器下拉菜单选项图标颜色 - 默认态
$color-select_option-bg-hovervar(--semi-color-fill-0)选择器下拉菜单选项背景颜色 - 悬停态
$color-select_option-bg-activevar(--semi-color-fill-1)选择器下拉菜单选项背景颜色 - 按下态
$color-select_option_disabled-textvar(--semi-color-disabled-text)禁用选择器下拉菜单选项文字颜色
$color-select_option-icon-activevar(--semi-color-text-2)选择器下拉菜单选项图标颜色 - 选中态
$color-select_option-border-defaultvar(--semi-color-border)选择器下拉菜单分组标题分割线颜色
$color-select-option-bg-selectedtransparent选择器下拉菜单选项背景颜色 - 选中态
$color-select_create_tips-textvar(--semi-color-text-2)选择器下拉菜单新建选项提示文本颜色
$color-select_group-textvar(--semi-color-text-2)选择器下拉菜单分组标题文本颜色
$color-select_prefix_suffix_text-defaultvar(--semi-color-text-2)选择器输入框前后缀文本颜色
$height-select_large$height-control-large选择器输入框高度 - 大尺寸
$height-select_small$height-control-small选择器输入框高度 - 小尺寸
$height-select_default$height-control-default选择器输入框高度 - 默认尺寸
$width-select_option_tick$width-icon-small选择器下拉菜单项选中对勾图标大小
$width-select-border1px选择器输入框描边宽度
$width-select_arrow32px选择器输入框下拉箭头宽度
$width-select_arrow_empty12px选择器输入框下拉箭头为空时(有suffix icon)宽度
$width-select_clear-icon32px选择器输入框清空按钮宽度
$width-select_group_top-border$border-thickness-control选择器下拉菜单分组标题描边宽度
$height-select_multiple_input_small20px小尺寸多项选择器输入框Input框高度
$height-select_multiple_input_default24px默认多项选择器输入框Input框高度
$height-select_multiple_input_large24px大尺寸多项选择器输入框Input框高度
$width-select-border-hover$width-select-border选择器输入框描边宽度 - 悬浮
$width-select-border-focus$width-select-border-hover选择器输入框描边宽度 - 按下
$width-select-border-active$width-select-border-focus选择器输入框描边宽度 - 选中
$spacing-select_option_tick-marginRight$spacing-tight选择器下拉菜单选中对勾右侧外边距
$spacing-select_prefix_suffix_text-marginX$spacing-base-tight选择器输入框前后缀文本水平内边距
$spacing-select_prefix_suffix_text-marginY0px选择器输入框前后缀文本垂直内边距
$spacing-select_prefix_suffix_icon-marginX$spacing-tight选择器输入框前后缀图标水平内边距
$spacing-select_prefix_suffix_icon-marginY0px选择器输入框前后缀图标垂直内边距
$spacing-select_create_tips-marginRight$spacing-extra-tight创建新选项右侧外边距
$spacing-select_group-marginTop$spacing-extra-tight选择器下拉菜单分组标题顶部外边距
$spacing-select_group-paddingTop$spacing-base-tight选择器下拉菜单分组标题顶部内边距
$spacing-select_group-paddingBottom$spacing-extra-tight选择器下拉菜单分组标题底部内边距
$spacing-select_group-paddingLeft$spacing-base-tight + $width-select_option_tick + $spacing-select_option_tick-marginRight选择器下拉菜单分组标题左侧内边距
$spacing-select_group-paddingRight$spacing-base选择器下拉菜单分组标题右侧内边距
$spacing-select_loading_wrapper-paddingLeft$spacing-base选择器加载左侧内边距
$spacing-select_loading_wrapper-paddingRight$spacing-base选择器加载右侧内边距
$spacing-select_loading_wrapper-paddingTop$spacing-tight选择器加载顶部内边距
$spacing-select_loading_wrapper-paddingBottom$spacing-tight选择器加载底部内边距
$spacing-select_multiple_content_wrapper_empty-marginLeft$spacing-tight多项选择器空回填内容为空时左侧内边距
$spacing-select_multiple_selection-marginLeft$spacing-extra-tight多项选择器回填内容左侧内边距
$spacing-select_option-paddingLeft$spacing-base-tight选择器下拉菜单项左侧内边距
$spacing-select_option-paddingRight$spacing-base-tight选择器下拉菜单项右侧内边距
$spacing-select_option-paddingTop$spacing-tight选择器下拉菜单项顶部内边距
$spacing-select_option-paddingBottom$spacing-tight选择器下拉菜单项底部内边距
$spacing-select_tag-marginTop$spacing-super-tight - 1px多项选择器标签顶部外边距
$spacing-select_tag-marginRight$spacing-extra-tight多项选择器标签右侧外边距
$spacing-select_tag-marginBottom$spacing-super-tight - 1px多项选择器标签底部外边距
$spacing-select_selection-marginLeft$spacing-base-tight选择器内容区左侧外边距
$spacing-select_option_list-paddingTop$spacing-extra-tight选择器内容区顶部内边距
$spacing-select_option_list-paddingRight0px选择器内容区右侧内边距
$spacing-select_option_list-paddingBottom$spacing-extra-tight选择器内容区底部内边距
$spacing-select_option_list-paddingLeft0px选择器内容区左侧内边距
$spacing-select_dropdown_input_paddingTop8px下拉搜索框顶部内边距
$spacing-select_dropdown_input_paddingBottom8px下拉搜索框底部内边距
$spacing-select_dropdown_input_paddingRight12px下拉搜索框右侧内边距
$spacing-select_dropdown_input_paddingLeft12px下拉搜索框左侧内边距
$radius-selectvar(--semi-border-radius-small)选择器输入框圆角
$radius-select_option0px选择器待选项圆角
$font-select-fontWeight$font-weight-regular选择器文本字重
$font-select_keyword-fontWeight600选择器搜索结果命关键词中文本字重
$font-select_prefix_suffix-fontWeight$font-weight-bold选择器输入框前后缀文本字重
$opacity-select_selection_text_inactive0.4

TypeScript Generic Support

FAQ

  • Searchable Select, using remote data to dynamically update the optionList, why sometimes there is no data before the asynchronous request is completed?
    Please check whether remote is turned on. If remote is not turned on, the input value of the input box will be compared with the current optionList by default. If there is no match, no data will be displayed.
    You can turn off matching filtering on the current local data by turning on remote.

  • Will Select automatically limit the width of the drop-down menu?
    MinWidth will be given, but width will not be written dead. If necessary, you can add it yourself through dropdownStyle.

  • Why is the blur event not fired after a radio selection option?

    Before V2.17.0, after Select radio is selected, the blur event of Select will be triggered. After V2.17.0, Select has added A11y support, which will not trigger Select's blur event. In single-selection selection, the Select floating layer is closed, and the focus is still on the trigger (at this time, the Select floating layer can be opened again by pressing the Enter key) No matter single selection or multiple selection, press Esc, only the Select floating layer is closed, and the trigger keeps the focus (the Select floating layer can be opened again by pressing the Enter key at this time)