Skip to content

Toggle

A button that stays pressed, for a formatting control or a filter chip.

View source View as Markdown

Toggle is a button that stays pressed once activated, and reports that state as aria-pressed. Useful for a formatting control or a filter chip; for a setting the user turns on and off, use Switch.

App.vue
<template>
  <div class="flex items-center gap-1" role="group" aria-label="Formatting">
    <Toggle.Root
      v-for="format in formats"
      :key="format.label"
      v-model="format.pressed"
      :aria-label="format.label"
      :class="[style, format.glyphClass]"
    >
      {{ format.glyph }}
    </Toggle.Root>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { Toggle } from '@maas/mirror/vue/Toggle'

const style = [
  'inline-flex size-10 items-center justify-center',
  'rounded-component-md border-2 border-[transparent] type-component-md',
  'text-primary-solid transition-all duration-100 ease-linear',
  'outline-4 outline-transparent focus-visible:focus-ring',
  'hover:bg-primary-subtle',
  'active:bg-primary-subtle-active',
  'data-[state=on]:bg-primary-solid data-[state=on]:text-primary-on-solid',
  'data-[state=on]:hover:bg-primary-solid-hover',
  'data-[state=on]:active:bg-primary-solid-active',
].join(' ')

const formats = ref([
  { label: 'Bold', glyph: 'B', glyphClass: 'font-bold', pressed: true },
  { label: 'Italic', glyph: 'I', glyphClass: 'italic', pressed: false },
  { label: 'Underline', glyph: 'U', glyphClass: 'underline', pressed: false },
])
</script>

Usage guidelines

  • A toggle whose content is a glyph has no accessible name, so give it an aria-label, as every example on this page does.must
  • Set name and value together, or neither, since a name without a value submits the browser’s default of on.should
  • Inside a Toggle.Group, value is required and the group owns the pressed state.must