Skip to content
Cynosurev0.5.0
SearchStorybookGitHubnpmColour mode: System. Switch to Light

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.

Enter and comma add tags

When to useLink to "When to use"

  • An open-ended list of short values, typed or picked.

Use something else when:

UsageLink to "Usage"

tsx
Copy
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.

Suggestions

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.

Refusals are explained

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.

Custom tag content and an icon

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"

Every prop of TagInput
PropWhat it doesTypeDefault
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 suggestions is set. The tags are a list named "Tags"; each has a "Remove …" button.
  • Keyboard:
Behaviour and accessibility, table 1
KeyWhereAction
Enter / ,FieldAdd the typed text (or the active suggestion)
BackspaceEmpty fieldTake the last tag back into the field to edit
Arrow LeftStart of fieldMove to the last tag
Arrow Left / RightTagsMove between tags; past the last, back to the field
Delete / BackspaceTagRemove it
EscapeTags or listBack 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-*.

Combobox · TextField · Badge

These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.

Getting started
Theming
Icons
Accessibility
Code editors and highlighters
Using Cynosure without React
Build-tool adapters
Components
Accordion
AppShell
AspectRatio
Breadcrumbs
Calendar
Card
Container
Disclosure
Divider
DocumentViewport
Grid
Inline
PageHeader
PanZoomCanvas
ScrollArea
SideNav
SortableList
SplitPane
Stack
StatusBar
Tabs
TitleBar
Toolbar
Tree
VirtualList
ZoomControls
Announcer
Avatar
Badge
CodeBlock
DescriptionList
EmptyState
ErrorBoundary
Field
Heading
IconTile
Image
Kbd
List
LoadingDots
Notice
ProgressBar
Prose
Skeleton
Stat
Steps
Table
Text
Button
Checkbox
Checklist
ColorField
ColorSwatches
Combobox
CompareSlider
CopyButton
DateField
FileDrop
IconButton
KeyValueEditor
Link
NumberField
Pagination
PathField
RadioGroup
SearchField
SegmentedControl
Select
SelectionFrame
SignaturePad
Slider
Switch
TagInput
TextArea
TextField
ThemeToggle
TimeField
ButtonBase
ChoiceBase
DialogBase
FileInputBase
HiddenValue
Icon
InputBase
LinkBase
LiveRegion
TextAreaBase
ChatMessage
Choice
DataGrid
DeviceFrame
HighlightedText
HotkeyField
ListRow
OptionList
OverlayFrame
QRCode
RowActions
Section
SiteFooter
SiteHeader
SkipLink
SortButton
VisuallyHidden
CommandPalette
ContextMenu
Dialog
FloatingToolbar
HoverCard
Menu
Menubar
Popover
ProgressOverlay
Sheet
Toast
Tooltip
Changelog