Badge

Lightweight status and label primitive with minimal styling hooks.

Default

With no properties supplied, Badge renders its base appearance.

Default

Code

<link
  rel="component"
  href="@threadlabs/looma/components/ui-badge/ui-badge.html"
>

<ui-badge>Default</ui-badge>
<script setup>
  import { UiBadge } from "@threadlabs/looma";
</script>

<template>
  <UiBadge>Default</UiBadge>
</template>
import { UiBadge } from "@threadlabs/looma";

export default function Example() {
  return <UiBadge>Default</UiBadge>;
}
/** @jsxImportSource preact */
import { UiBadge } from "@threadlabs/looma";

export default function Example() {
  return <UiBadge>Default</UiBadge>;
}
<script>
  import { UiBadge } from "@threadlabs/looma";
</script>

<UiBadge>Default</UiBadge>
import { Component } from "@angular/core";
import { UiBadge } from "@threadlabs/looma";

@Component({
  selector: "example-view",
  standalone: true,
  imports: [UiBadge],
  template: `
    <span
      ui-badge
    >Default</span>
  `,
})
export default class Example {}

variant="solid" and tone

Solid badges use the strongest filled treatment for each semantic tone.

Accent Info Success Warning Danger Category Collection

Code

<link
  rel="component"
  href="@threadlabs/looma/components/ui-cluster/ui-cluster.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-badge/ui-badge.html"
>

<ui-cluster
  gap="xs"
>
  <ui-badge
    variant="solid"
    tone="accent"
  >Accent</ui-badge>
  <ui-badge
    variant="solid"
    tone="info"
  >Info</ui-badge>
  <ui-badge
    variant="solid"
    tone="success"
  >Success</ui-badge>
  <ui-badge
    variant="solid"
    tone="warning"
  >Warning</ui-badge>
  <ui-badge
    variant="solid"
    tone="danger"
  >Danger</ui-badge>
  <ui-badge
    variant="solid"
    tone="accent-secondary"
  >Category</ui-badge>
  <ui-badge
    variant="solid"
    tone="accent-tertiary"
  >Collection</ui-badge>
</ui-cluster>
<script setup>
  import { UiBadge, UiCluster } from "@threadlabs/looma";
</script>

<template>
  <UiCluster
    gap="xs"
  >
    <UiBadge
      variant="solid"
      tone="accent"
    >Accent</UiBadge>
    <UiBadge
      variant="solid"
      tone="info"
    >Info</UiBadge>
    <UiBadge
      variant="solid"
      tone="success"
    >Success</UiBadge>
    <UiBadge
      variant="solid"
      tone="warning"
    >Warning</UiBadge>
    <UiBadge
      variant="solid"
      tone="danger"
    >Danger</UiBadge>
    <UiBadge
      variant="solid"
      tone="accent-secondary"
    >Category</UiBadge>
    <UiBadge
      variant="solid"
      tone="accent-tertiary"
    >Collection</UiBadge>
  </UiCluster>
</template>
import { UiBadge, UiCluster } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="xs"
  >
    <UiBadge
      variant="solid"
      tone="accent"
    >Accent</UiBadge>
    <UiBadge
      variant="solid"
      tone="info"
    >Info</UiBadge>
    <UiBadge
      variant="solid"
      tone="success"
    >Success</UiBadge>
    <UiBadge
      variant="solid"
      tone="warning"
    >Warning</UiBadge>
    <UiBadge
      variant="solid"
      tone="danger"
    >Danger</UiBadge>
    <UiBadge
      variant="solid"
      tone="accent-secondary"
    >Category</UiBadge>
    <UiBadge
      variant="solid"
      tone="accent-tertiary"
    >Collection</UiBadge>
  </UiCluster>;
}
/** @jsxImportSource preact */
import { UiBadge, UiCluster } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="xs"
  >
    <UiBadge
      variant="solid"
      tone="accent"
    >Accent</UiBadge>
    <UiBadge
      variant="solid"
      tone="info"
    >Info</UiBadge>
    <UiBadge
      variant="solid"
      tone="success"
    >Success</UiBadge>
    <UiBadge
      variant="solid"
      tone="warning"
    >Warning</UiBadge>
    <UiBadge
      variant="solid"
      tone="danger"
    >Danger</UiBadge>
    <UiBadge
      variant="solid"
      tone="accent-secondary"
    >Category</UiBadge>
    <UiBadge
      variant="solid"
      tone="accent-tertiary"
    >Collection</UiBadge>
  </UiCluster>;
}
<script>
  import { UiBadge, UiCluster } from "@threadlabs/looma";
</script>

<UiCluster
  gap="xs"
>
  <UiBadge
    variant="solid"
    tone="accent"
  >Accent</UiBadge>
  <UiBadge
    variant="solid"
    tone="info"
  >Info</UiBadge>
  <UiBadge
    variant="solid"
    tone="success"
  >Success</UiBadge>
  <UiBadge
    variant="solid"
    tone="warning"
  >Warning</UiBadge>
  <UiBadge
    variant="solid"
    tone="danger"
  >Danger</UiBadge>
  <UiBadge
    variant="solid"
    tone="accent-secondary"
  >Category</UiBadge>
  <UiBadge
    variant="solid"
    tone="accent-tertiary"
  >Collection</UiBadge>
</UiCluster>
import { Component } from "@angular/core";
import { UiBadge, UiCluster } from "@threadlabs/looma";

@Component({
  selector: "example-view",
  standalone: true,
  imports: [UiCluster, UiBadge],
  template: `
    <div
      ui-cluster
      [gap]="'xs'"
    >
      <span
        ui-badge
        [variant]="'solid'"
        [tone]="'accent'"
      >Accent</span>
      <span
        ui-badge
        [variant]="'solid'"
        [tone]="'info'"
      >Info</span>
      <span
        ui-badge
        [variant]="'solid'"
        [tone]="'success'"
      >Success</span>
      <span
        ui-badge
        [variant]="'solid'"
        [tone]="'warning'"
      >Warning</span>
      <span
        ui-badge
        [variant]="'solid'"
        [tone]="'danger'"
      >Danger</span>
      <span
        ui-badge
        [variant]="'solid'"
        [tone]="'accent-secondary'"
      >Category</span>
      <span
        ui-badge
        [variant]="'solid'"
        [tone]="'accent-tertiary'"
      >Collection</span>
    </div>
  `,
})
export default class Example {}

variant="subtle" and tone

Subtle badges retain the same semantic tones on quiet tinted surfaces.

Accent Info Success Warning Danger Category Collection

Code

<link
  rel="component"
  href="@threadlabs/looma/components/ui-cluster/ui-cluster.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-badge/ui-badge.html"
>

<ui-cluster
  gap="xs"
>
  <ui-badge
    variant="subtle"
    tone="accent"
  >Accent</ui-badge>
  <ui-badge
    variant="subtle"
    tone="info"
  >Info</ui-badge>
  <ui-badge
    variant="subtle"
    tone="success"
  >Success</ui-badge>
  <ui-badge
    variant="subtle"
    tone="warning"
  >Warning</ui-badge>
  <ui-badge
    variant="subtle"
    tone="danger"
  >Danger</ui-badge>
  <ui-badge
    tone="accent-secondary"
  >Category</ui-badge>
  <ui-badge
    tone="accent-tertiary"
  >Collection</ui-badge>
</ui-cluster>
<script setup>
  import { UiBadge, UiCluster } from "@threadlabs/looma";
</script>

<template>
  <UiCluster
    gap="xs"
  >
    <UiBadge
      variant="subtle"
      tone="accent"
    >Accent</UiBadge>
    <UiBadge
      variant="subtle"
      tone="info"
    >Info</UiBadge>
    <UiBadge
      variant="subtle"
      tone="success"
    >Success</UiBadge>
    <UiBadge
      variant="subtle"
      tone="warning"
    >Warning</UiBadge>
    <UiBadge
      variant="subtle"
      tone="danger"
    >Danger</UiBadge>
    <UiBadge
      tone="accent-secondary"
    >Category</UiBadge>
    <UiBadge
      tone="accent-tertiary"
    >Collection</UiBadge>
  </UiCluster>
