Chip input

Turns typed entries, such as email addresses, into removable chips.

Live React portVue source: WildChipInput.vueStorybook story: Forms/Chip InputReact component: WChipInput

Try it

Remove a chip with its ×, or tab to the × and press Enter. Turn on Suggestions to see the match list.

JMJoel Mannsam@orchard.nznot-an-email
Size
Suggestions
Error
Disabled
<WildChipInput
  v-model="recipients"
  size="md"
  placeholder="Add people by email"
/>

When to use

  • Use it to collect several email addresses in one field, such as when inviting people.
  • Check each address as its own chip, so one typo marks that address and not the whole line.
Don’t use it

Anatomy

Chips for what’s been added, then the text being typed. Each chip carries its own state and a × in its own colour, which fills a circle on hover.

JMjoel@mywildeye.comSOsam@orchard.nz
Add people by email
<WildChipInput v-model="recipients"
  placeholder="Add people by email" />

Chip states

Four states show how far an address has got: typed, recognised as an existing user, rejected, or already sent.

JMJoel Mannsam@orchard.nznot-an-emailAKana@mywildeye.com
Recognised resolves an address to a person with initials, so a typo of a colleague’s address stands out before Send.

Field states

rest
joel@mywildeye.com
hover
joel@mywildeye.com
focus
joel@mywildeye.com
error
joel@mywildeye.com
disabled
joel@mywildeye.com
The frame thickens to 2px on focus and error, and the chips hold their place.

Suggestions

JMJoel Mannsa
SOSam Okonkwosam@orchard.nzAdmin
SPSana Patelsana@mywildeye.comViewer
Matches from the account appear as you type, with a role badge so an admin isn’t invited as a viewer by accident.

Accessibility

Each × is a button named after its chip, such as “Remove sam@orchard.nz”, so a screen reader can tell them apart.

KeyWhat it does
TabMoves to each chip’s remove button in turn.
Enter / SpaceRemoves that chip.

Props

PropTypeDefaultDescription
chips{ label, state?, initials? }[][]The chips, in order.
onRemoveChip(label: string) => void—Called when a chip’s × is pressed.
size'sm' | 'md' | 'lg''md'Minimum height: 36, 40 or 44px.
state'rest' | 'hover' | 'focus' | 'error' | 'disabled''rest'The frame. Disabled also disables every ×.
placeholderstring—Shown while there are no chips.
typingstring—Text after the chips, still being typed.
suggestions{ label, sublabel?, initials?, badge?, active? }[]—The match list under the field.
widthnumber | string—Field width.

Tokens

TokenValueWhere it lands
--radius-lg8pxThe field frame.
--global-blue-1000#1877F2Frame on focus.
--color-error#E12121Frame on error.
--global-blue-100 / -1100#EBFAFF / #0C296ARecognised chip ground and ink.
--global-red-200 / -1100#FFE3E3 / #711111Invalid chip ground and ink.
--global-green-100 / -1000#EBFBF1 / #016626Sent chip ground and ink.
--global-{family}-1000 / 1100the chip’s familyThe × at rest, then on hover.
--global-{family}-200 / 300the chip’s familyThe × circle on hover, then pressed, on the recognised (blue) and sent (green) chips.
--global-neutral-grey-300 / 500#F1F1F1 / #E6E6E6The × circle on the neutral chip, which has no family tint.
--global-red-300 / 400#FFC9C9 / #FAA4A4The × circle on the invalid chip. It already rests on red-200, so the circle goes one step deeper to show.
--global-blue-400 / red-300 / green-300#A3E7FF / #FFC9C9 / #C1F4D4Recognised, invalid and sent chip borders.
--shadow-dropdown0 4px 12px rgba(0,0,0,.08), …The suggestion list.