Skip to content

Components

TagInput

A list of short values typed into one row: keywords, symbols, addresses. Enter or comma commits, Backspace removes the last chip, and a pasted list arrives as separate tags.

Examples

Values with a shape

`validate` returns a message and the candidate never enters the list — validation belongs here, not in a toast.

BTC-USDETH-USD

Uppercase tickers, optionally venue-qualified.

Up to five addresses; duplicates are refused.

2 tags · 0 recipients

States

Empty, filled, read-only and disabled are one input with four treatments — the chips do not change shape, only their editability does.

Empty

momentumcarryvalue

Filled

BTC-USD

Read-only

BTC-USD

Disabled

The same chips, read-only

The chips a tag input produces are the `Tag` component used everywhere else in the library, so a read-only list and an editable one look identical.

BTC-USDETH-USD

Usage

import { TagInput } from "@luc/ui";
<TagInput value={symbols} onValueChange={setSymbols} placeholder="Add a symbol…" />

`value` plus `onValueChange` controls the list; `defaultValue` leaves it to the component. A `Field` supplies the label and the message a refused value is announced through.

API

Read from the published TypeScript API, so a prop that is not listed here does not exist and a default that is listed is the one the compiler sees.

Exported symbols
ExportKindSignature
TagInput16 documented props({ value, defaultValue, onValueChange, placeholder, maxTags, separators, validate, caseSensitive, allowDuplicates, size, invalid, disabled, readOnly, id, className, ...props }: TagInputProps) => impo…

TagInput props

Type: TagInputProps

Values the compiler reads from the declaration.

TagInput props
PropTypeDefaultNotes
allowDuplicates?boolean | undefined—
aria-label?string | undefined—
caseSensitive?boolean | undefined—Trims and lowercases before comparing for duplicates. Default `false`.
className?string | undefined—
defaultValue?string[] | undefined—
disabled?boolean | undefined—
id?string | undefined—
invalid?boolean | undefined—
maxTags?number | undefined—Maximum tags. Further input is refused with an inline message.
onValueChange?((tags: string[]) => void) | undefined—
placeholder?string | undefined—
readOnly?boolean | undefined—
separators?string[] | undefined—Keys that commit the current text. Enter always commits.
size?ControlSize | undefined—
validate?((tag: string, tags: string[]) => string | undefined) | undefined—Return a message to reject the candidate value.
value?string[] | undefined—

Guidelines

Do

  • Give `validate` both the rule and the sentence a reader sees when it fails: a rejected tag never enters the list.
  • Set `maxTags` when the list has a real ceiling — recipients, venues, sectors — instead of letting it grow without limit.
  • Use `readOnly` for a list a reader may copy but not edit; the chips keep their shape either way.

Don't

  • Report a rejected value in a toast: the message belongs beside the field that refused it.
  • Use a tag input for long text — the chips are for short identifiers a reader recognises at a glance.
  • Expect a pasted list to arrive as one tag: a pasted delimiter-separated list is split into separate values.

Accessibility

The chips are the same `Tag` component used elsewhere in the library, and the input keeps its own label, description and message through `Field`. Enter or comma commits a value, Backspace removes the last chip, and a value the `validate` function refuses is announced through the field's message rather than silently dropped.

Luc UI v1.0TagInputdark theme