@douyinfe/semi-ui
Version:
A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.
455 lines (371 loc) • 17.6 kB
Markdown
---
localeCode: en-US
order: 49
category: Input
title: TagInput
subTitle: TagInput
icon: doc-tagInput
brief: Taginput is a input component that can add content as a tag.
---
```jsx import
import { TagInput } from '@douyinfe/semi-ui';
```
After pressing the Enter key, the input will add value as a tag. If the tag content is an empty string or pure space, it will be filtered.
```jsx live=true
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
<TagInput
defaultValue={['Semi', 'Design', 'Design2Code']}
placeholder='Please enter...'
onChange={v => console.log(v)}
/>
);
```
You can use `separator` to set the separator to achieve batch input, and its default value is a comma. Multiple separators are supported in string[] format.
```jsx live=true
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
<>
<TagInput
separator='-'
placeholder='Use `-` for batch input'
onChange={v => console.log(v)}
/>
<br/><br/>
<TagInput
separator={['-', '/', '|', '++']}
placeholder='Support multiple separators for batch input'
onChange={v => console.log(v)}
/>
</>
);
```
You can also use `showClear` to set whether to support one-click deletion of all tags and input.
```jsx live=true
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
<TagInput
showClear
defaultValue={['Semi', 'Design2Code']}
placeholder='Please enter...'
onChange={v => console.log(v)}
/>
);
```
```jsx live=true
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
<TagInput
disabled
showClear
defaultValue={['Semi', 'Design2Code']}
placeholder='Please enter...'
/>
);
```
Use `size` to set the size of the TagInput, optional: `small`, `default`, `large`.
```jsx live=true
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
<>
<TagInput size='small' placeholder='small'/>
<br/><br/>
<TagInput placeholder='default'/>
<br/><br/>
<TagInput size='large' placeholder='large'/>
</>
);
```
validateStatus: `default`, `warning`, `error`.
```jsx live=true
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
<>
<TagInput placeholder='default'/>
<br/><br/>
<TagInput placeholder='warning' validateStatus='warning'/>
<br/><br/>
<TagInput placeholder='error' validateStatus='error'/>
</>
);
```
You can pass the input box prefix through `prefix`, the input 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.If necessary, you can set it in the ReactNode you passed in.
```jsx live=true
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
import { IconVigoLogo, IconGift } from '@douyinfe/semi-icons';
() => (
<>
<TagInput prefix={<IconVigoLogo />} showClear/>
<br/><br/>
<TagInput prefix="Prefix" showClear/>
<br/><br/>
<TagInput suffix={<IconGift />}/>
<br/><br/>
<TagInput suffix="Suffix" showClear/>
</>
);
```
You can use `allowDuplicates` to set whether to allow the creation of the same tag.
```jsx live=true
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
<TagInput
allowDuplicates={false}
defaultValue={['Semi', 'Design', 'Design2Code']}
placeholder='Please enter...'
onChange={v => console.log(v)}
/>
);
```
You can use `addOnBlur` to set whether the current input value is automatically created as a tag when the blur event is triggered.
```jsx live=true
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
<TagInput
addOnBlur={true}
defaultValue={['Semi', 'Design', 'Design2Code']}
placeholder='Please enter...'
onChange={v => console.log(v)}
/>
);
```
You can use `max` to limit the number of tags. The `onExceed()` callback will be invoked when the limit is exceeded.
You can use `maxLength` to limit the maximum length of a single tag, and the `onInputExceed()` callback will be invoked when this value is exceeded.
```jsx live=true
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
<>
<TagInput
max={3}
placeholder='max = 3'
onChange={v => console.log(v)}
onExceed={v => {
Toast.warning('Exceeds max');
console.log(v);
}}
/>
<TagInput
maxLength={5}
placeholder='maxLength = 5'
style={{ marginTop: 12 }}
onChange={v => console.log(v)}
onInputExceed={v => {
Toast.warning('Exceeds maxLength');
console.log(v);
}}
/>
</>
);
```
You can use `maxTagCount` to limit the number of tags displayed, and the excess will be displayed as +N. You can use `showRestTagsPopover` to set whether hover +N displays Popover after `maxTagCount` is exceeded, and you can configure Popover in the `restTagsPopoverProps` property.
```jsx live=true
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
<TagInput
maxTagCount={2}
showRestTagsPopover={true}
restTagsPopoverProps={{ position: 'top' }}
defaultValue={['Semi', 'Design', 'Design2Code']}
/>
);
```
You can use `value` to set tags, and use `onChange` to achieve control of the tags.
```jsx live=true
import React, { useCallback, useState } from 'react';
import { TagInput } from '@douyinfe/semi-ui';
function TagInputDemo() {
const [value, setValue] = useState(['semi']);
const handleChange = useCallback(v => setValue(v), []);
return <TagInput value={value} onChange={handleChange} />;
}
```
You can use `inputValue` to set input box, and use `onInputChange` to control the input content.
```jsx live=true
import React, { useCallback, useState } from 'react';
import { TagInput } from '@douyinfe/semi-ui';
function TagInputDemo() {
const [value, setValue] = useState('semi');
const handleInputChange = useCallback((v, e) => setValue(v), []);
return <TagInput inputValue={value} onInputChange={handleInputChange} />;
}
```
```jsx live=true
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
<TagInput
defaultValue={['Semi', 'Design2Code']}
showClear
onFocus={e =>{console.log(`onFocus`);}}
onBlur={e=>{console.log(`onBlur`);}}
onChange={tag=>{console.log(`onChange :${tag}`);}}
onAdd={tag=>{console.log(`onAdd :${tag}`);}}
onRemove={(v, i)=>{console.log(`onRemove :${v}, index:${i}`);}}
onInputChange={(input, e)=>{console.log(`onInputChange :${input}`);}}
/>
);
```
You can use the `blur()` and `focus()` methods to manage the focus.
```jsx live=true
import React, { useCallback, useRef } from 'react';
import { TagInput, Button } from '@douyinfe/semi-ui';
function TagInputDemo() {
const ref = useRef();
const handleTagInputFocus = useCallback(() => {
ref.current && ref.current.focus();
}, []);
return (
<>
<TagInput defaultValue={['Semi', 'Design2Code']} ref={ref} />
<Button style={{ marginTop: 10 }} onClick={handleTagInputFocus}>
focus
</Button>
</>
);
}
```
You can use `renderTagItem` to customize tag rendering. `renderTagItem(value: string, index: number, onClose: function ) => React.ReactNode` The third parameter `onClose` is available since version 2.23.0.
```jsx live=true
import React, { useCallback, useMemo, useState } from 'react';
import { TagInput, Avatar } from '@douyinfe/semi-ui';
import { IconClose } from '@douyinfe/semi-ui-icons';
function CustomRender() {
const [value, setValue] = useState(['xiakeman']);
const list = useMemo(() => ([
{ "name": "xiakeman", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg" },
{ "name": "shenyue", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg" },
{ "name": "quchenyi", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg" },
{ "name": "wenjiamao", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/7abf810ff060ac3387bd027ead92c4e0.jpg" },
]), []);
const mapList = useMemo(() => new Map(list.map(item => [item.name, item])), [list]);
const renderTagItem = useCallback((value, index, onClose) => {
const data = mapList.get(value);
return (
<div
key={index}
style={{ display: 'flex', alignItems: 'center', fontSize: 14, marginRight: 10 }}
>
<Avatar
alt='avatar'
src={data ? data.avatar : 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dy.png'}
size="extra-small"
/>
<span style={{ marginLeft: 8 }}>
{`${value}@semi.com`}
</span>
<IconClose onClick={onClose} />
</div>
);
}, [mapList]);
return (
<TagInput
value={value}
onChange={setValue}
renderTagItem={renderTagItem}
/>
);
}
```
Set `draggable` to true to enable drag and drop sorting. Supported since v2.17.0. Adding the same Tag is not allowed under drag and drop sorting,
so you need to set `allowDuplicates` to false. After the drag function is enabled, click TagInput, and the Tag can be dragged. Click anywhere
outside the TagInput, the Tag cannot be dragged.
```jsx live=true
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
<TagInput
draggable
allowDuplicates={false}
defaultValue={['Semi', 'Design', 'Design2Code']}
placeholder='please enter...'
onChange={v => console.log(v)}
/>
);
```
|Properties |Instructions |Type |Default |Version |
|--------------|-------------------------------------------------|----------------------------------------------------------------|----------|--------|
|addOnBlur |Whether to automatically create the current input value into a tag when the blur event is triggered |boolean | false |-|
|allowDuplicates|Allows adding the same tag multiple times |boolean | true |-|
|autoFocus |Set whether to automatically focus during initial rendering |boolean | false |-|
|className |Class name |string | - |-|
|defaultValue |Default tag value |string[] | - |-|
|disabled |Read-only, disable interaction |boolean |false |-|
|inputValue |Controlled input value |string | - |-|
|maxLength |Maximum length of a tag |number | - |-|
|max |Maximum number of tags allowed |number | - |-|
|maxTagCount |The maximum number of tags to be displayed, if exceeded, they will be displayed in the form of +N |number | - |-|
|showRestTagsPopover |When maxTagCount is exceeded and hover reaches +N, whether to display the remaining content through Popover |boolean | true |-|
|restTagsPopoverProps |The configuration properties of the popover |PopoverProps | {} |-|
|showContentTooltip |When the tag is too long and truncated, when hovering the tag, whether to display all contents through Tooltip.If passed in as object: type,type of component to show tooltip, one of Tooltip, Popover; opts, properties that will be passed directly to the component |boolean\|{type: 'tooltip'\|'popover', opts: object} | true |-|
|placeholder |Content to be appear by default |string | - |-|
|prefix |Prefix |ReactNode |- |-|
| preventScroll | Indicates whether the browser should scroll the document to display the newly focused element, acting on the focus method inside the component, excluding the component passed in by the user | boolean | | |
|renderTagItem |Customize the rendering of items, The parameter onClose is available in version 2.23.0 |<ApiType detail='(value: string, index: number, onClose: function) => React.ReactNode'>(params) => React.ReactNode</ApiType> | - |-|
|separator |Customize the separator |string\|string[] |, |-|
|showClear |Whether to show the clear button |boolean |false |-|
|size |Size, one of `small`、`large`、`default` |string |`default` |-|
|split |Customize the separator processing function |(value: string, separator: string) => string[] | - |2.90.0|
|style |Inline style |React.CSSProperties | - |-|
|suffix |Suffix |ReactNode |- |-|
|validateStatus|Validate status for styling only, one of `default`、`warning`、`error`|string |`default` |-|
|value |Controlled tag value |string[] \| undefined | - |-|
|draggable |Set whether to drag and drop |boolean |false |2.17.0|
|expandRestTagsOnClick| Without dragging,whether to expand redundant tags after TagInput is clicked |boolean |true |2.17.0|
|onAdd |Callback invoked when tags are added |(addedValue: string[]) => void | - |-|
|onBlur |Callback invoked when input loses focus |(e:React.MouseEvent) => void | - |-|
|onChange |Callback invoked when tags changes |(value:string[]) => void | - |-|
|onExceed |Callback invoked when max is exceeded |(value:string[]) => void | - |-|
|onFocus |Callback invoked when input gets focus |(e:React.MouseEvent) => void | - |-|
|onInputChange |Callback invoked when input changes |(value:string,e: React.KeyboardEvent) => void)| - |-|
|onInputExceed |Callback invoked when maxLength is exceeded |(value:string) => void | - |-|
|onKeyDown |Callback invoked when keydown |(e: React.KeyboardEvent) => void | - |2.1.0|
|onRemove |Callback invoked when tags are removed |(removedValue: string, idx: number) => void | - |-|
Some internal methods provided by TagInput can be accessed through ref:
|Name |Description |Version |
|-------|------------|--------|
|blur() |Remove focus|-|
|focus()|Get focus |-|
- TagInput supports the input of `aria-label` to indicate the function of the TagInput;
- TagInput will set `aria-disabled` and `aria-invalid` according to disabled and validateStatus props;
- Both the input box and the clear button of TagInput have `aria-label` to indicate the function of the element.
<DesignToken/>
<!--
```material
192,176
``` -->