Toggle

A button-style toggle control that allows the user to switch between pressed (active) and unpressed (inactive) states. Unlike BrSwitch (which is a slider-style switch), BrToggle is a flat button that visually indicates its active state.

Component Features

  • 🔄 4 Visual Variants: Supports outline (default), solid, soft, ghost.
  • 🌈 Multiple Colors: Supports default, primary, secondary, success, warning, danger, info, carbon.
  • 📏 Multiple Sizes: Supports xs, sm, md, lg, xl, 2xl, default size specs.
  • 🖼️ Icon Support: Supports prefix and suffix slots for icons.
  • Loading State: Supports loading prop to display loading animation.
  • Disabled State: Supports disabled prop.
  • 📝 Readonly State: Supports readonly prop.
  • 🎨 Theme Customization: Based on BrConfigProvider for global theming and TailwindCSS local overrides.

Basic Usage

<script setup lang="ts">
import { ref } from 'vue'
import { BrToggle } from '@breezeui/vue'

const active = ref(false)
</script>

<template>
  <div class="flex items-center space-x-4">
    <BrToggle v-model="active">Toggle Button</BrToggle>
    <span class="text-sm text-muted-foreground">State: {{ active ? 'Pressed' : 'Unpressed' }}</span>
  </div>
</template>

Variants

Toggle supports four visual variants: outline (default), solid, soft, and ghost.

<script setup lang="ts">
import { ref } from 'vue'
import { BrToggle, BrFlex } from '@breezeui/vue'

const solid = ref(true)
const outline = ref(false)
const soft = ref(true)
const ghost = ref(false)
</script>

<template>
  <BrFlex gap="3" wrap>
    <BrToggle v-model="solid" variant="solid">Solid</BrToggle>
    <BrToggle v-model="outline" variant="outline">Outline</BrToggle>
    <BrToggle v-model="soft" variant="soft">Soft</BrToggle>
    <BrToggle v-model="ghost" variant="ghost">Ghost</BrToggle>
  </BrFlex>
</template>

Colors

Use the color prop to set the toggle's color theme.

<script setup lang="ts">
import { ref } from 'vue'
import { BrToggle, BrFlex } from '@breezeui/vue'

const states = ref<Record<string, boolean>>({
  default: false,
  primary: true,
  secondary: false,
  success: false,
  warning: false,
  danger: false,
  info: false,
})
</script>

<template>
  <BrFlex gap="3" wrap>
    <BrToggle v-model="states.default" color="default">Default</BrToggle>
    <BrToggle v-model="states.primary" color="primary">Primary</BrToggle>
    <BrToggle v-model="states.secondary" color="secondary">Secondary</BrToggle>
    <BrToggle v-model="states.success" color="success">Success</BrToggle>
    <BrToggle v-model="states.warning" color="warning">Warning</BrToggle>
    <BrToggle v-model="states.danger" color="danger">Danger</BrToggle>
    <BrToggle v-model="states.info" color="info">Info</BrToggle>
  </BrFlex>
</template>

Sizes

Use the size prop to control the toggle size.

<script setup lang="ts">
import { ref } from 'vue'
import { BrToggle, BrFlex } from '@breezeui/vue'

const states = ref<Record<string, boolean>>({
  xs: false,
  sm: true,
  md: false,
  lg: false,
  xl: false,
})
</script>

<template>
  <BrFlex align="center" gap="3" wrap>
    <BrToggle v-model="states.xs" size="xs">XS</BrToggle>
    <BrToggle v-model="states.sm" size="sm">Small</BrToggle>
    <BrToggle v-model="states.md" size="md">Medium</BrToggle>
    <BrToggle v-model="states.lg" size="lg">Large</BrToggle>
    <BrToggle v-model="states.xl" size="xl">Extra Large</BrToggle>
  </BrFlex>
</template>

With Icons

Toggle supports prefix and suffix icon slots for rich content.

<script setup lang="ts">
import { ref } from 'vue'
import { BrToggle, BrFlex } from '@breezeui/vue'
import { Bold, Italic, Underline, Star } from 'lucide-vue-next'

const bold = ref(false)
const italic = ref(false)
const underline = ref(false)
const starred = ref(true)
</script>

