Data display & Filters

Tag

Tags label, categorize, or filter content with a compact, removable chip.

Components · Data display

A tag is a compact chip that labels, categorizes, or filters a piece of content. Namirial tags are built from --nm-tag-* tokens defined in namirial-theme.css, ship in seven soft intents, two sizes, and an optional remove action.

Design SystemLiveReact

Overview

A tag names a single attribute of the thing it's attached to — a category, a keyword, a status. Unlike a badge, a tag carries text as its primary content and can be dismissed by the user; unlike a button, it never triggers a page-level action on its own (only its optional remove control does).

When to use

  • To label content with a category or keyword (React, Design System)
  • To show active filters that the user can remove (Status: Active ✕)
  • To let users build a multi-value input, like recipients or skills

When not to use

  • To show a count or a short status indicator with no removable text — use a badge.
  • To trigger navigation or a standalone action — use a button or link.
  • For a single mutually-exclusive choice — use a segmented control or radio group.

Anatomy

A tag is an inline flex container: a soft-tinted background, a tinted border, a text label, and an optional remove button. Every part reads its color from a --nm-tag-* custom property that the intent modifier reassigns.

Tokens and values that drive each part

PartRoleSource
ContainerFill--nm-tag-bg
ContainerBorder--nm-tag-border
ContainerRadiusborder-radius: 6px (fixed)
ContainerPadding2px 6px (4px 8px on --lg)
LabelColor--nm-tag-fg
LabelSize / weight12px / SemiBold (14px on --lg)
Remove iconColor at rest--nm-tag-remove-fg
Remove iconColor on hover--nm-tag-remove-hover-fg

Intents

Every intent pairs a soft background with a tinted border and a solid-colored label — quieter than a button, but still legible at a glance. Pick the intent that matches what the tag communicates, not the color you like.

PrimarySecondaryAccentInfoPositiveNegativeWarning

Seven intents · sm · soft background + tinted border + solid label

With remove

Add a .nm-tag__remove button to let users dismiss the tag — typically an applied filter or a value in a multi-select input. The icon inherits --nm-tag-remove-fg and darkens on hover.

LabelPrimaryInfoNegative

Every removable tag needs an aria-label on the remove button — "Remove tag" or, better, "Remove {value}".

Sizes

Two sizes, set with nm-tag--lg (omit for the default, sm-equivalent size).

DefaultLabelLabel
lgLabelLabel

Light & dark theme

--nm-tag-fg, --nm-tag-remove-fg, and --nm-tag-remove-hover-fg remap under data-theme so labels stay legible against the soft background in both themes; --nm-tag-bg and --nm-tag-border come from the shared tag/badge palette and don't need remapping.

Light data-theme="light"
PrimaryAccentNegative
Dark data-theme="dark"
PrimaryAccentNegative

Both previews are locked — they don't follow the page theme switcher. Toggle the page theme to see the rest of the documentation cascade.

Do & don't

✓Do
DesignEngineering
Keep tag text to one or two words — a category name, not a sentence.
✕Don't
This document was last edited yesterday
Don't use a tag for long or sentence-like text — it will truncate awkwardly. Use a paragraph or a table cell instead.
✓Do
Status: Active
Add a remove button when the tag represents something the user can clear, like an applied filter.
✕Don't
Click to filter
Don't make the whole tag clickable to trigger navigation — that's what a button or link chip is for.

Accessibility

Semantics

  • A plain tag is a <span> — it carries no interaction and needs no special role.
  • The remove control must be a real <button> with an aria-label ("Remove {'{'}value{'}'}"); the icon alone is not accessible text.

Keyboard

  • Non-removable tags are not focusable — they're static labels.
  • The remove button follows normal tab order and activates on Space / Enter.

Contrast

  • All seven intents meet WCAG 2.2 AA for label-over-background in both themes.

Token reference

TokenRole
--nm-tag-bgContainer fill
--nm-tag-borderContainer border
--nm-tag-fgLabel color
--nm-tag-remove-fgRemove icon color at rest
--nm-tag-remove-hover-fgRemove icon color on hover

Each nm-tag--{intent} modifier reassigns --nm-tag-bg, --nm-tag-border, and (for accent/info/positive/negative/warning) --nm-tag-fg. {intent} = primary · secondary · accent · info · positive · negative · warning.

Index palette — categorical colors beyond the 7 intents

For content that needs many distinguishable colors with no semantic meaning (user-created labels, calendar categories, chart legends), namirial-theme.css ships a 10-hue categorical palette: --palette-index-{'{n}'}-50 (soft), --palette-index-{'{n}'}-75 (border/mid), and --palette-index-{'{n}'}-100 (solid), for {'{n}'} = 1–10. These are fixed hex values — they don't remap per theme. There's no dedicated nm-tag--index-{'{n}'} modifier class yet, so wire them up per instance:

Category 1Category 2Category 3Category 4Category 5Category 6Category 7Category 8Category 9Category 10
<span class="nm-tag" style="
  --nm-tag-bg: var(--palette-index-3-50);
  --nm-tag-border: var(--palette-index-3-75);
  --nm-tag-fg: var(--palette-index-3-100);
">
  <span class="nm-tag__label">Category 3</span>
</span>

Implementation

<link rel="stylesheet" href="namirial-theme.css">

<span class="nm-tag nm-tag--accent">
  <span class="nm-tag__label">Design System</span>
  <button class="nm-tag__remove" aria-label="Remove tag">
    <i class="icon-x"></i>
  </button>
</span>

CSS classes

ClassValuesDefault
nm-tag--{intent}primary · secondary · accent · info · positive · negative · warningnone (base tokens)
nm-tag--lglarger padding, gap, and font sizeomit for default size
nm-tag__labelrequired wrapper for the text content—
nm-tag__removeoptional dismiss button, requires aria-label—