Skip to content

DynamicTags ​

Always-visible input + tag flow: press Enter or a separator to create tags; supports deduplication, validation, limits, save-on-blur, reordering, overflow collapsing, and in-place tag editing.

Basic Usage ​

Deduplicate by default

model-value is a JSON array attribute; duplicate tags are not allowed by default. Keyboard: Enter / separator to submit; with the input empty, Backspace deletes the last tag.

Allow Duplicates ​

allow-duplicate

Separator & Paste Batching ​

separator=; (semicolon submits)

Paste comma-separated text to batch-create (on by default)

  • separator customizes the commit separator (single character, default ,; empty string = Enter only; separator=" " gives space triggering)
  • add-on-paste (default true): pasting text that contains the separator splits and batch-creates tags, each going through dedup/limit/format checks; pastes without a separator keep native insertion
  • maxlength limits the input length

Save on Blur (Behavior Change) ​

save-on-blur defaults to true

save-on-blur=false discards on blur (old behavior)

Behavior change (since v2.5.0): save-on-blur now defaults to true — leftover input text is committed as a tag on blur (aligning with the mainstream default). Previously the text was silently discarded; set save-on-blur="false" explicitly to keep the old behavior.

Reordering ​

sortable: drag + buttons + keyboard reorder

sortable enables three reorder channels; a reorder dispatches oas-change (detail.trigger = "sort"):

  • Buttons: per-tag "move up / move down" icon buttons swap with the neighbor on click (touch reachable — HTML5 drag is not available on touch screens)
  • Drag: hold a tag and drop it on the target position
  • Keyboard: with the input empty, ← focuses the last tag / → the first; ← / → walk between tags (both ends return to the input); Alt + ← / Alt + → swap with the neighbor

On touch screens (pointer: coarse) tags grow to a 44px row height, and the remove / sort / clear button hit targets widen to 44px.

Overflow Collapsing ​

max-tag-count=2 collapses to +N

Tags beyond max-tag-count collapse into a +N counter with a title tooltip listing hidden tags; combine with oas-tooltip for richer display (attach the overlay to .tag-overflow after render).

Validation ​

pattern regex (digits only)

oas-before-add cancelable event (banned words)

  • pattern: a regex string; a mismatch rejects the add with a hint (reusing the duplicate-hint channel: aria-invalid + a 2s message)
  • oas-before-add: a cancelable event (detail: { value }); hosts call preventDefault() to veto (synchronous validation only; async validation is not supported)
  • Check order: limit > format > duplicate > oas-before-add veto

Editing Existing Tags ​

Double-click a tag to edit in place

Double-click a tag (or press Enter on a focused tag when sortable) to edit in place: Enter commits, Esc cancels, blur follows save-on-blur. Commits go through dedup/format checks; success dispatches oas-edit (detail: { index, value, oldValue }) and oas-change (trigger = "edit"); committing an empty value reverts.

Custom Tags ​

template[slot=tag]

template[slot="tag"] is cloned into each tag ([data-tag-label] binds the tag text; the remove button stays component-side). template[slot="prefix"] / template[slot="suffix"] clone to the start/end of the tag container.

Size / Status / Readonly / Clearable ​

size variants

status=error

readonly / clearable

  • readonly: tags stay, the input and remove buttons are hidden (form semantics differ from disabled)
  • clearable: a clear button appears when there is a value and the component is interactive; clicking dispatches oas-clear and oas-change (trigger = "clear")

IME Safety ​

While an IME composition is active (isComposing), pressing Enter or the separator (candidate confirmation) does not create a tag; pressing Enter after the composition ends commits normally. Safe for CJK input methods.

When to Use Select Multiple Instead ​

For "pick from suggestions + free input", use oas-select with multiple + searchable + allow-create (built-in suggestion dropdown, highlighting, multi-select chips) instead of building a dropdown over DynamicTags:

Select multiple + searchable + allow-create (comparison)

Rule of thumb: free-form short token sets (recipients, keywords) use DynamicTags; a candidate list that also accepts new values uses Select multiple.

max Limit ​

max=3

When max is reached, the input is automatically disabled; deleting a tag restores input.

Placeholder & Disabled ​

placeholder

disabled

Events ​

Add/remove/edit/clear/sort events

oas-change detail is { value, trigger } with trigger ∈ add | remove | clear | sort | edit (backward compatible: the value field is unchanged); there are also oas-add / oas-remove (detail: { value }), oas-edit (detail: { index, value, oldValue }), oas-clear, oas-before-add (cancelable), and oas-focus / oas-blur:

API ​

oas-dynamic-tags ​

Attributes ​

AttributeDescriptionTypeDefault
add-on-pasteSplit pasted text into tags by separator (default true)stringtrue
allow-duplicateAllow duplicate tagsboolean—
clearableClear button (one-click clears all tags)boolean—
disabledDisabledboolean—
maxMaximum number of tagsstring—
max-tag-countCollapse overflow into a +N chip (title lists hidden tags)number—
maxlengthMaximum length per tagstring—
model-valueTag array (property or JSON)string[][]
patternRegex for new tags (mismatch warns and rejects)string—
placeholderInput placeholderstring—
readonlyRead-only (input/remove buttons hidden, tags display-only)boolean—
save-on-blurCommit leftover input as a tag on blur (default true, behavior change: previously silently discarded; set "false" for the old behavior)stringtrue
separatorSeparator (creates a tag on type; default ,; empty string = Enter only)string,
sizeSize preset small / medium (default) / largestringmedium
sortableTag sorting: drag + keyboard Alt+←/→ adjacent swapboolean—
statusValidation status: error / warning / successstring—

Property (JS property; see each row for attribute reflection) ​

PropertyDescriptionTypeDefault
valueCurrent value: array of tag stringsstring[][]

Events ​

EventDescription
oas-addTag added, detail: { value }
oas-before-addFires before creating a tag (cancellable via preventDefault; limit/format/duplicate checks run first), detail: { value }
oas-blurFires when the input loses focus
oas-changeDispatched after add/remove, detail: { value }
oas-clearFires on clear, detail: {}
oas-editTag edit committed, detail: { index, value, oldValue } (double-click or focused Enter to edit)
oas-focusFires when the input gains focus
oas-removeTag removed, detail: { value }

Slots ​

NameDescription
template[slot="prefix"]Prefix content slot
template[slot="suffix"]Suffix content slot
template[slot="tag"]Custom tag ([data-tag-label] binding; remove button stays component-side)

CSS Variables ​

CSS VariableDefault
--oas-entry-pad0px

Keyboard: Enter / , to submit; with the input empty, Backspace deletes the last tag.

ARIA: the container has role="list", tags have role="listitem", remove buttons are focusable with an aria-label; when submitting a duplicate, the input is marked aria-invalid with a hint shown.

Released under the MIT OR Apache-2.0 License.