</template>
import { UiBadge, UiCluster } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="xs"
  >
    <UiBadge
      variant="subtle"
      tone="accent"
    >Accent</UiBadge>
    <UiBadge
      variant="subtle"
      tone="info"
    >Info</UiBadge>
    <UiBadge
      variant="subtle"
      tone="success"
    >Success</UiBadge>
    <UiBadge
      variant="subtle"
      tone="warning"
    >Warning</UiBadge>
    <UiBadge
      variant="subtle"
      tone="danger"
    >Danger</UiBadge>
    <UiBadge
      tone="accent-secondary"
    >Category</UiBadge>
    <UiBadge
      tone="accent-tertiary"
    >Collection</UiBadge>
  </UiCluster>;
}
/** @jsxImportSource preact */
import { UiBadge, UiCluster } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="xs"
  >
    <UiBadge
      variant="subtle"
      tone="accent"
    >Accent</UiBadge>
    <UiBadge
      variant="subtle"
      tone="info"
    >Info</UiBadge>
    <UiBadge
      variant="subtle"
      tone="success"
    >Success</UiBadge>
    <UiBadge
      variant="subtle"
      tone="warning"
    >Warning</UiBadge>
    <UiBadge
      variant="subtle"
      tone="danger"
    >Danger</UiBadge>
    <UiBadge
      tone="accent-secondary"
    >Category</UiBadge>
    <UiBadge
      tone="accent-tertiary"
    >Collection</UiBadge>
  </UiCluster>;
}
<script>
  import { UiBadge, UiCluster } from "@threadlabs/looma";
</script>

<UiCluster
  gap="xs"
>
  <UiBadge
    variant="subtle"
    tone="accent"
  >Accent</UiBadge>
  <UiBadge
    variant="subtle"
    tone="info"
  >Info</UiBadge>
  <UiBadge
    variant="subtle"
    tone="success"
  >Success</UiBadge>
  <UiBadge
    variant="subtle"
    tone="warning"
  >Warning</UiBadge>
  <UiBadge
    variant="subtle"
    tone="danger"
  >Danger</UiBadge>
  <UiBadge
    tone="accent-secondary"
  >Category</UiBadge>
  <UiBadge
    tone="accent-tertiary"
  >Collection</UiBadge>
</UiCluster>
import { Component } from "@angular/core";
import { UiBadge, UiCluster } from "@threadlabs/looma";

@Component({
  selector: "example-view",
  standalone: true,
  imports: [UiCluster, UiBadge],
  template: `
    <div
      ui-cluster
      [gap]="'xs'"
    >
      <span
        ui-badge
        [variant]="'subtle'"
        [tone]="'accent'"
      >Accent</span>
      <span
        ui-badge
        [variant]="'subtle'"
        [tone]="'info'"
      >Info</span>
      <span
        ui-badge
        [variant]="'subtle'"
        [tone]="'success'"
      >Success</span>
      <span
        ui-badge
        [variant]="'subtle'"
        [tone]="'warning'"
      >Warning</span>
      <span
        ui-badge
        [variant]="'subtle'"
        [tone]="'danger'"
      >Danger</span>
      <span
        ui-badge
        [tone]="'accent-secondary'"
      >Category</span>
      <span
        ui-badge
        [tone]="'accent-tertiary'"
      >Collection</span>
    </div>
  `,
})
export default class Example {}

Shape

pill is the default. tag is flat at the start and points at the end, for tags and chosen chips.

Pill Tag Principles Decision

Code

<link
  rel="component"
  href="@threadlabs/looma/components/ui-cluster/ui-cluster.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-badge/ui-badge.html"
>

<ui-cluster
  gap="s"
>
  <ui-badge>Pill</ui-badge>
  <ui-badge
    shape="tag"
  >Tag</ui-badge>
  <ui-badge
    shape="tag"
    variant="subtle"
    tone="accent"
  >Principles</ui-badge>
  <ui-badge
    shape="tag"
    variant="subtle"
    tone="warning"
  >Decision</ui-badge>
</ui-cluster>
<script setup>
  import { UiBadge, UiCluster } from "@threadlabs/looma";
</script>

<template>
  <UiCluster
    gap="s"
  >
    <UiBadge>Pill</UiBadge>
    <UiBadge
      shape="tag"
    >Tag</UiBadge>
    <UiBadge
      shape="tag"
      variant="subtle"
      tone="accent"
    >Principles</UiBadge>
    <UiBadge
      shape="tag"
      variant="subtle"
      tone="warning"
    >Decision</UiBadge>
  </UiCluster>
</template>
import { UiBadge, UiCluster } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="s"
  >
    <UiBadge>Pill</UiBadge>
    <UiBadge
      shape="tag"
    >Tag</UiBadge>
    <UiBadge
      shape="tag"
      variant="subtle"
      tone="accent"
    >Principles</UiBadge>
    <UiBadge
      shape="tag"
      variant="subtle"
      tone="warning"
    >Decision</UiBadge>
  </UiCluster>;
}
/** @jsxImportSource preact */
import { UiBadge, UiCluster } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="s"
  >
    <UiBadge>Pill</UiBadge>
    <UiBadge
      shape="tag"
    >Tag</UiBadge>
    <UiBadge
      shape="tag"
      variant="subtle"
      tone="accent"
    >Principles</UiBadge>
    <UiBadge
      shape="tag"
      variant="subtle"
      tone="warning"
    >Decision</UiBadge>
  </UiCluster>;
}
<script>
  import { UiBadge, UiCluster } from "@threadlabs/looma";
</script>

<UiCluster
  gap="s"
>
  <UiBadge>Pill</UiBadge>
  <UiBadge
    shape="tag"
  >Tag</UiBadge>
  <UiBadge
    shape="tag"
    variant="subtle"
    tone="accent"
  >Principles</UiBadge>
  <UiBadge
    shape="tag"
    variant="subtle"
    tone="warning"
  >Decision</UiBadge>
</UiCluster>
import { Component } from "@angular/core";
import { UiBadge, UiCluster } from "@threadlabs/looma";

@Component({
  selector: "example-view",
  standalone: true,
  imports: [UiCluster, UiBadge],
  template: `
    <div
      ui-cluster
      [gap]="'s'"
    >
      <span
        ui-badge
      >Pill</span>
      <span
        ui-badge
        [shape]="'tag'"
      >Tag</span>
      <span
        ui-badge
        [shape]="'tag'"
        [variant]="'subtle'"
        [tone]="'accent'"
      >Principles</span>
      <span
        ui-badge
        [shape]="'tag'"
        [variant]="'subtle'"
        [tone]="'warning'"
      >Decision</span>
    </div>
  `,
})
export default class Example {}

Outline

Outline uses the tone on its text and edge; it works for both the pill and pointed tag shapes.

Queued Ready Blocked

Code

<link
  rel="component"
  href="@threadlabs/looma/components/ui-cluster/ui-cluster.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-badge/ui-badge.html"
>

<ui-cluster
  gap="s"
>
  <ui-badge
    variant="outline"
    tone="info"
  >Queued</ui-badge>
  <ui-badge
    variant="outline"
    tone="success"
  >Ready</ui-badge>
  <ui-badge
    variant="outline"
    tone="danger"
    shape="tag"
  >Blocked</ui-badge>
</ui-cluster>
<script setup>
  import { UiBadge, UiCluster } from "@threadlabs/looma";
</script>

