Components / Controls
TagInput
A field for several short values: topics, labels, keywords, recipients. People type and press Enter, pick a suggestion or paste a list, and remove tags with a click or the keyboard.
When to useLink to "When to use"
- An open-ended list of short values, typed or picked.
Use something else when:
- the choices are a fixed, short set: checkboxes (Checkbox)
- there is exactly one value: Combobox or TextField
UsageLink to "Usage"
import { TagInput } from "@arshad-shah/cynosure";
<TagInput label="Topics" value={topics} onChange={setTopics} suggestions={allTopics} />SuggestionsLink to "Suggestions"
With suggestions, matching ones (anywhere in the word, not already added) appear in a list while typing. Arrow keys move through it, Enter or a click adds one. Free text is still accepted.
ChecksLink to "Checks"
Duplicates are refused (without regard to case) unless allowDuplicates; maxTags caps the count; validate returns a message to refuse a tag. The message shows as the field's error and the typed text stays so it can be fixed.
Editing, custom tags and an iconLink to "Editing, custom tags and an icon"
Backspace in an empty field takes the last tag back into the field as text, to fix a typo: Enter (or leaving the field) adds it again, and "Editing …" is announced (labels.editing). renderTag(tag) draws a tag's content (an icon, a coloured dot, a formatted value) in place of its text; Backspace still edits the text, and the remove button is still named by it. iconStart puts an icon in the field, before the input.
FormsLink to "Forms"
With name, each tag is submitted as its own value under that name (formData.getAll(name)). required needs at least one tag; reset restores defaultValue; disabled fields are not submitted and lose their remove buttons.
PropsLink to "Props"
| Prop | What it does | Type | Default |
|---|---|---|---|
labelRequired | The field's label and accessible name. | ReactNode | |
labelHidden | Visually hide the label (it still names the control). Prefer visible labels. | boolean | |
description | Help text shown below the field. | ReactNode | |
error | Your own error; it replaces the field's own messages. | ReactNode | |
value | The tags (controlled). | string[] | |
defaultValue | Starting tags when uncontrolled. | string[] | |
onChange | Called with the full list of tags whenever one is added or removed. | ((tags: string[]) => void) | |
suggestions | Offered while typing (and with Arrow Down). Free text is still allowed. | string[] | |
separators | Typing one of these adds the text as a tag (Enter always does). Pasted text is split on them. Default: [","]. | string[] | [" |
allowDuplicates | Allows the same tag more than once. Otherwise a tag already in the list (ignoring case) is refused. | boolean | |
maxTags | The most tags allowed; more are refused with a message. | number | |
validate | Return a message to refuse a tag (shown as the field's error), or null to accept it. | ((tag: string, tags: string[]) => string | null) | |
name | Form field name; each tag is submitted as its own value under it. | string | |
form | id of the form the tags are submitted with, when the field sits outside it. | string | |
required | The form cannot be submitted while there are no tags. | boolean | |
disabled | Blocks typing and removing tags, and leaves the tags out of the form submission. | boolean | |
placeholder | Hint shown in the input while nothing is typed. | string | |
renderTag | Draws a tag's content in place of its text (the remove button is still named by the text). | ((tag: string) => ReactNode) | |
iconStart | Icon at the start of the field, before the input. | IconData | |
size | Field height and text size. Default "md". | Size | "md" |
variant | outline or soft (tinted, borderless until focus). Default "outline". | "soft" | "outline" | "outline" |
labels | Replace the built-in English text: the tag list's name, the remove buttons, announcements and refusals. | Partial<TagInputLabels> | |
className | Added to the root element, for layout. | string | |
style | Layout only. Restyle through --cy-tag-input-* tokens. | CSSProperties | |
layout | stack puts the label above the control and the description and error below it. split puts the label and description at the start and the control at the end of one row (a settings row); when the field is too narrow for both, the control moves under the text. Default "stack". | "stack" | "split" | "stack" |
width | Width of the control, so the controls of a column of fields line up: "sm", "md" and "lg" are the --cy-field-control-width-* tokens (never wider than the field), "full" is the whole field. Default: the control's own width (the whole field in the stacked layout for TextField and the other fields). | FieldWidth |
Generated from the type definitions in @arshad-shah/cynosure 0.5.0.
Behaviour and accessibilityLink to "Behaviour and accessibility"
- Roles: the input is a text box, or an APG combobox with a listbox when
suggestionsis set. The tags are a list named "Tags"; each has a "Remove …" button. - Keyboard:
| Key | Where | Action |
|---|---|---|
Enter / , | Field | Add the typed text (or the active suggestion) |
| Backspace | Empty field | Take the last tag back into the field to edit |
| Arrow Left | Start of field | Move to the last tag |
| Arrow Left / Right | Tags | Move between tags; past the last, back to the field |
| Delete / Backspace | Tag | Remove it |
| Escape | Tags or list | Back to the field / close the list |
- Tab order: the field is one tab stop; tags are reached with the arrow keys.
- Paste: text with commas or new lines becomes several tags.
- Announcements: "… added", "… removed" and "Editing …" are announced politely.
- Touch: remove buttons have a 44px hit area on touch screens.
- All built-in text is in
labels.
ThemingLink to "Theming"
Tokens: --cy-tag-input-tag-background and --cy-tag-input-tag-radius. The suggestion list is an OptionList, restyled with --cy-option-list-*.
RelatedLink to "Related"
These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.