Eunomia v1.0.0-beta.2
AllAngularReactNext.jsJavaScriptVue
EunomiaSalmonForestVioletOceanGoldFireCustom…
🇬🇧 English🇫🇷 Français

Chip

Chip represents a small, removable piece of information, such as a selected filter, an invited guest, or an uploaded file. Its label can be paired with an optional leading visual, such as an icon, an avatar photo, an image thumbnail, or a colored initials badge. It's always about one discrete, removable piece of data, so it ships with a working delete button by default.

Dependencies

eun-icon · if using an icon, or removable (the default) eun-button · if removable (the default)
Overview API Examples Accessibility
Design Featured Alice Doe

When to use

Reach for a chip whenever the user is looking at a discrete, removable piece of data they added themselves, such as an applied filter, a recipient in a "to" field, or a file staged for upload. Each chip should read on its own, independent of the others around it. See Alternatives below if what you need instead is a static label with no removal behavior.

Install & usage

Pick a framework in the toolbar above and these snippets adapt.

npm install @eunomia/elements
import "@eunomia/elements/chip.js";
<eun-chip avatar-initials="AD">Alice Doe</eun-chip>
document.querySelector("eun-chip").addEventListener("eunclose", (event) => {
  event.target.remove();
});

Importing the file registers <eun-chip> as a custom element, with no further setup needed. It works with any framework, or none, since it's a standard web component.

Alternatives

You want .. Prefers A static label with no removal behavior eun-tag

Guidance

  • Keep the label short and specific, such as a name, a filename, or a filter value, since it's the only reliably-perceived carrier of what the chip actually represents
  • Pick one leading visual per chip: avatarSrc for a real photo, avatarInitials for a person with no photo, icon for a category/type, or none at all for a plain label
  • Give ariaLabelRemove a translated verb ("Retirer", "Entfernen"...) rather than leaving the English default in a localized UI. See the Accessibility tab
  • Move focus somewhere deliberate after removing a chip in response to eunclose. See the Accessibility tab
  • Using eun-chip for a static status or count that's never removed. See Alternatives above
  • Setting both avatarSrc/avatarInitials and expecting icon to still show. Only one leading visual ever renders, see the API tab for the precedence order
  • Relying on a generic, un-translated "Remove" across a whole list of chips in a non-English UI. See the Accessibility tab
  • Overriding colors with inline styles instead of the --chip-* CSS variables

Live testing

Properties

Chip <eun-chip>

Attributes

NameTypeDefaultDescription
hide-iconbooleanfalseWhether the leading icon is hidden from the chip, once resolved. The avatar and initials are unaffected
avatar-srcstringThe URL of a leading avatar or image. Takes priority over avatar initials and icon
avatar-altstring''The alt text for the avatar image. Left empty by default, since the slotted label already carries the identity. Set it only when the image conveys information the label doesn't
avatar-shape'circle' | 'square''circle'The shape of the leading avatar, initials, or image. Circle suits a person's photo, square a generic image thumbnail
avatar-initialsstringOne or two characters shown in a colored badge in place of an image. Ignored once an avatar image is set, and takes priority over icon
aria-label-removestringRemoveA prefix combined with the chip's own slotted text to build the delete button's accessible name, such as "Remove Alice Doe", so multiple chips on the same page stay distinguishable to assistive technology. Defaults to the localized string for the current locale (English: "Remove")
color'primary' | 'secondary' | 'light' | 'medium' | 'dark''medium'The color to apply to the chip
severity'info' | 'success' | 'warning' | 'critical' | 'neutral'The severity of the chip, matching the nature of the information conveyed. Takes priority over color when both are set
appearance'default' | 'fill' | 'outline' | 'flat''default'The surface style of the chip. Flat always renders the same muted, low emphasis surface regardless of color or severity
size's' | 'm' | 'l''m'The size of the chip
iconEunomiaIconNameThe leading icon to display. Ignored once an avatar image or initials are set. When severity is set and icon isn't, the icon is set according to the chip's severity
roundedbooleantrueWhether the chip is fully rounded, as a pill
removablebooleantrueShows the delete button. Clicking it fires the close event without changing the chip's own rendering
disabledbooleanfalseDisables the delete button, preventing removal