<template>
  <UiCluster
    gap="s"
  >
    <UiBadge
      variant="outline"
      tone="info"
    >Queued</UiBadge>
    <UiBadge
      variant="outline"
      tone="success"
    >Ready</UiBadge>
    <UiBadge
      variant="outline"
      tone="danger"
      shape="tag"
    >Blocked</UiBadge>
  </UiCluster>
</template>
import { UiBadge, UiCluster } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="s"
  >
    <UiBadge
      variant="outline"
      tone="info"
    >Queued</UiBadge>
    <UiBadge
      variant="outline"
      tone="success"
    >Ready</UiBadge>
    <UiBadge
      variant="outline"
      tone="danger"
      shape="tag"
    >Blocked</UiBadge>
  </UiCluster>;
}
/** @jsxImportSource preact */
import { UiBadge, UiCluster } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="s"
  >
    <UiBadge
      variant="outline"
      tone="info"
    >Queued</UiBadge>
    <UiBadge
      variant="outline"
      tone="success"
    >Ready</UiBadge>
    <UiBadge
      variant="outline"
      tone="danger"
      shape="tag"
    >Blocked</UiBadge>
  </UiCluster>;
}
<script>
  import { UiBadge, UiCluster } from "@threadlabs/looma";
</script>

<UiCluster
  gap="s"
>
  <UiBadge
    variant="outline"
    tone="info"
  >Queued</UiBadge>
  <UiBadge
    variant="outline"
    tone="success"
  >Ready</UiBadge>
  <UiBadge
    variant="outline"
    tone="danger"
    shape="tag"
  >Blocked</UiBadge>
</UiCluster>
import { Component } from "@angular/core";
import { UiBadge, UiCluster } from "@threadlabs/looma";

@Component({
  selector: "example-view",
  standalone: true,
  imports: [UiCluster, UiBadge],
  template: `
    <div
      ui-cluster
      [gap]="'s'"
    >
      <span
        ui-badge
        [variant]="'outline'"
        [tone]="'info'"
      >Queued</span>
      <span
        ui-badge
        [variant]="'outline'"
        [tone]="'success'"
      >Ready</span>
      <span
        ui-badge
        [variant]="'outline'"
        [tone]="'danger'"
        [shape]="'tag'"
      >Blocked</span>
    </div>
  `,
})
export default class Example {}

Custom colour

Tones mean a status. For a category, set --ui-badge-color on the badge to any CSS colour; it derives a soft wash and readable text in every variant and theme.

Business Person Location Solid Outline

Code

<link
  rel="component"
  href="@threadlabs/looma/components/ui-cluster/ui-cluster.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-badge/ui-badge.html"
>

<ui-cluster
  gap="xs"
>
  <ui-badge
    style="--ui-badge-color: teal"
  >Business</ui-badge>
  <ui-badge
    style="--ui-badge-color: rebeccapurple"
  >Person</ui-badge>
  <ui-badge
    style="--ui-badge-color: #f59e0b"
  >Location</ui-badge>
  <ui-badge
    variant="solid"
    style="--ui-badge-color: teal"
  >Solid</ui-badge>
  <ui-badge
    variant="outline"
    shape="tag"
    style="--ui-badge-color: rebeccapurple"
  >Outline</ui-badge>
</ui-cluster>
<script setup>
  import { UiBadge, UiCluster } from "@threadlabs/looma";
</script>

<template>
  <UiCluster
    gap="xs"
  >
    <UiBadge
      style="--ui-badge-color: teal"
    >Business</UiBadge>
    <UiBadge
      style="--ui-badge-color: rebeccapurple"
    >Person</UiBadge>
    <UiBadge
      style="--ui-badge-color: #f59e0b"
    >Location</UiBadge>
    <UiBadge
      variant="solid"
      style="--ui-badge-color: teal"
    >Solid</UiBadge>
    <UiBadge
      variant="outline"
      shape="tag"
      style="--ui-badge-color: rebeccapurple"
    >Outline</UiBadge>
  </UiCluster>
</template>
import { UiBadge, UiCluster } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="xs"
  >
    <UiBadge
      style={{"--ui-badge-color":"teal"}}
    >Business</UiBadge>
    <UiBadge
      style={{"--ui-badge-color":"rebeccapurple"}}
    >Person</UiBadge>
    <UiBadge
      style={{"--ui-badge-color":"#f59e0b"}}
    >Location</UiBadge>
    <UiBadge
      variant="solid"
      style={{"--ui-badge-color":"teal"}}
    >Solid</UiBadge>
    <UiBadge
      variant="outline"
      shape="tag"
      style={{"--ui-badge-color":"rebeccapurple"}}
    >Outline</UiBadge>
  </UiCluster>;
}
/** @jsxImportSource preact */
import { UiBadge, UiCluster } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="xs"
  >
    <UiBadge
      style={{"--ui-badge-color":"teal"}}
    >Business</UiBadge>
    <UiBadge
      style={{"--ui-badge-color":"rebeccapurple"}}
    >Person</UiBadge>
    <UiBadge
      style={{"--ui-badge-color":"#f59e0b"}}
    >Location</UiBadge>
    <UiBadge
      variant="solid"
      style={{"--ui-badge-color":"teal"}}
    >Solid</UiBadge>
    <UiBadge
      variant="outline"
      shape="tag"
      style={{"--ui-badge-color":"rebeccapurple"}}
    >Outline</UiBadge>
  </UiCluster>;
}
<script>
  import { UiBadge, UiCluster } from "@threadlabs/looma";
</script>

<UiCluster
  gap="xs"
>
  <UiBadge
    style="--ui-badge-color: teal"
  >Business</UiBadge>
  <UiBadge
    style="--ui-badge-color: rebeccapurple"
  >Person</UiBadge>
  <UiBadge
    style="--ui-badge-color: #f59e0b"
  >Location</UiBadge>
  <UiBadge
    variant="solid"
    style="--ui-badge-color: teal"
  >Solid</UiBadge>
  <UiBadge
    variant="outline"
    shape="tag"
    style="--ui-badge-color: rebeccapurple"
  >Outline</UiBadge>
</UiCluster>
import { Component } from "@angular/core";
import { UiBadge, UiCluster } from "@threadlabs/looma";

@Component({
  selector: "example-view",
  standalone: true,
  imports: [UiCluster, UiBadge],
  template: `
    <div
      ui-cluster
      [gap]="'xs'"
    >
      <span
        ui-badge
        style="--ui-badge-color: teal"
      >Business</span>
      <span
        ui-badge
        style="--ui-badge-color: rebeccapurple"
      >Person</span>
      <span
        ui-badge
        style="--ui-badge-color: #f59e0b"
      >Location</span>
      <span
        ui-badge
        [variant]="'solid'"
        style="--ui-badge-color: teal"
      >Solid</span>
      <span
        ui-badge
        [variant]="'outline'"
        [shape]="'tag'"
        style="--ui-badge-color: rebeccapurple"
      >Outline</span>
    </div>
  `,
})
export default class Example {}

Compact state signals

A dot keeps its state label available to assistive technology. The same tones and variants apply; words beside it explain its meaning visually.

New messages New messages
Waiting for your reply Waiting for your reply

Code

<link
  rel="component"
  href="@threadlabs/looma/components/ui-cluster/ui-cluster.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-badge/ui-badge.html"
>

<ui-cluster
  gap="m"
>
  <ui-cluster
    gap="s"
  >
    <ui-badge
      shape="dot"
      tone="accent"
      variant="solid"
    >New messages</ui-badge>
    <span>New messages</span>
  </ui-cluster>
  <ui-cluster
    gap="s"
  >
    <ui-badge
      shape="dot"
      tone="warning"
    >Waiting for your reply</ui-badge>
    <span>Waiting for your reply</span>
  </ui-cluster>
</ui-cluster>
<script setup>
  import { UiBadge, UiCluster } from "@threadlabs/looma";
