Usage
label, paint with intent, height with size, and a decorative leading icon or avatar.
onRemove with removeLabel and removedAnnouncement adds a remove Button after the label. Activating it calls onRemove(details), then announces removedAnnouncement politely, unless the handler calls details.cancel(). The consumer removes the token from its own state. The token that held focus unmounts, so the consumer also moves focus, usually back to the entry.
Name the subject in removeLabel ("Remove Dana Levi"), not just "Remove": a row of tokens would otherwise read as identical buttons. removedAnnouncement is a whole sentence ("Dana Levi removed") because it is read with no visual context.
While focus is on a token's toggle or remove button, Backspace and Delete remove it, with the same onRemove call and announcement as a click. A held key, a modified key and an input-method composition are ignored, so one press never removes a run of tokens.
A composer can remove its last token when the person presses Backspace in an empty entry. That rule is easy to get wrong, so Token ships it as shouldRemoveLastTokenOnBackspace(event):
It returns true only for a first, unmodified Backspace in a text entry that is empty and not read-only, outside composition, that no handler has already claimed. It never fires while the person is editing text: with ab in the entry, Backspace deletes b, then a, and only the next press, with the entry empty, removes a token. The token that is removed this way never held focus, so the composer calls announceTokenRemoval itself.
Pass selected (controlled), or defaultSelected and onSelectedChange, to turn the label into a toggle button with aria-pressed, for a filter that can be switched on. Selected adds a wash and an accent edge, so it does not rest on color alone. A token can be both selectable and removable; the toggle and the remove button are siblings, never nested.
disabled disables the toggle and the remove button, ignores Backspace and Delete, and paints the disabled foreground on the disabled surface (ADR 0015). A token inside a disabled fieldset takes the same paint with no prop.
A long label truncates with an ellipsis at the token's maximum inline size. The leading part and the remove button keep their size. The full text stays in the DOM and in the label's title.
Small, Medium and Large are 24, 28 and 32px, the shared control heights, and Large is the default. The remove button and the avatar are 24px discs at every size and sit concentric with the pill. On a coarse pointer the remove button grows to the touch target and the token grows with it.