Import the exact TypeScript type behind any property above, see Types.

Properties

JS-only — no matching HTML attribute, set these from a script or a template binding.

NameTypeDefaultDescription
localestringThe locale used to resolve the default accessible label of the delete button. Defaults to the runtime's own
dictionaryThis instance's locale-resolved string dictionary — see the class doc for the resolution order.

Slots

NameDescription
(default)The chip's label
iconReplaces the leading icon entirely with any content, not just an icon element. Falls back to the resolved icon or severity glyph when empty. Ignored once an avatar image or initials are set

Events

NameTypeDescription
euncloseCloseEventFired when the delete button is activated. The chip has no visibility state of its own, so removing or hiding it in response is the consumer's own responsibility

Every event above follows the same naming convention, covered in Events.

CSS custom properties

NameDescription
--chip-background-colorSets the background color of the chip
--chip-border-colorSets the border color of the chip, for the outline appearance
--chip-border-widthSets the border width of the chip, for the outline appearance
--chip-box-shadowSets a box shadow on the chip, none by default
--chip-colorSets the text color of the chip
--chip-icon-colorSets the color of the leading icon only, not the avatar, initials, or delete button icon. Defaults to matching the chip's own text color
--chip-border-radiusSets the corner radius of the chip when rounded is unset
--chip-gapSets the gap between the chip's leading visual, label, and delete button
--chip-avatar-backgroundSets the background color of the initials badge
--chip-avatar-colorSets the text color of the initials badge
--chip-avatar-sizeSets the diameter of the leading avatar, initials, or image
--chip-delete-focus-outline-colorSets the focus outline color of the delete button

CSS shadow parts

NameDescription
chipThe outer box wrapping the leading visual, label, and delete button. Exposed for effects the chip's CSS custom properties don't cover, such as an accent

Label only

The minimal chip has no leading visual, just a slotted label and the default delete button. With nothing to fill the leading edge, the chip widens its own start padding a little so the label doesn't read as cramped against it. See "Icon and label" below for the other case that gets the same treatment, and "Avatar and label" for why an avatar/initials badge doesn't.

Design
<eun-chip>Design</eun-chip>

Icon and label

A plain icon gets the same wider start padding as a label-only chip, since it's small enough on its own that the default padding would otherwise look uneven next to the label.

Featured Project files
<eun-chip icon="star">Featured</eun-chip>
<eun-chip icon="folder" color="primary">Project files</eun-chip>

Need something other than a eun-icon, or a different icon library entirely? Slot your own content into icon instead. It replaces the prop-driven icon entirely (ignored, same as icon itself, once avatarSrc/avatarInitials is set).

Featured
<eun-chip>
  <svg
    slot="icon"
    width="16"
    height="16"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    stroke-width="2"
  >
    <path
      d="m12 2 2.9 6.9L22 10l-5.5 4.8L18 22l-6-3.7L6 22l1.5-7.2L2 10l7.1-1.1L12 2Z"
    ></path>
  </svg>
  Featured
</eun-chip>

Avatar and label

Set avatarSrc to a photo URL. It renders as a circle by default, inset with the same padding as the label and delete button on every side (unlike icon/label-only, an avatar already carries enough visual weight against the edge on its own), e.g. a form's list of invited guests.

Alice Doe Bob Smith
<eun-chip avatar-src="https://example.com/alice.jpg">Alice Doe</eun-chip>
<eun-chip avatar-src="https://example.com/bob.jpg">Bob Smith</eun-chip>

Image and label

Set avatarShape="square" alongside avatarSrc for a generic image thumbnail instead of a person's photo, such as a file preview or a small logo.

report.pdf
<eun-chip avatar-src="https://example.com/thumb.png" avatar-shape="square"
  >report.pdf</eun-chip
>

Initials and label

Set avatarInitials for a person chip with no photo available: one or two characters in a colored badge, matching color.

Alice Doe Bob Smith
<eun-chip avatar-initials="AD">Alice Doe</eun-chip>
<eun-chip avatar-initials="BS" color="primary">Bob Smith</eun-chip>

Leading visual precedence

