UserTag
A chip that pairs an avatar (with optional status badge) and a name label — for representing a person or account inline.
Overview
UserTag combines Avatar and Tag into a single component: it renders an avatar (image, initials, or fallback icon, plus an optional status badge) next to a text label. Like Tag, it renders as a static <div> by default and becomes a <button> when an onClick prop is provided, and icon slots (startIcon, endIcon) can have their own independent onClick handlers via slotProps — enabling actions like "remove" without triggering the tag's own click.
Import
import { UserTag } from '@unflow.io/ui/components/UserTag';Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Text shown next to the avatar |
src | string | — | Avatar image URL, forwarded to the internal Avatar |
status | 'invisible' | 'away' | 'available' | 'unavailable' | — | Status shown as a badge on the avatar |
variant | 'white' | 'grey' | 'white' | Background color family |
size | 'sm' | 'md' | 'lg' | 'sm' | Tag size (also controls the internal avatar size) |
rounded | boolean | false | Renders a fully rounded (pill) shape instead of the default radius |
startIcon | ReactNode | — | Icon before the avatar |
endIcon | ReactNode | — | Icon after the label |
onClick | (e: MouseEvent<HTMLButtonElement>) => void | — | Makes the tag a button |
disabled | boolean | false | Sets aria-disabled="true" and makes the tag inert |
Basic usage
<UserTag label="Jane Doe" src="https://i.pravatar.cc/60" status="available" />Statuses
The status prop is passed through to the internal Avatar and rendered as a badge over it.
<UserTag label="Available" src="https://i.pravatar.cc/60" status="available" />
<UserTag label="Away" src="https://i.pravatar.cc/60?img=2" status="away" />
<UserTag label="Unavailable" src="https://i.pravatar.cc/60?img=3" status="unavailable" />
<UserTag label="No badge" src="https://i.pravatar.cc/60?img=4" status="invisible" />Sizes
<UserTag label="Small" src="https://i.pravatar.cc/60" status="available" size="sm" />
<UserTag label="Medium" src="https://i.pravatar.cc/60" status="available" size="md" />
<UserTag label="Large" src="https://i.pravatar.cc/60" status="available" size="lg" />Interactive
When onClick is provided, the entire tag becomes a <button>:
<UserTag
label="Clickable"
src="https://i.pravatar.cc/60"
status="available"
onClick={() => console.log('user tag clicked')}
/>Icon onClick handlers in slotProps stop propagation — they don't trigger the main tag handler, which makes them useful for "remove" actions:
<UserTag
label="Removable"
src="https://i.pravatar.cc/60"
status="available"
endIcon={<X />}
slotProps={{ endIcon: { onClick: () => console.log('remove clicked') } }}
/>Customization (slots & slotProps)
| Slot | Type | Description |
|---|---|---|
avatar | ReactNode | Override the entire avatar element |
| Slot Prop | Props | Description |
|---|---|---|
label | BaseHTMLProps<HTMLParagraphElement> | Override the text element |
startIcon | BaseHTMLProps<HTMLDivElement | HTMLButtonElement> | Override start icon wrapper |
endIcon | BaseHTMLProps<HTMLDivElement | HTMLButtonElement> | Override end icon wrapper |
avatar | Omit<IAvatar, 'src' | 'size' | 'status'> | Props forwarded to the internal Avatar (e.g. name, alt, disableStatusBadge) — src, size and status are controlled by UserTag itself |
Accessibility
- Renders as a
<div>by default; becomes a<button>whenonClickis provided, enabling keyboard focus and Enter/Space activation. disabledsetsaria-disabled="true"and marks the taginert, removing it from the accessibility tree and tab order while it stays visible.- Icon slots (
startIcon/endIcon) with their ownonClickinslotPropsrender as independently focusable buttons; their clicks stop propagation so they don't also trigger the tag's ownonClick. - Provide meaningful
labeltext — the status badge conveys state visually, but the label remains the primary accessible content.