</script>

<template>
  <UiCluster
    gap="m"
  >
    <UiCluster
      gap="s"
    >
      <UiBadge
        shape="dot"
        tone="accent"
        variant="solid"
      >New messages</UiBadge>
      <span>New messages</span>
    </UiCluster>
    <UiCluster
      gap="s"
    >
      <UiBadge
        shape="dot"
        tone="warning"
      >Waiting for your reply</UiBadge>
      <span>Waiting for your reply</span>
    </UiCluster>
  </UiCluster>
</template>
import { UiBadge, UiCluster } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="m"
  >
    <UiCluster
      gap="s"
    >
      <UiBadge
        shape="dot"
        tone="accent"
        variant="solid"
      >New messages</UiBadge>
      <span>New messages</span>
    </UiCluster>
    <UiCluster
      gap="s"
    >
      <UiBadge
        shape="dot"
        tone="warning"
      >Waiting for your reply</UiBadge>
      <span>Waiting for your reply</span>
    </UiCluster>
  </UiCluster>;
}
/** @jsxImportSource preact */
import { UiBadge, UiCluster } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="m"
  >
    <UiCluster
      gap="s"
    >
      <UiBadge
        shape="dot"
        tone="accent"
        variant="solid"
      >New messages</UiBadge>
      <span>New messages</span>
    </UiCluster>
    <UiCluster
      gap="s"
    >
      <UiBadge
        shape="dot"
        tone="warning"
      >Waiting for your reply</UiBadge>
      <span>Waiting for your reply</span>
    </UiCluster>
  </UiCluster>;
}
<script>
  import { UiBadge, UiCluster } from "@threadlabs/looma";
</script>

<UiCluster
  gap="m"
>
  <UiCluster
    gap="s"
  >
    <UiBadge
      shape="dot"
      tone="accent"
      variant="solid"
    >New messages</UiBadge>
    <span>New messages</span>
  </UiCluster>
  <UiCluster
    gap="s"
  >
    <UiBadge
      shape="dot"
      tone="warning"
    >Waiting for your reply</UiBadge>
    <span>Waiting for your reply</span>
  </UiCluster>
</UiCluster>
import { Component } from "@angular/core";
import { UiBadge, UiCluster } from "@threadlabs/looma";

@Component({
  selector: "example-view",
  standalone: true,
  imports: [UiCluster, UiBadge],
  template: `
    <div
      ui-cluster
      [gap]="'m'"
    >
      <div
        ui-cluster
        [gap]="'s'"
      >
        <span
          ui-badge
          [shape]="'dot'"
          [tone]="'accent'"
          [variant]="'solid'"
        >New messages</span>
        <span>New messages</span>
      </div>
      <div
        ui-cluster
        [gap]="'s'"
      >
        <span
          ui-badge
          [shape]="'dot'"
          [tone]="'warning'"
        >Waiting for your reply</span>
        <span>Waiting for your reply</span>
      </div>
    </div>
  `,
})
export default class Example {}

Leading icon

The icon slot centers a decorative glyph beside the label. Only the label truncates in constrained space.

Ready Attention Confirmed

Code

<link
  rel="component"
  href="@threadlabs/looma/components/ui-badge/ui-badge.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-icon/ui-icon.html"
>

<ui-badge
  tone="success"
>
  <ui-icon
    slot="icon"
    name="check"
  ></ui-icon>
  Ready
</ui-badge>
<ui-badge
  tone="warning"
>
  <ui-icon
    slot="icon"
    name="triangle-alert"
  ></ui-icon>
  Attention
</ui-badge>
<ui-badge
  tone="info"
><svg
    width="16"
    height="16"
    viewBox="0 0 24 24"
    aria-hidden="true"
  >
    <path
      d="m5 12 4 4 10-10"
      fill="none"
      stroke="currentColor"
      stroke-width="2"
    ></path>
  </svg>Confirmed</ui-badge>
<script setup>
  import { UiBadge, UiIcon } from "@threadlabs/looma";
</script>

<template>
  <UiBadge
    tone="success"
  ><template #icon>
      <UiIcon
        name="check"
      />
    </template>Ready</UiBadge>
  <UiBadge
    tone="warning"
  ><template #icon>
      <UiIcon
        name="triangle-alert"
      />
    </template>Attention</UiBadge>
  <UiBadge
    tone="info"
  ><svg
      width="16"
      height="16"
      viewBox="0 0 24 24"
      aria-hidden="true"
    >
      <path
        d="m5 12 4 4 10-10"
        fill="none"
        stroke="currentColor"
        stroke-width="2"
      ></path>
    </svg>Confirmed</UiBadge>
</template>
import { UiBadge, UiIcon } from "@threadlabs/looma";

export default function Example() {
  return <>
    <UiBadge
      tone="success"
      slots={{
        icon: <UiIcon
          name="check"
        />,
      }}
    >Ready</UiBadge>
    <UiBadge
      tone="warning"
      slots={{
        icon: <UiIcon
          name="triangle-alert"
        />,
      }}
    >Attention</UiBadge>
    <UiBadge
      tone="info"
    ><svg
        width="16"
        height="16"
        viewBox="0 0 24 24"
        aria-hidden="true"
      >
        <path
          d="m5 12 4 4 10-10"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
        />
      </svg>Confirmed</UiBadge>
  </>;
}
/** @jsxImportSource preact */
import { UiBadge, UiIcon } from "@threadlabs/looma";

export default function Example() {
  return <>
    <UiBadge
      tone="success"
      slots={{
        icon: <UiIcon
          name="check"
        />,
      }}
    >Ready</UiBadge>
    <UiBadge
      tone="warning"
      slots={{
        icon: <UiIcon
          name="triangle-alert"
        />,
      }}
    >Attention</UiBadge>
    <UiBadge
      tone="info"
    ><svg
        width="16"
        height="16"
        viewBox="0 0 24 24"
        aria-hidden="true"
      >
        <path
          d="m5 12 4 4 10-10"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
        />
      </svg>Confirmed</UiBadge>
  </>;
}
<script>
  import { UiBadge, UiIcon } from "@threadlabs/looma";
</script>