avatarSrc wins over avatarInitials, which wins over icon (itself resolved from the explicit prop or, failing that, severity's own default icon). Only one leading visual ever renders.

All three set
<eun-chip
  avatar-src="https://example.com/alice.jpg"
  avatar-initials="AD"
  icon="star"
  >All three set</eun-chip
>

Color

Primary Secondary Light Medium Dark
<eun-chip color="primary">Primary</eun-chip>
<eun-chip color="secondary">Secondary</eun-chip>
<eun-chip color="light">Light</eun-chip>
<eun-chip color="medium">Medium</eun-chip>
<eun-chip color="dark">Dark</eun-chip>

Part of the shared vocabulary covered in Variants, alongside every other component that reuses it.

Severity

Set severity for a state that maps to a semantic meaning (info/success/warning/critical/neutral). Like eun-tag, it also picks a matching default icon automatically, and takes precedence over color when both are set.

Info Success Warning Critical Neutral
<eun-chip severity="info">Info</eun-chip>
<eun-chip severity="success">Success</eun-chip>
<eun-chip severity="warning">Warning</eun-chip>
<eun-chip severity="critical">Critical</eun-chip>
<eun-chip severity="neutral">Neutral</eun-chip>

Unlike eun-tag, an explicit icon set alongside severity still wins over the severity's own default icon. severity only drives the color here, so a caller that needs its own icon per state (a status icon, for instance) keeps full control of it.

Pending Confirmed
<eun-chip severity="warning" icon="hourglass_empty">Pending</eun-chip>
<eun-chip severity="success" icon="check_circle">Confirmed</eun-chip>

Hiding the icon

Set hideIcon to drop the leading icon entirely, whether it came from an explicit icon or a severity default. The avatar/initials leading visual is unaffected, since hideIcon only ever governs the icon.

Overdue
<eun-chip severity="critical" hide-icon>Overdue</eun-chip>

Display appearance

Default Fill Outline Flat
<eun-chip color="primary" appearance="default">Default</eun-chip>
<eun-chip color="primary" appearance="fill">Fill</eun-chip>
<eun-chip color="primary" appearance="outline">Outline</eun-chip>
<eun-chip color="primary" appearance="flat">Flat</eun-chip>

flat always renders the same muted, low-emphasis surface regardless of color, matching eun-tag's own flat type.

Sizes

Small Medium Large
<eun-chip avatar-initials="AD" size="s">Small</eun-chip>
<eun-chip avatar-initials="AD">Medium</eun-chip>
<eun-chip avatar-initials="AD" size="l">Large</eun-chip>

Not rounded

Turn rounded off for a chip with a small corner radius (matching eun-tag's own default shape) instead of a full pill.

Alice Doe
<eun-chip avatar-initials="AD" id="square-chip">Alice Doe</eun-chip>
<script>
  document.getElementById("square-chip").rounded = false;
</script>

rounded is a boolean property defaulting to true. Per web component convention, writing the HTML attribute at all (even as rounded="false") sets it to true, so turning it off means setting the JS property instead, as above.

Not removable

Set removable to false for a chip that carries the same visual language but isn't meant to be dismissed.

Alice Doe
<eun-chip avatar-initials="AD" id="locked-chip">Alice Doe</eun-chip>
<script>
  document.getElementById("locked-chip").removable = false;
</script>

Same boolean-attribute caveat as rounded above. removable defaults to true, so opting out means setting the JS property, not writing removable="false" in markup.

Disabled

Disables the delete button, preventing removal, and mutes the chip slightly.

Alice Doe
<eun-chip avatar-initials="AD" disabled>Alice Doe</eun-chip>

Removing a chip

eun-chip dispatches eunclose and stops there. It never removes or hides itself. The consumer decides what "removed" means, typically deleting the element (or the underlying data item, in a framework-rendered list).

Alice Doe Bob Smith Carla Jones
<div id="chip-list">
  <eun-chip avatar-initials="AD">Alice Doe</eun-chip>
  <eun-chip avatar-initials="BS">Bob Smith</eun-chip>
  <eun-chip avatar-initials="CJ">Carla Jones</eun-chip>
</div>
<script>
  document.getElementById("chip-list").addEventListener("eunclose", (event) => {
    event.target.remove();
  });
</script>

Custom colors

Override the --chip-* CSS variables, listed in full in the API tab. Unlike eun-tag, these apply regardless of which color is set, since every color branch itself reads through the corresponding --chip-* variable.

Custom Pending review
<eun-chip class="custom-chip" avatar-initials="ZK">Custom</eun-chip>
<eun-chip appearance="outline" icon="warning" class="custom-icon-chip"
  >Pending review</eun-chip
>
.custom-chip {
  --chip-background-color: #fdf2f8;
  --chip-color: #be185d;
  --chip-avatar-background: #be185d;
  --chip-border-width: 2px;
  --chip-border-color: #be185d;
  --chip-box-shadow: 0 2px 8px rgba(190, 24, 93, 0.25);
}

.custom-icon-chip {
  --chip-icon-color: #c85207;
}

Keyboard interactions

Key Action
Tab / Shift+Tab Moves focus to/from the delete button, when removable is set
Space / Enter Activates the focused delete button, native <button> behavior

eun-chip itself is never focusable and carries no tabindex. It isn't a single interactive control, it's a label with an interactive delete affordance inside it. When removable is unset there is nothing in it to reach with the keyboard at all. It reads exactly like a eun-tag would.

Delete button semantics

The delete button is a real eun-button (ghost rounded size="xs", an icon-only eun-icon child), so it inherits a native, fully accessible <button> under the hood with no extra work here. See eun-button's own Accessibility tab for the underlying details. Its accessible name is ariaLabelRemove (default "Remove") combined with the chip's own slotted text (e.g. "Remove Alice Doe"), computed automatically off the default slot's content. This matters more here than it does for eun-alert's single close button. A page can easily show a whole row of chips at once, and several identical unlabeled "Remove, button" announcements in a row give a screen reader user no way to tell which one they're about to activate. Set a translated ariaLabelRemove ("Retirer", "Entfernen"...) for a localized UI. Leaving the English default in place while the label text itself is localized produces a mixed-language accessible name.

Leading visual is decorative

The leading icon renders via eun-icon, which always sets aria-hidden="true" on itself (see its own Accessibility tab). The initials badge (avatarInitials) is likewise aria-hidden="true" on the chip's own markup. Neither is ever announced, and neither is a substitute for the label text. The identity or category they represent should already be spelled out in the slotted label itself (a chip reading "Alice Doe" next to her initials, not initials alone).

Avatar image alt text

The avatarSrc image defaults to alt="" (decorative) for the same reason: the slotted label already names who or what the avatar represents, so a redundant alt text would just have a screen reader announce the same name twice in a row. Set avatarAlt explicitly only when the image conveys something the label text genuinely doesn't, such as a photo used as the sole identifier with no accompanying name, per WCAG 1.1.1 Non-text Content.

Focus management on removal is your responsibility

eun-chip dispatches eunclose and stops there. It never removes or hides itself (see "Removing a chip" in the Examples tab). If your eunclose handler removes the element from the DOM while focus was still on its delete button, the browser drops focus to <body>, and a keyboard user loses their place per WCAG 2.4.3 Focus Order. This is especially easy to hit with a list of chips, since removing one usually shifts every chip after it. Move focus somewhere deliberate right after removal: the next remaining chip's own delete button, the field that lets the user add a new one, or the nearest heading/landmark, rather than leaving it to land wherever the browser defaults to.

Don't rely on color alone

color changes the chip's visual appearance only. WCAG 1.4.1 Use of Color requires that information conveyed by color also be available another way. Keep the slotted label descriptive on its own ("Design" or "Alice Doe", not just a colored dot) rather than relying on the reader inferring meaning from color alone.

Color contrast

The default and fill types are built from this design system's own color tokens, already chosen to meet contrast minimums against their paired background. A custom --chip-background-color/--chip-color combination (or a custom brand color) must still be checked against WCAG 1.4.3 Contrast (Minimum) (4.5:1 for this size of text). See Color for the tokens that already meet it. The initials badge defaults to white text over the chip's own solid --_backgroundFilled color specifically so it stays legible regardless of the active appearance. A custom --chip-avatar-background / --chip-avatar-color pair needs the same contrast check independently, since it's a separate foreground/background pair from the label text.

Reference links

WCAG 1.4.1: Use of Color
WCAG 1.1.1: Non-text Content
WCAG 1.4.3: Contrast (Minimum)
WCAG 2.4.3: Focus Order