/Documentation

Badge

PublishedUpdated

A badge shows a count or a status on another element: unread messages on an icon, a new item in a navigation bar. A large badge holds up to four characters; a small one is a 6dp dot for news without a number. See the M3 badges guidelines.

Usage

Vanilla
import { createBadge } from 'mtrl';

const badge = createBadge({ label: 3 });
document.body.append(badge.element);
Web Components
<m-badge label="3"></m-badge>
React
import { Badge } from 'mtrl/react';

export function Example() {
  return (
    <Badge label="3" />
  );
}
Vue
<script setup lang="ts">
import { MBadge } from 'mtrl/vue';
</script>

<template>
  <MBadge label="3" />
</template>
Svelte
<script lang="ts">
  import { Badge } from 'mtrl/svelte';
</script>

<Badge label="3" />
SolidJS
import { Badge } from 'mtrl/solid';

export function Example() {
  return (
    <Badge label="3" />
  );
}

The factory's target wraps an element and puts the badge on its corner, set by position. The web component is the badge alone, placed where it is written. Navigation items and tabs take a badge of their own, through their badge option.

Examples

A maximum

Above max, a number shows as {max}+. A label longer than four characters is shortened: 12500 to 999+, text to its first four characters.

Vanilla
import { createBadge } from 'mtrl';

const badge = createBadge({ label: 1200, max: 999, color: 'primary' });
document.body.append(badge.element);
Web Components
<m-badge label="1200" max="999" color="primary"></m-badge>
React
import { Badge } from 'mtrl/react';

export function Example() {
  return (
    <Badge label="1200" max={999} color="primary" />
  );
}
Vue
<script setup lang="ts">
import { MBadge } from 'mtrl/vue';
</script>

<template>
  <MBadge label="1200" :max="999" color="primary" />
</template>
Svelte
<script lang="ts">
  import { Badge } from 'mtrl/svelte';
</script>

<Badge label="1200" max={999} color="primary" />
SolidJS
import { Badge } from 'mtrl/solid';

export function Example() {
  return (
    <Badge label="1200" max={999} color="primary" />
  );
}

Hidden at zero

An empty label or 0 hides the badge, and any other label shows it again.

Vanilla
import { createBadge } from 'mtrl';

const badge = createBadge({ label: 5 });
document.body.append(badge.element);

function markAllRead() {
  badge.setLabel(0);
}
Web Components
<m-badge label="5"></m-badge>

<script type="module">
  const badge = document.querySelector('m-badge');

  function markAllRead() {
    badge.setAttribute('label', "0");
  }
</script>
React
import { useState } from 'react';
import { Badge } from 'mtrl/react';

export function Example() {
  const [label, setLabel] = useState(5);
  const markAllRead = () => setLabel(0);

  return (
    <Badge label={label} />
  );
}
Vue
<script setup lang="ts">
import { ref } from 'vue';
import { MBadge } from 'mtrl/vue';

const label = ref(5);

function markAllRead() {
  label.value = 0;
}
</script>

<template>
  <MBadge :label="label" />
</template>
Svelte
<script lang="ts">
  import { Badge } from 'mtrl/svelte';

  let label = $state(5);

  function markAllRead() {
    label = 0;
  }
</script>

<Badge label={label} />
SolidJS
import { createSignal } from 'solid-js';
import { Badge } from 'mtrl/solid';

export function Example() {
  const [label, setLabel] = createSignal(5);
  const markAllRead = () => setLabel(0);

  return (
    <Badge label={label()} />
  );
}

API

Options

Option Type Default Description
label string | number '' What a large badge shows
variant 'small' | 'large' 'large' A dot, or a badge with a label
max number undefined Above it, a number shows as {max}+
color 'error' | 'primary' | 'secondary' | 'tertiary' | 'success' | 'warning' | 'info' 'error' Its color role
target HTMLElement undefined The element it is attached to, which it wraps; it needs a parent
position 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' 'top-right' Which corner of the target
visible boolean true Whether it starts shown
class string undefined Additional CSS classes
prefix string 'mtrl' Prefix for CSS class names

The web component takes label (or its text), variant, color and max as attributes, and visible as a property.

Methods

Method Parameters Returns Description
setLabel(label) / getLabel() label: string | number BadgeComponent / string The label, as shown; setting it hides the badge when it is empty or 0, and shows it otherwise
setContent(content) / getContent() content: string | number BadgeComponent / string The same as setLabel() and getLabel()
setMax(max) max: number BadgeComponent The maximum, applied to the label
show() / hide() / toggle(visible?) visible?: boolean BadgeComponent Shows or hides it
isVisible() none boolean Whether it is shown
setVariant(variant) / setColor(color) / setPosition(position) string BadgeComponent The variant, the color, the corner
attachTo(target) / detach() target: HTMLElement BadgeComponent Wraps a target and moves the badge onto it; detached, it moves to the end of document.body
addClass(...classes) / removeClass(...classes) ...classes: string[] BadgeComponent CSS classes
destroy() none void Removes it, and unwraps its target
Property Type Description
element HTMLElement The badge
wrapper HTMLElement | undefined The element wrapping the target and the badge

A badge has no events: it has on() and off(), and emits nothing.

Accessibility

  • A large badge has role="status", so a change of its label is announced.
  • A small badge is aria-hidden: name the element it is on with what it says, such as "Inbox, new messages".
  • A badge is not focusable; the element it is on takes the interaction.

Styling

.mtrl-badge, .mtrl-badge--small, .mtrl-badge--large { }
.mtrl-badge--error, .mtrl-badge--primary, .mtrl-badge--secondary, .mtrl-badge--tertiary { }
.mtrl-badge--success, .mtrl-badge--warning, .mtrl-badge--info { }
.mtrl-badge--positioned { }            /* on a target */
.mtrl-badge--top-right, .mtrl-badge--top-left, .mtrl-badge--bottom-right, .mtrl-badge--bottom-left { }
.mtrl-badge--invisible, .mtrl-badge--overflow { }
.mtrl-badge__wrapper { }               /* the target's wrapper */

Measurements

Attribute Value
Small 6dp dot, 3dp beyond the target's corner
Large 16dp high, at least 16dp wide, 8dp corners, 4dp padding, 8dp beyond the target's corner
Large, with a maximum 34dp wide at most
Colors The role and its on- pair: error and on-error by default