{#snippet icon()}
  <UiIcon
    name="check"
  />
{/snippet}

{#snippet badgeIcon()}
  <UiIcon
    name="triangle-alert"
  />
{/snippet}

<UiBadge
  tone="success"
  slots={{ icon }}
>Ready</UiBadge>
<UiBadge
  tone="warning"
  slots={{ icon: badgeIcon }}
>Attention</UiBadge>
<UiBadge
  tone="info"
><svg
    width="16"
    height="16"
    viewBox="0 0 24 24"
    aria-hidden="true"
  >
    <path
      d="m5 12 4 4 10-10"
      fill="none"
      stroke="currentColor"
      stroke-width="2"
    ></path>
  </svg>Confirmed</UiBadge>
import { Component } from "@angular/core";
import { UiBadge, UiIcon } from "@threadlabs/looma";

@Component({
  selector: "example-view",
  standalone: true,
  imports: [UiBadge, UiIcon],
  template: `
    <span
      ui-badge
      [tone]="'success'"
    ><ng-container ngProjectAs="[slot='icon']">
        <span
          ui-icon
          name="check"
        ></span>
      </ng-container>Ready</span>
    <span
      ui-badge
      [tone]="'warning'"
    ><ng-container ngProjectAs="[slot='icon']">
        <span
          ui-icon
          name="triangle-alert"
        ></span>
      </ng-container>Attention</span>
    <span
      ui-badge
      [tone]="'info'"
    ><svg
        width="16"
        height="16"
        viewBox="0 0 24 24"
        aria-hidden="true"
      >
        <path
          d="m5 12 4 4 10-10"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
        ></path>
      </svg>Confirmed</span>
  `,
})
export default class Example {}

Icon marks

A rounded square groups a decorative icon with its heading. It reuses the badge tones, global radius and spacing; the words convey the meaning.

Published

Needs attention

Code

<link
  rel="component"
  href="@threadlabs/looma/components/ui-cluster/ui-cluster.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-badge/ui-badge.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-icon/ui-icon.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-text/ui-text.html"
>

<ui-cluster
  gap="m"
>
  <ui-cluster
    gap="s"
  >
    <ui-badge
      shape="square"
      tone="success"
      aria-hidden="true"
    >
      <ui-icon
        name="check"
      ></ui-icon>
    </ui-badge>
    <ui-text
      as="h2"
      size="lg"
      weight="semibold"
    >Published</ui-text>
  </ui-cluster>
  <ui-cluster
    gap="s"
  >
    <ui-badge
      shape="square"
      tone="warning"
      aria-hidden="true"
    >
      <ui-icon
        name="triangle-alert"
      ></ui-icon>
    </ui-badge>
    <ui-text
      as="h2"
      size="lg"
      weight="semibold"
    >Needs attention</ui-text>
  </ui-cluster>
  <ui-badge
    shape="square"
    size="xs"
    role="img"
    aria-label="New messages"
  >
    <ui-icon
      name="bell"
    ></ui-icon>
  </ui-badge>
  <ui-badge
    shape="square"
    size="lg"
    role="img"
    aria-label="New messages"
  >
    <ui-icon
      name="bell"
    ></ui-icon>
  </ui-badge>
</ui-cluster>
<script setup>
  import { UiBadge, UiCluster, UiIcon, UiText } from "@threadlabs/looma";
</script>

<template>
  <UiCluster
    gap="m"
  >
    <UiCluster
      gap="s"
    >
      <UiBadge
        shape="square"
        tone="success"
        aria-hidden="true"
      >
        <UiIcon
          name="check"
        />
      </UiBadge>
      <UiText
        as="h2"
        size="lg"
        weight="semibold"
      >Published</UiText>
    </UiCluster>
    <UiCluster
      gap="s"
    >
      <UiBadge
        shape="square"
        tone="warning"
        aria-hidden="true"
      >
        <UiIcon
          name="triangle-alert"
        />
      </UiBadge>
      <UiText
        as="h2"
        size="lg"
        weight="semibold"
      >Needs attention</UiText>
    </UiCluster>
    <UiBadge
      shape="square"
      size="xs"
      role="img"
      aria-label="New messages"
    >
      <UiIcon
        name="bell"
      />
    </UiBadge>
    <UiBadge
      shape="square"
      size="lg"
      role="img"
      aria-label="New messages"
    >
      <UiIcon
        name="bell"
      />
    </UiBadge>
  </UiCluster>
</template>
import { UiBadge, UiCluster, UiIcon, UiText } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="m"
  >
    <UiCluster
      gap="s"
    >
      <UiBadge
        shape="square"
        tone="success"
        aria-hidden="true"
      >
        <UiIcon
          name="check"
        />
      </UiBadge>
      <UiText
        as="h2"
        size="lg"
        weight="semibold"
      >Published</UiText>
    </UiCluster>
    <UiCluster
      gap="s"
    >
      <UiBadge
        shape="square"
        tone="warning"
        aria-hidden="true"
      >
        <UiIcon
          name="triangle-alert"
        />
      </UiBadge>
      <UiText
        as="h2"
        size="lg"
        weight="semibold"
      >Needs attention</UiText>
    </UiCluster>
    <UiBadge
      shape="square"
      size="xs"
      role="img"
      aria-label="New messages"
    >
      <UiIcon
        name="bell"
      />
    </UiBadge>
    <UiBadge
      shape="square"
      size="lg"
      role="img"
      aria-label="New messages"
    >
      <UiIcon
        name="bell"
      />
    </UiBadge>
  </UiCluster>;
}
/** @jsxImportSource preact */
import { UiBadge, UiCluster, UiIcon, UiText } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="m"
  >
    <UiCluster
      gap="s"
    >
      <UiBadge
        shape="square"
        tone="success"
        aria-hidden="true"
      >
        <UiIcon
          name="check"
        />
      </UiBadge>
      <UiText
        as="h2"
        size="lg"
        weight="semibold"
      >Published</UiText>
    </UiCluster>
    <UiCluster
      gap="s"
    >
      <UiBadge
        shape="square"
        tone="warning"
        aria-hidden="true"
      >
        <UiIcon
          name="triangle-alert"
        />
      </UiBadge>
      <UiText
        as="h2"
        size="lg"
        weight="semibold"
      >Needs attention</UiText>
    </UiCluster>
    <UiBadge
      shape="square"
      size="xs"
      role="img"
      aria-label="New messages"
    >
      <UiIcon
        name="bell"
      />
    </UiBadge>
    <UiBadge
      shape="square"
      size="lg"
      role="img"
      aria-label="New messages"
    >
      <UiIcon
        name="bell"
      />
    </UiBadge>
  </UiCluster>;
}
<script>
  import { UiBadge, UiCluster, UiIcon, UiText } from "@threadlabs/looma";
</script>

<UiCluster
  gap="m"
>
  <UiCluster
    gap="s"
  >
    <UiBadge
      shape="square"
      tone="success"
      aria-hidden="true"
    >
      <UiIcon
        name="check"
      />
    </UiBadge>
    <UiText
      as="h2"
      size="lg"
      weight="semibold"
    >Published</UiText>
  </UiCluster>
  <UiCluster
    gap="s"
  >
    <UiBadge
      shape="square"
      tone="warning"
      aria-hidden="true"
    >
      <UiIcon
        name="triangle-alert"
      />
    </UiBadge>
    <UiText
      as="h2"
      size="lg"
      weight="semibold"
    >Needs attention</UiText>
  </UiCluster>
  <UiBadge
    shape="square"
    size="xs"
    role="img"
    aria-label="New messages"
  >
    <UiIcon
      name="bell"
    />
  </UiBadge>
  <UiBadge
    shape="square"
    size="lg"
    role="img"
    aria-label="New messages"
  >
    <UiIcon
      name="bell"
    />
  </UiBadge>
</UiCluster>
import { Component } from "@angular/core";
import { UiBadge, UiCluster, UiIcon, UiText } from "@threadlabs/looma";

@Component({
  selector: "example-view",
  standalone: true,
  imports: [UiCluster, UiBadge, UiIcon, UiText],
  template: `
    <div
      ui-cluster
      [gap]="'m'"
    >
      <div
        ui-cluster
        [gap]="'s'"
      >
        <span
          ui-badge
          [shape]="'square'"
          [tone]="'success'"
          aria-hidden="true"
        >
          <span
            ui-icon
            name="check"
          ></span>
        </span>
        <ng-template
          ui-text
          [as]="'h2'"
          [size]="'lg'"
          [weight]="'semibold'"
        >Published</ng-template>
      </div>
      <div
        ui-cluster
        [gap]="'s'"
      >
        <span
          ui-badge
          [shape]="'square'"
          [tone]="'warning'"
          aria-hidden="true"
        >
          <span
            ui-icon
            name="triangle-alert"
          ></span>
        </span>
        <ng-template
          ui-text
          [as]="'h2'"
          [size]="'lg'"
          [weight]="'semibold'"
        >Needs attention</ng-template>
      </div>
      <span
        ui-badge
        [shape]="'square'"
        [size]="'xs'"
        role="img"
        aria-label="New messages"
      >
        <span
          ui-icon
          name="bell"
        ></span>
      </span>
      <span
        ui-badge
        [shape]="'square'"
        [size]="'lg'"
        role="img"
        aria-label="New messages"
      >
        <span
          ui-icon
          name="bell"
        ></span>
      </span>
    </div>
  `,
})
export default class Example {}

Circular marks

