ToggleButton

An interactive toggle control for on/off or selected/unselected states

Usage

import { ToggleButton } from '@hareui/vue'
<script setup lang="ts">import { Icon } from '@iconify/vue'import { ToggleButton } from '@hareui/vue'</script><template>  <ToggleButton>    <Icon icon="gravity-ui:heart" />    Like  </ToggleButton></template>

Examples

Variants

<script setup lang="ts">import { Icon } from '@iconify/vue'import { ToggleButton } from '@hareui/vue'</script><template>  <div class="flex items-center gap-3">    <ToggleButton>      <Icon icon="gravity-ui:heart" />      Default    </ToggleButton>    <ToggleButton variant="ghost">      <Icon icon="gravity-ui:heart" />      Ghost    </ToggleButton>  </div></template>

Icon Only

<script setup lang="ts">import { Icon } from '@iconify/vue'import { ToggleButton } from '@hareui/vue'</script><template>  <div class="flex items-center gap-3">    <ToggleButton icon-only aria-label="Like">      <Icon icon="gravity-ui:heart" />    </ToggleButton>    <ToggleButton icon-only aria-label="Bookmark" variant="ghost">      <Icon icon="gravity-ui:bookmark" />    </ToggleButton>  </div></template>

Sizes

<script setup lang="ts">import { Icon } from '@iconify/vue'import { ToggleButton } from '@hareui/vue'</script><template>  <div class="flex flex-col gap-6">    <div class="flex items-center gap-3">      <ToggleButton size="sm">        <Icon icon="gravity-ui:heart" />        Small      </ToggleButton>      <ToggleButton size="md">        <Icon icon="gravity-ui:heart" />        Medium      </ToggleButton>      <ToggleButton size="lg">        <Icon icon="gravity-ui:heart" />        Large      </ToggleButton>    </div>    <div class="flex items-center gap-3">      <ToggleButton icon-only aria-label="Like" size="sm">        <Icon icon="gravity-ui:heart" />      </ToggleButton>      <ToggleButton icon-only aria-label="Like" size="md">        <Icon icon="gravity-ui:heart" />      </ToggleButton>      <ToggleButton icon-only aria-label="Like" size="lg">        <Icon icon="gravity-ui:heart" />      </ToggleButton>    </div>  </div></template>

Disabled

<script setup lang="ts">import { Icon } from '@iconify/vue'import { ToggleButton } from '@hareui/vue'</script><template>  <div class="flex items-center gap-3">    <ToggleButton disabled>      <Icon icon="gravity-ui:heart" />      Like    </ToggleButton>    <ToggleButton default-value disabled>      <Icon icon="gravity-ui:heart-fill" />      Like    </ToggleButton>  </div></template>

Controlled

Bind the selected state with v-model. The default slot receives { selected, disabled } (HeroUI's render props).

Status: Not selected

<script setup lang="ts">import { Icon } from '@iconify/vue'import { ToggleButton } from '@hareui/vue'import { ref } from 'vue'const selected = ref(false)</script><template>  <div class="flex flex-col gap-4">    <ToggleButton v-slot="{ selected: isSelected }" v-model="selected">      <Icon :icon="isSelected ? 'gravity-ui:heart-fill' : 'gravity-ui:heart'" />      {{ isSelected ? 'Liked' : 'Like' }}    </ToggleButton>    <p class="text-sm text-muted">      Status: <span class="font-medium">{{ selected ? 'Selected' : 'Not selected' }}</span>    </p>  </div></template>

Customization

Tailwind CSS

<script setup lang="ts">import { Icon } from '@iconify/vue'import { ToggleButton } from '@hareui/vue'</script><template>  <ToggleButton class="gap-2 rounded-full border border-border/80 bg-surface px-4 text-foreground shadow-sm data-[selected=true]:border-accent/30 data-[selected=true]:bg-accent-soft data-[selected=true]:text-accent-soft-foreground [&_svg]:text-muted data-[selected=true]:[&_svg]:text-accent">    <Icon icon="gravity-ui:heart" />    Save article  </ToggleButton></template>

Global theme override

Override the toggleButton theme app-wide with createHareUI:

app.use(createHareUI({
  ui: {
    toggleButton: {
      slots: { base: 'bg-purple-500 text-white' },
      variants: { iconOnly: { true: { base: 'rounded-lg' } } },
    },
  },
}))

Styling Reference

The root carries data-slot="toggle-button", as in HeroUI. ui key: base.

Interactive States

  • Selected: [data-selected="true"] (accent background and foreground)
  • Hover: :hover
  • Active/Pressed: :active (includes scale transform)
  • Focus: :focus-visible (shows focus ring)
  • Disabled: :disabled or [aria-disabled="true"] (reduced opacity, no pointer events)

API Reference

Props

PropTypeDefaultDescription
asAsTag | Component"button"The element or component to render as.
variant"default" | "ghost"'default'Visual style of the toggle button.
size"md" | "sm" | "lg"'md'Size of the toggle button. Inside a ToggleButtonGroup, defaults to the group's size.
iconOnlybooleanfalseWhether the button only contains an icon (square shape).
disabledbooleanundefinedWhether the toggle button is disabled. Inside a disabled ToggleButtonGroup, :disabled="false" re-enables it.
modelValuebooleanundefinedThe selected state (controlled, v-model). Ignored inside a ToggleButtonGroup.
defaultValuebooleanfalseThe initial selected state when uncontrolled. Ignored inside a ToggleButtonGroup.
valuestring-Identifies the button inside a ToggleButtonGroup (HeroUI's id); the group's v-model holds these values.
uiComponentSlots<{ slots: { base: string[]; }; variants: { variant: { default: { base: string; }; ghost: { base: string; }; }; size: { sm: { base: string; }; md: { base: string; }; lg: { base: string; }; }; iconOnly: { true: { base: string; }; }; }; defaultVariants: { variant: string; size: string; iconOnly: boolean; }; }>-Per-slot class overrides.

Slots

SlotPropsDescription
defaultToggleButtonSlotPropsThe button content.

Emits

EventPayloadDescription
update:modelValue[value: boolean]-

On this page

No Headings