<template>
  <BrFlex gap="3" wrap>
    <BrToggle v-model="bold" variant="outline">
      <template #prefix><Bold class="h-4 w-4" /></template>
      Bold
    </BrToggle>
    <BrToggle v-model="italic" variant="outline">
      <template #prefix><Italic class="h-4 w-4" /></template>
      Italic
    </BrToggle>
    <BrToggle v-model="underline" variant="outline">
      <template #prefix><Underline class="h-4 w-4" /></template>
      Underline
    </BrToggle>
    <BrToggle v-model="starred" color="warning" variant="soft">
      <template #suffix><Star class="h-4 w-4" /></template>
      Favorite
    </BrToggle>
  </BrFlex>
</template>

Toolbar Example

A common use case is a toolbar with multiple toggle buttons for formatting options.

<script setup lang="ts">
import { ref } from 'vue'
import { BrToggle } from '@breezeui/vue'
import { Bold, Italic, Underline, AlignLeft, AlignCenter, AlignRight } from 'lucide-vue-next'

const bold = ref(false)
const italic = ref(false)
const underline = ref(false)
const alignLeft = ref(true)
const alignCenter = ref(false)
const alignRight = ref(false)
</script>

<template>
  <div class="border border-border rounded-lg p-2 inline-flex items-center gap-1">
    <BrToggle v-model="bold" variant="ghost" size="sm">
      <Bold class="h-4 w-4" />
    </BrToggle>
    <BrToggle v-model="italic" variant="ghost" size="sm">
      <Italic class="h-4 w-4" />
    </BrToggle>
    <BrToggle v-model="underline" variant="ghost" size="sm">
      <Underline class="h-4 w-4" />
    </BrToggle>
    <div class="w-px h-6 bg-border mx-1" />
    <BrToggle v-model="alignLeft" variant="ghost" size="sm">
      <AlignLeft class="h-4 w-4" />
    </BrToggle>
    <BrToggle v-model="alignCenter" variant="ghost" size="sm">
      <AlignCenter class="h-4 w-4" />
    </BrToggle>
    <BrToggle v-model="alignRight" variant="ghost" size="sm">
      <AlignRight class="h-4 w-4" />
    </BrToggle>
  </div>
</template>

Disabled State

Set the disabled prop to disable the toggle.

<script setup lang="ts">
import { ref } from 'vue'
import { BrToggle } from '@breezeui/vue'

const active = ref(true)
</script>

<template>
  <div class="flex items-center space-x-4">
    <BrToggle v-model="active" disabled>Disabled (Active)</BrToggle>
    <BrToggle :model-value="false" disabled>Disabled (Inactive)</BrToggle>
  </div>
</template>

Loading State

Set the loading prop to show a loading spinner. The toggle is disabled while loading.

<script setup lang="ts">
import { ref } from 'vue'
import { BrToggle } from '@breezeui/vue'

const active = ref(false)
</script>

<template>
  <div class="flex items-center space-x-4">
    <BrToggle v-model="active" loading>Loading</BrToggle>
  </div>
</template>

Theming

Global Customization (BrConfigProvider)

You can override default CSS variables via the theme prop of BrConfigProvider.

<template>
  <BrConfigProvider :theme="{ primary: '#8b5cf6' }">
    <BrToggle v-model="active" color="primary">Themed Toggle</BrToggle>
  </BrConfigProvider>
</template>

Local Customization (TailwindCSS)

You can directly override styles using TailwindCSS utility classes.

<template>
  <BrToggle v-model="active" class="rounded-full">Round Toggle</BrToggle>
</template>

Toggle vs Switch

FeatureBrToggleBrSwitch
StyleButton-style (flat)Slider-style (with thumb)
Visual cueBackground/color changeThumb slides left/right
Use caseToolbar actions, filtersSettings, on/off options
Icon supportPrefix/suffix slotsThumb slot

API

Props

NameTypeDefaultDescription
modelValuebooleanundefinedThe pressed state (v-model)
defaultValuebooleanfalseDefault pressed state for uncontrolled mode
variant'solid' | 'outline' | 'soft' | 'ghost''outline'Visual variant
color'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'carbon''default'Color theme
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'default''default'Size of the toggle
disabledbooleanfalseWhether the toggle is disabled
loadingbooleanfalseWhether to show loading state
readonlybooleanfalseWhether the toggle is readonly
type'button' | 'submit' | 'reset''button'Native button type
classany-Custom CSS class

Emits

NameDescriptionParameters
update:modelValueEmitted when pressed state changes(value: boolean)
changeEmitted when pressed state changes(value: boolean)

Slots

NameDescription
defaultDefault toggle content (text/icons)
prefixContent before the default slot
suffixContent after the default slot