Circles center a visible glyph, icon or short bounded count. The large circle fits 30 and 99+; an inverse counter reuses the same Badge inside a filled action. Name the full count on the action.

A B 30 99+

Code

<link
  rel="component"
  href="@threadlabs/looma/components/ui-cluster/ui-cluster.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-badge/ui-badge.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-icon/ui-icon.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-button/ui-button.html"
>

<ui-cluster
  gap="m"
>
  <ui-badge
    shape="circle"
    size="xs"
    variant="outline"
    tone="neutral"
    aria-label="Category A"
  >A</ui-badge>
  <ui-badge
    shape="circle"
    variant="outline"
    tone="accent"
    aria-label="Category B"
  >B</ui-badge>
  <ui-badge
    shape="circle"
    tone="success"
    role="img"
    aria-label="Complete"
  >
    <ui-icon
      name="check"
    ></ui-icon>
  </ui-badge>
  <ui-badge
    shape="circle"
    size="lg"
    aria-label="30 items"
  >30</ui-badge>
  <ui-badge
    shape="circle"
    size="lg"
    aria-label="More than 99 items"
  >99+</ui-badge>
  <ui-button
    variant="solid"
    size="sm"
    aria-label="Submit 120 items"
  >Submit <ui-badge
      shape="circle"
      size="lg"
      tone="accent"
      variant="inverse"
      aria-hidden="true"
    >99+</ui-badge></ui-button>
</ui-cluster>
<script setup>
  import { UiBadge, UiButton, UiCluster, UiIcon } from "@threadlabs/looma";
</script>

<template>
  <UiCluster
    gap="m"
  >
    <UiBadge
      shape="circle"
      size="xs"
      variant="outline"
      tone="neutral"
      aria-label="Category A"
    >A</UiBadge>
    <UiBadge
      shape="circle"
      variant="outline"
      tone="accent"
      aria-label="Category B"
    >B</UiBadge>
    <UiBadge
      shape="circle"
      tone="success"
      role="img"
      aria-label="Complete"
    >
      <UiIcon
        name="check"
      />
    </UiBadge>
    <UiBadge
      shape="circle"
      size="lg"
      aria-label="30 items"
    >30</UiBadge>
    <UiBadge
      shape="circle"
      size="lg"
      aria-label="More than 99 items"
    >99+</UiBadge>
    <UiButton
      variant="solid"
      size="sm"
      aria-label="Submit 120 items"
    >Submit <UiBadge
        shape="circle"
        size="lg"
        tone="accent"
        variant="inverse"
        aria-hidden="true"
      >99+</UiBadge></UiButton>
  </UiCluster>
</template>
import { UiBadge, UiButton, UiCluster, UiIcon } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="m"
  >
    <UiBadge
      shape="circle"
      size="xs"
      variant="outline"
      tone="neutral"
      aria-label="Category A"
    >A</UiBadge>
    <UiBadge
      shape="circle"
      variant="outline"
      tone="accent"
      aria-label="Category B"
    >B</UiBadge>
    <UiBadge
      shape="circle"
      tone="success"
      role="img"
      aria-label="Complete"
    >
      <UiIcon
        name="check"
      />
    </UiBadge>
    <UiBadge
      shape="circle"
      size="lg"
      aria-label="30 items"
    >30</UiBadge>
    <UiBadge
      shape="circle"
      size="lg"
      aria-label="More than 99 items"
    >99+</UiBadge>
    <UiButton
      variant="solid"
      size="sm"
      aria-label="Submit 120 items"
    >Submit <UiBadge
        shape="circle"
        size="lg"
        tone="accent"
        variant="inverse"
        aria-hidden="true"
      >99+</UiBadge></UiButton>
  </UiCluster>;
}
/** @jsxImportSource preact */
import { UiBadge, UiButton, UiCluster, UiIcon } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster
    gap="m"
  >
    <UiBadge
      shape="circle"
      size="xs"
      variant="outline"
      tone="neutral"
      aria-label="Category A"
    >A</UiBadge>
    <UiBadge
      shape="circle"
      variant="outline"
      tone="accent"
      aria-label="Category B"
    >B</UiBadge>
    <UiBadge
      shape="circle"
      tone="success"
      role="img"
      aria-label="Complete"
    >
      <UiIcon
        name="check"
      />
    </UiBadge>
    <UiBadge
      shape="circle"
      size="lg"
      aria-label="30 items"
    >30</UiBadge>
    <UiBadge
      shape="circle"
      size="lg"
      aria-label="More than 99 items"
    >99+</UiBadge>
    <UiButton
      variant="solid"
      size="sm"
      aria-label="Submit 120 items"
    >Submit <UiBadge
        shape="circle"
        size="lg"
        tone="accent"
        variant="inverse"
        aria-hidden="true"
      >99+</UiBadge></UiButton>
  </UiCluster>;
}
<script>
  import { UiBadge, UiButton, UiCluster, UiIcon } from "@threadlabs/looma";
</script>

<UiCluster
  gap="m"
>
  <UiBadge
    shape="circle"
    size="xs"
    variant="outline"
    tone="neutral"
    aria-label="Category A"
  >A</UiBadge>
  <UiBadge
    shape="circle"
    variant="outline"
    tone="accent"
    aria-label="Category B"
  >B</UiBadge>
  <UiBadge
    shape="circle"
    tone="success"
    role="img"
    aria-label="Complete"
  >
    <UiIcon
      name="check"
    />
  </UiBadge>
  <UiBadge
    shape="circle"
    size="lg"
    aria-label="30 items"
  >30</UiBadge>
  <UiBadge
    shape="circle"
    size="lg"
    aria-label="More than 99 items"
  >99+</UiBadge>
  <UiButton
    variant="solid"
    size="sm"
    aria-label="Submit 120 items"
  >Submit <UiBadge
      shape="circle"
      size="lg"
      tone="accent"
      variant="inverse"
      aria-hidden="true"
    >99+</UiBadge></UiButton>
</UiCluster>
import { Component } from "@angular/core";
import { UiBadge, UiButton, UiCluster, UiIcon } from "@threadlabs/looma";

@Component({
  selector: "example-view",
  standalone: true,
  imports: [UiCluster, UiBadge, UiIcon, UiButton],
  template: `
    <div
      ui-cluster
      [gap]="'m'"
    >
      <span
        ui-badge
        [shape]="'circle'"
        [size]="'xs'"
        [variant]="'outline'"
        [tone]="'neutral'"
        aria-label="Category A"
      >A</span>
      <span
        ui-badge
        [shape]="'circle'"
        [variant]="'outline'"
        [tone]="'accent'"
        aria-label="Category B"
      >B</span>
      <span
        ui-badge
        [shape]="'circle'"
        [tone]="'success'"
        role="img"
        aria-label="Complete"
      >
        <span
          ui-icon
          name="check"
        ></span>
      </span>
      <span
        ui-badge
        [shape]="'circle'"
        [size]="'lg'"
        aria-label="30 items"
      >30</span>
      <span
        ui-badge
        [shape]="'circle'"
        [size]="'lg'"
        aria-label="More than 99 items"
      >99+</span>
      <ng-template
        ui-button
        [variant]="'solid'"
        [size]="'sm'"
        [hnAttributes]="{ 'aria-label': 'Submit 120 items' }"
      >Submit <span
          ui-badge
          [shape]="'circle'"
          [size]="'lg'"
          [tone]="'accent'"
          [variant]="'inverse'"
          aria-hidden="true"
        >99+</span></ng-template>
    </div>
  `,
})
export default class Example {}

API

Package: @threadlabs/looma · Native root: span

Attributes

