---
title: "Toggle"
description: "A button that can be pressed on or off."
canonical_url: "https://ui.nuxt.com/docs/components/toggle"
---
# Toggle

> A button that can be pressed on or off.

## Usage

Use the `v-model` directive to control the pressed state of the Toggle.

```vue
<script setup lang="ts">
const value = ref(true)
</script>

<template>
  <UToggle v-model="value" icon="i-lucide-bold" aria-label="Toggle bold" />
</template>
```

Use the `default-value` prop to set the initial value when you do not need to control its state.

```vue
<template>
  <UToggle default-value icon="i-lucide-bold" aria-label="Toggle bold" />
</template>
```

> [!NOTE]
> 
> The Toggle component extends the [Button](https://ui.nuxt.com/docs/components/button) component, so you can pass its properties such as `label`, `icon`, `size`, etc., except the link ones. It sets the `active` prop of the Button from its pressed state.

### Color

Use the `color` and `active-color` props to set the color of the Toggle when not pressed and when pressed. Defaults to `neutral` and `primary`.

```vue
<template>
  <UToggle color="neutral" active-color="neutral" default-value label="Bold" />
</template>
```

### Variant

Use the `variant` and `active-variant` props to set the variant of the Toggle when not pressed and when pressed. Defaults to `ghost` and `soft`.

```vue
<template>
  <UToggle variant="outline" active-variant="subtle" default-value label="Bold" />
</template>
```

### Disabled

Use the `disabled` prop to disable the Toggle.

```vue
<template>
  <UToggle disabled label="Bold" />
</template>
```

## Examples

### Style the pressed state

The Toggle renders `data-state="on"` when pressed, so you can style it with the `data-[state=on]` variant.

```vue
<template>
  <UToggle label="Bold" class="data-[state=on]:ring data-[state=on]:ring-primary" />
</template>
```

## API

### Props

```ts
/**
 * Props for the Toggle component
 */
interface ToggleProps {
  id?: string | undefined;
  /**
   * @default 'neutral'
   */
  color?: "error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral" | undefined;
  /**
   * @default 'ghost'
   */
  variant?: "solid" | "outline" | "soft" | "subtle" | "ghost" | "link" | undefined;
  /**
   * The color of the toggle when pressed.
   * @default 'primary'
   */
  activeColor?: "error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral" | undefined;
  /**
   * The variant of the toggle when pressed.
   * @default 'soft'
   */
  activeVariant?: "solid" | "outline" | "soft" | "subtle" | "ghost" | "link" | undefined;
  /**
   * The element or component this component should render as when not a link.
   * @default 'button'
   */
  as?: any;
  /**
   * Display an icon based on the `leading` and `trailing` props.
   */
  icon?: any;
  /**
   * Display an avatar on the left side.
   */
  avatar?: AvatarProps | undefined;
  ui?: { base?: SlotClass; label?: SlotClass; leadingIcon?: SlotClass; leadingAvatar?: SlotClass; leadingAvatarSize?: SlotClass; trailingIcon?: SlotClass; } | undefined;
  /**
   * Class to apply when the link is active
   */
  activeClass?: string | undefined;
  /**
   * The class to apply when the link is inactive.
   */
  inactiveClass?: string | undefined;
  /**
   * Class to apply when the link is exact active
   */
  exactActiveClass?: string | undefined;
  /**
   * Pass the returned promise of `router.push()` to `document.startViewTransition()` if supported.
   */
  viewTransition?: boolean | undefined;
  autofocus?: false | true | "true" | "false" | undefined;
  disabled?: boolean | undefined;
  form?: string | undefined;
  formaction?: string | undefined;
  formenctype?: string | undefined;
  formmethod?: string | undefined;
  formnovalidate?: false | true | "true" | "false" | undefined;
  formtarget?: string | undefined;
  name?: string | undefined;
  onClick?: (event: MouseEvent): void | ((event: MouseEvent) => void)[] | undefined;
  label?: string | undefined;
  /**
   * @default 'md'
   */
  size?: "md" | "xs" | "sm" | "lg" | "xl" | undefined;
  /**
   * Render the button with equal padding on all sides.
   */
  square?: boolean | undefined;
  /**
   * Render the button full width.
   */
  block?: boolean | undefined;
  /**
   * When `true`, the icon will be displayed on the left side.
   */
  leading?: boolean | undefined;
  /**
   * Display an icon on the left side.
   */
  leadingIcon?: any;
  /**
   * When `true`, the icon will be displayed on the right side.
   */
  trailing?: boolean | undefined;
  /**
   * Display an icon on the right side.
   */
  trailingIcon?: any;
  /**
   * When `true`, the loading icon will be displayed.
   */
  loading?: boolean | undefined;
  /**
   * The icon when the `loading` prop is `true`.
   * @default appConfig.ui.icons.loading
   */
  loadingIcon?: any;
  /**
   * The controlled pressed state of the toggle. Can be bind as `v-model`.
   * @default undefined
   */
  modelValue?: boolean | null | undefined;
  /**
   * The pressed state of the toggle when it is initially rendered. Use when you do not need to control its open state.
   */
  defaultValue?: boolean | undefined;
  /**
   * When `true`, indicates that the user must set the value before the owning form can be submitted.
   */
  required?: boolean | undefined;
}
```

### Slots

```ts
/**
 * Slots for the Toggle component
 */
interface ToggleSlots {
  leading(): any;
  default(): any;
  trailing(): any;
}
```

### Emits

```ts
/**
 * Emitted events for the Toggle component
 */
interface ToggleEmits {
  change: (payload: [event: Event]) => void;
  update:modelValue: (payload: [value: boolean]) => void;
}
```

## Changelog

See commit history for [component](https://github.com/nuxt/ui/commits/v4/src/runtime/components/Toggle.vue) and [theme](https://github.com/nuxt/ui/commits/v4/src/theme/toggle.ts).

---

- [Toggle](https://reka-ui.com/docs/components/toggle)
- [GitHub](https://github.com/nuxt/ui/blob/v4/src/runtime/components/Toggle.vue)


## Sitemap

See the full [sitemap](https://ui.nuxt.com/sitemap.md) for all pages.
