Skip to content
weftGitHub

Tag

A label people added themselves, which they can often remove.

SourcePackage @weft-js/warpPlayground

Preview

tsx
import { Tag } from '@weft-js/warp'export function Plain() {  return (    <>      <Tag>frontend</Tag>      <Tag>eu-west</Tag>      <Tag>needs review</Tag>    </>  )}

Installation

npm install @weft-js/warp

Usage

tsx
import { Tag } from '@weft-js/warp'<Tag onRemove={remove}>frontend</Tag>

Tones

Use tone to colour a tag.

tsx
import { Tag } from '@weft-js/warp'export function Tones() {  return (    <>{TONES.map(tone => <Tag key={tone} tone={tone}>Label</Tag>)}</>  )}const TONES = ['neutral', 'accent', 'positive', 'caution', 'critical', 'info'] as const

With a swatch

swatch adds a dot of colour, for categories.

tsx
import { Tag } from '@weft-js/warp'export function Swatches() {  return (    <>      <Tag tone="accent" swatch>Web</Tag>      <Tag tone="positive" swatch>Platform</Tag>      <Tag tone="caution" swatch>Data</Tag>      <Tag tone="info" swatch>Mobile</Tag>    </>  )}

Removable

onRemove adds the cross. When the text is an expression, pass label to name it.

tsx
import { state } from '@weft-js/core'import { Button, Tag } from '@weft-js/warp'export function Removable() {  const tags = state(['frontend', 'eu-west', 'needs review'])  return (    <>      {tags.value.map(t => <Tag key={t} label={t} onRemove={() => (tags.value = tags.value.filter(x => x !== t))}>{t}</Tag>)}      {!tags.value.length && <Button size="sm" emphasis="ghost" tone="neutral" onClick={() => (tags.value = ['frontend', 'eu-west', 'needs review'])}>Put them back</Button>}    </>  )}

Adding labels

Use onRemove to give each tag a button that takes it off.

tsx
import { state } from '@weft-js/core'import { Input, Row, Stack, Tag } from '@weft-js/warp'export function AddToProject() {  const tags = state(['frontend', 'checkout'])  const draft = state('')  const add = (e: Event) => {    e.preventDefault()    const name = draft.value.trim()    if (name && !tags.value.includes(name)) tags.value = [...tags.value, name]    draft.value = ''  }  return (    <Stack as="form" gap="related" onSubmit={add}>      <Input label="Add a label" placeholder="Type and press Enter" value={draft.value} onInput={(e: Event) => (draft.value = (e.target as HTMLInputElement).value)} />      <Row gap="tight">        {tags.value.map(t => <Tag key={t} label={t} onRemove={() => (tags.value = tags.value.filter(x => x !== t))}>{t}</Tag>)}      </Row>    </Stack>  )}

When to use

Use it for

  • Labels people choose or type
  • A list of values with a remove button

Reach for something else

  • Badge, when the app set the status
  • Chip, when it filters when pressed

Playground

Tone
import { Tag } from '@weft-js/warp'<Tag onRemove={remove}>frontend</Tag>

Accessibility

  • The remove button is named "Remove" plus the tag's text.

API Reference

PropTypeDefaultDescription
toneTone—Its colour.
swatchbooleanfalseA dot of colour before the text.
labelstring—Names the remove button, when children is an expression.
childrenunknown—What it contains.
EventTypeDefaultDescription
onRemove(() => void)—Adds a remove button. You take the tag out of your list.

Parts

Every element carries a stable name, so you can style it from your own CSS: [data-scope="tag"] [data-part="swatch"]

swatchremove

RelatedBadgeChip