NameDescriptionPropertyTypeDefaultAllowed values
shapeSilhouette. pill is rounded at both ends; tag is a pointed label. dot is a compact circular signal with visually hidden text: include a state label, or set aria-hidden when the surrounding control already names that state. square is a fixed rounded square for an icon or single glyph beside a heading; hide a decorative icon when adjacent words name it. circle frames a visible glyph, icon or short bounded count in a fixed circle, centered in both directions.shapekeywordpillpill, tag, dot, square, circle
sizeScale. xs is compact; sm keeps the usual badge geometry with compact text, fitting short counts such as 99+ inside a 24px circle. md is the usual text badge; lg adds room to fixed marks while retaining the usual text size. A square is 24px at xs, 32px at sm and md, and 40px at lg. A circle is 16px at xs, 24px at sm and md, and 32px at lg. A small overlay circle is 20px.sizekeywordmdxs, sm, md, lg
toneWhich colour the badge speaks in. neutral is a quiet grey for plain labels; accent draws the eye in the accent colour; info, success, warning, and danger mark a status, so match the tone to what the badge says. For a category rather than a status, set the --ui-badge-color hook on the badge instead: any CSS colour, which overrides the tone. Supporting brand families use accent-secondary and accent-tertiary; their usable colors derive from the theme, and unset families follow the primary accent.tonekeywordneutralneutral, accent, accent-secondary, accent-tertiary, info, success, warning, danger
variantEmphasis. subtle sets toned text over a soft wash; solid fills with the tone and uses contrasting text; outline keeps the surface with a toned edge. inverse uses a translucent contrasting surface and toned ink for a count or label on a filled control of that tone. Neutral looks the same in solid and subtle. overlay inherits the containing filled control's text colour on a faint translucent fill, with a quiet single-pixel boundary and no shadow. Its small circle is 20px. When space is constrained, the label truncates with an ellipsis while its full text remains available.variantkeywordsubtlesolid, subtle, outline, inverse, overlay

Framework props

NameTypeDefaultAllowed values
shape"pill" | "tag" | "dot" | "square" | "circle"pillpill, tag, dot, square, circle
size"xs" | "sm" | "md" | "lg"mdxs, sm, md, lg
tone"neutral" | "accent" | "accent-secondary" | "accent-tertiary" | "info" | "success" | "warning" | "danger"neutralneutral, accent, accent-secondary, accent-tertiary, info, success, warning, danger
variant"solid" | "subtle" | "outline" | "inverse" | "overlay"subtlesolid, subtle, outline, inverse, overlay

Events

No events.

Slots

NamePurpose
iconNamed content for the icon region.
defaultDefault child content.

Design tokens

Set shared theme properties on a theme boundary. Component hooks apply only to their owning component.

Component tokens

TokenDeclared valuesFallback
--_badge-color-bordercolor-mix(in srgb, var(--_badge-color-wash) 75%, var(--_badge-color-ink) 25%) | var(--_badge-color-ink) | var(--_badge-color-surface) | light-dark( color-mix(in srgb, color-mix(in oklab, var(--_ui-badge-color) 0%, var(--ui-surface-default)) 88%, transparent), color-mix(in srgb, color-mix(in oklab, var(--_ui-badge-color) 0%, var(--ui-surface-default)) 44%, transparent) ) | color-mix(in srgb, var(--_badge-surface) 75%, var(--_badge-text) 25%) | var(--ui-accent-secondary-strong-surface, var(--ui-accent-secondary-solid)) | var(--ui-accent-tertiary-strong-surface, var(--ui-accent-tertiary-solid)) | var(--ui-accent-secondary-soft-border) | var(--ui-accent-tertiary-soft-border) | var(--ui-accent-secondary-solid) | var(--ui-accent-tertiary-solid) | var(--ui-accent-strong-surface, var(--ui-accent-solid)) | var(--ui-danger-strong-surface, var(--ui-danger-solid)) | var(--ui-success-strong-surface, var(--ui-success-solid)) | var(--ui-warning-strong-surface, var(--ui-warning-solid)) | var(--ui-info-strong-surface, var(--ui-info-solid)) | var(--ui-accent-soft-border) | var(--ui-danger-soft-border) | var(--ui-success-soft-border) | var(--ui-warning-soft-border) | var(--ui-info-soft-border) | var(--ui-border-strong) | var(--ui-accent-solid) | var(--ui-danger-solid) | var(--ui-success-solid) | var(--ui-warning-solid) | var(--ui-info-solid) | var(--ui-badge-surface, var(--_badge-color-surface, var(--_badge-surface))) | var(--ui-badge-surface, var(--_badge-color-surface, color-mix(in srgb, var(--_badge-text) 88%, transparent))) | var(--ui-badge-surface, var(--_badge-color-surface, var(--_badge-count-surface))) | var(--ui-badge-surface, color-mix(in srgb, currentColor 6%, transparent)) | var(--ui-badge-surface, var(--_badge-color-surface, color-mix(in srgb, var(--ui-surface-raised) 88%, transparent))) | var( --ui-badge-surface, var( --_badge-color-surface, light-dark( color-mix(in srgb, var(--ui-surface-raised) var(--ui-badge-circle-opacity, 66%), transparent), color-mix(in srgb, var(--ui-surface-raised) var(--ui-badge-circle-opacity, 56%), transparent) ) ) ) | var(--ui-text-secondary) | var(--ui-accent-secondary-on-strong, var(--ui-text-on-accent)) | var(--ui-accent-tertiary-on-strong, var(--ui-text-on-accent)) | var(--ui-accent-secondary-subtle-text, var(--ui-accent-secondary-solid)) | var(--ui-accent-tertiary-subtle-text, var(--ui-accent-tertiary-solid)) | var(--ui-accent-on-strong, var(--ui-text-on-accent)) | var(--ui-danger-on-strong, var(--ui-text-on-accent)) | var(--ui-success-on-strong, var(--ui-text-on-accent)) | var(--ui-warning-on-strong, var(--ui-text-on-accent)) | var(--ui-info-on-strong, var(--ui-text-on-accent)) | var(--ui-accent-subtle-text, var(--ui-accent-solid)) | var(--ui-danger-subtle-text, var(--ui-danger-solid)) | var(--ui-success-subtle-text, var(--ui-success-solid)) | var(--ui-warning-subtle-text, var(--ui-warning-solid)) | var(--ui-info-subtle-text, var(--ui-info-solid))color-mix(in srgb, var(--_badge-text) 88%, transparent) | light-dark(color-mix(in srgb, var(--_badge-text) 88%, transparent), color-mix(in srgb, var(--_badge-text) 44%, transparent))
--_badge-color-surfacevar(--_badge-color-wash) | var(--_badge-color-ink) | color-mix(in srgb, color-mix(in oklab, var(--_ui-badge-color) 0%, var(--ui-surface-default)) 88%, transparent) | light-dark( color-mix(in srgb, color-mix(in oklab, var(--_ui-badge-color) 0%, var(--ui-surface-default)) var(--ui-badge-circle-opacity, 66%), transparent), color-mix(in srgb, color-mix(in oklab, var(--_ui-badge-color) 0%, var(--ui-surface-default)) var(--ui-badge-circle-opacity, 56%), transparent) ) | initial | color-mix(in srgb, var(--ui-surface-subtle) 80%, var(--ui-surface-default)) | var(--ui-accent-secondary-strong-surface, var(--ui-accent-secondary-solid)) | var(--ui-accent-tertiary-strong-surface, var(--ui-accent-tertiary-solid)) | var(--ui-accent-secondary-soft) | var(--ui-accent-tertiary-soft) | var(--ui-accent-strong-surface, var(--ui-accent-solid)) | var(--ui-danger-strong-surface, var(--ui-danger-solid)) | var(--ui-success-strong-surface, var(--ui-success-solid)) | var(--ui-warning-strong-surface, var(--ui-warning-solid)) | var(--ui-info-strong-surface, var(--ui-info-solid)) | var(--ui-accent-soft) | var(--ui-danger-soft) | var(--ui-success-soft) | var(--ui-warning-soft) | var(--ui-info-soft) | var(--ui-surface-default) | light-dark( color-mix(in srgb, var(--_badge-text) var(--ui-badge-circle-opacity, 66%), transparent), color-mix(in srgb, var(--_badge-text) var(--ui-badge-circle-opacity, 56%), transparent) )color-mix(in srgb, var(--_badge-text) 88%, transparent) | color-mix(in srgb, var(--ui-surface-raised) 88%, transparent) | light-dark( color-mix(in srgb, var(--ui-surface-raised) var(--ui-badge-circle-opacity, 66%), transparent), color-mix(in srgb, var(--ui-surface-raised) var(--ui-badge-circle-opacity, 56%), transparent) )
--_badge-color-textvar(--_badge-color-ink) | color-mix(in oklab, var(--_ui-badge-color) 0%, var(--ui-surface-default)) | color-mix(in srgb, var(--_badge-color-ink) 85%, var(--ui-text-primary)) | light-dark( color-mix(in srgb, var(--_badge-color-ink) 65%, var(--ui-text-primary)), color-mix(in oklab, var(--_ui-badge-color) 0%, var(--ui-text-primary)) ) | var(--ui-text-secondary) | var(--ui-accent-secondary-on-strong, var(--ui-text-on-accent)) | var(--ui-accent-tertiary-on-strong, var(--ui-text-on-accent)) | var(--ui-accent-secondary-subtle-text, var(--ui-accent-secondary-solid)) | var(--ui-accent-tertiary-subtle-text, var(--ui-accent-tertiary-solid)) | var(--ui-accent-on-strong, var(--ui-text-on-accent)) | var(--ui-danger-on-strong, var(--ui-text-on-accent)) | var(--ui-success-on-strong, var(--ui-text-on-accent)) | var(--ui-warning-on-strong, var(--ui-text-on-accent)) | var(--ui-info-on-strong, var(--ui-text-on-accent)) | var(--ui-accent-subtle-text, var(--ui-accent-solid)) | var(--ui-danger-subtle-text, var(--ui-danger-solid)) | var(--ui-success-subtle-text, var(--ui-success-solid)) | var(--ui-warning-subtle-text, var(--ui-warning-solid)) | var(--ui-info-subtle-text, var(--ui-info-solid))color-mix(in srgb, var(--_badge-surface) 85%, var(--_badge-inverse-ink)) | color-mix(in srgb, var(--_badge-surface) 35%, var(--_badge-inverse-ink)) | var(--ui-text-primary)
--ui-badge-border—var(--_badge-color-border, var(--_badge-border)) | var(--_badge-color-border, color-mix(in srgb, var(--_badge-text) 88%, transparent)) | var(--_badge-color-border, light-dark(color-mix(in srgb, var(--_badge-text) 88%, transparent), color-mix(in srgb, var(--_badge-text) 44%, transparent))) | color-mix(in srgb, currentColor 20%, transparent) | var(--_badge-color-border, var(--_badge-outline-surface)) | var(--_badge-color-border, var(--_badge-text))
--ui-badge-circle-opacity—66% | 56%
--ui-badge-circle-size—calc(var(--ui-space-3) * 2) | calc(var(--ui-space-4) + var(--ui-space-1)) | var(--ui-space-4) | calc(var(--ui-space-4) * 2)
--ui-badge-color——
--ui-badge-dot-size—var(--ui-space-2)
--ui-badge-font-size—var(--ui-font-size-sm) | var(--ui-font-size-2xs)
--ui-badge-font-weight—var(--ui-font-medium)
--ui-badge-line-height—var(--ui-line-height-tight) | 1
--ui-badge-min-block-size—1.5rem | 1rem
--ui-badge-padding-block—var(--ui-space-0-5) | 0
--ui-badge-padding-inline—var(--ui-space-2) | var(--ui-space-1)
--ui-badge-point—var(--ui-space-2)
--ui-badge-square-size—calc(var(--ui-space-4) * 2) | calc(var(--ui-space-3) * 2) | calc(var(--ui-space-4) * 2 + var(--ui-space-2))
--ui-badge-surface—var(--_badge-color-surface, var(--_badge-surface)) | var(--_badge-color-surface, color-mix(in srgb, var(--_badge-text) 88%, transparent)) | var(--_badge-color-surface, var(--_badge-count-surface)) | color-mix(in srgb, currentColor 6%, transparent) | var(--_badge-color-surface, color-mix(in srgb, var(--ui-surface-raised) 88%, transparent)) | var( --_badge-color-surface, light-dark( color-mix(in srgb, var(--ui-surface-raised) var(--ui-badge-circle-opacity, 66%), transparent), color-mix(in srgb, var(--ui-surface-raised) var(--ui-badge-circle-opacity, 56%), transparent) ) )
--ui-badge-text—var(--_badge-color-text, var(--_badge-text)) | var(--_badge-color-text, color-mix(in srgb, var(--_badge-surface) 85%, var(--_badge-inverse-ink))) | var(--_badge-color-text, color-mix(in srgb, var(--_badge-surface) 35%, var(--_badge-inverse-ink))) | inherit | var(--_badge-color-text, var(--ui-text-primary))

