Chip Input
Use catnip-input-chip when users need to add and remove multiple short string values (tags, filters, skills). For plain text, email, password, or textarea fields, use Input instead.
Behaviour
- State: Bind
model-value/.modelValue(string[]) for committed chips. - Draft (default input): Chip owns draft internally. Parent sets via
setDraftValue()on a host ref (prefill, reset). Parent observes via optional@update:draftValue. Binding.draftValuehas no effect on the default input. - Draft (
draftInputslot): Parent binds.draftValueand wires the slotted control to the same ref.setDraftValue()does nothing — use the prop. Clear.draftValueafter commit in@update:modelValue. - Committing a tag: Non-empty draft commits on Enter or via Add (shown by default). Set
show-add-button="false"if you want Enter-only. The component emitsupdate:modelValuewith the new array. It does not emit per-tag events; add/remove are reflected only in that array. - Tag limits: Set
min-chipsto prevent removing below the minimum committed count andmax-chipsto prevent adding beyond the maximum. These props constrain user actions; keep app-level validation messages in your form flow. - Visible tags: Set
max-visible-chipswhen long chip lists would crowd the field. Hidden chips are represented by a tertiary Show n more button; the expanded list shows Show less at the bottom-right. Override labels withshow-more-chips-label/show-less-chips-labelif needed. - Add button: Shown by default; set
show-add-button="false"to hide it (aligned to field size s / m / l when visible). Configure it with.addButton="{ label, ariaLabel, appearance, leftIcon, ... }"— same forwarding pattern ascatnipInput.labeloverrides the bundledinputChip.addstring (e.g. + Add); setariaLabelonly if the visible label is not enough for assistive tech. - Clear draft: Turn on
catnipInput.showClearButtonto showcatnip-input’s clear control when the draft has text (default off). Activating it clears only the draft line, not the chips.catnipInput.clearButtonAriaLabeloverrides the defaultinput.clearstring if needed. Useshow-add-buttonfor committing tags; reserve clear for wiping the unsent line. - Forms: The custom element’s form value is a comma-separated list of tags; draft text is not submitted.
Layout
Chips render below the draft row so the text field stays at a stable vertical position while the list grows; helper/error copy (supporting-text) sits after the chip list so long tag lists do not push the message away from the label.
Composition (shared with Input)
- Labels: Use the
labelprop orlabelslot; optionallabel.action/label.suffixslots match Input. For custom controls, use Field Label standalone. See Input — Guidelines. - Supporting text: Pass
supporting-text—do not mount <catnip-field-supporting-text> manually. Oncatnip-input-chip, helper text is rendered after the chip list;aria-describedbyon the draft control still points at it. - Draft input (default): Put draft-only input props under
catnipInput. To prefill or reset draft from the parent, callsetDraftValue()on a host ref — not.draftValue. Listen to@update:draftValueonly if you need to mirror draft state elsewhere. - Draft input (custom): Use
slot="draftInput"when the defaultcatnip-inputis not enough. Bind.draftValue; wire your slotted control to that ref. Add commitsdraftValue; parent clears draft in@update:modelValue. Enter, focus, and validation on the slotted control are the parent's responsibility.
Intents and status
The intent prop matches Input: neutral, warning, danger (sets aria-invalid on the draft control), success. See Input — Guidelines — Intents and Status.
Best practices
- Prefer Enter and/or the Add button over ambiguous icons for “commit tag”.
- Keep chip lists manageable with
max-visible-chipswhen users can accumulate many tags. - Default vs custom draft: use
setDraftValue()with the embedded input; use.draftValuewith thedraftInputslot — not both for the same field.