Shared tokens

TokenFallback
--ui-accent-on-strongvar(--ui-text-on-accent)
--ui-accent-secondary-on-strongvar(--ui-text-on-accent)
--ui-accent-secondary-soft—
--ui-accent-secondary-soft-border—
--ui-accent-secondary-solid—
--ui-accent-secondary-strong-surfacevar(--ui-accent-secondary-solid)
--ui-accent-secondary-subtle-textvar(--ui-accent-secondary-solid)
--ui-accent-soft—
--ui-accent-soft-border—
--ui-accent-solid—
--ui-accent-strong-surfacevar(--ui-accent-solid)
--ui-accent-subtle-textvar(--ui-accent-solid)
--ui-accent-tertiary-on-strongvar(--ui-text-on-accent)
--ui-accent-tertiary-soft—
--ui-accent-tertiary-soft-border—
--ui-accent-tertiary-solid—
--ui-accent-tertiary-strong-surfacevar(--ui-accent-tertiary-solid)
--ui-accent-tertiary-subtle-textvar(--ui-accent-tertiary-solid)
--ui-border-strong—
--ui-border-width—
--ui-danger-on-strongvar(--ui-text-on-accent)
--ui-danger-soft—
--ui-danger-soft-border—
--ui-danger-solid—
--ui-danger-strong-surfacevar(--ui-danger-solid)
--ui-danger-subtle-textvar(--ui-danger-solid)
--ui-font-family-sans—
--ui-font-medium—
--ui-font-size-2xs—
--ui-font-size-sm—
--ui-info-on-strongvar(--ui-text-on-accent)
--ui-info-soft—
--ui-info-soft-border—
--ui-info-solid—
--ui-info-strong-surfacevar(--ui-info-solid)
--ui-info-subtle-textvar(--ui-info-solid)
--ui-line-height-tight—
--ui-radius-md—
--ui-radius-round—
--ui-space-0-5—
--ui-space-1—
--ui-space-2—
--ui-space-3—
--ui-space-4—
--ui-success-on-strongvar(--ui-text-on-accent)
--ui-success-soft—
--ui-success-soft-border—
--ui-success-solid—
--ui-success-strong-surfacevar(--ui-success-solid)
--ui-success-subtle-textvar(--ui-success-solid)
--ui-surface-default—
--ui-surface-raised—
--ui-surface-subtle—
--ui-text-on-accent—
--ui-text-primary—
--ui-text-secondary—
--ui-warning-on-strongvar(--ui-text-on-accent)
--ui-warning-soft—
--ui-warning-soft-border—
--ui-warning-solid—
--ui-warning-strong-surfacevar(--ui-warning-solid)
--ui-warning-subtle-textvar(--ui-warning-solid)