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:
:disabledor[aria-disabled="true"](reduced opacity, no pointer events)
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
as | AsTag | 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. |
iconOnly | boolean | false | Whether the button only contains an icon (square shape). |
disabled | boolean | undefined | Whether the toggle button is disabled. Inside a disabled ToggleButtonGroup, :disabled="false" re-enables it. |
modelValue | boolean | undefined | The selected state (controlled, v-model). Ignored inside a ToggleButtonGroup. |
defaultValue | boolean | false | The initial selected state when uncontrolled. Ignored inside a ToggleButtonGroup. |
value | string | - | Identifies the button inside a ToggleButtonGroup (HeroUI's id); the group's v-model holds these values. |
ui | ComponentSlots<{ 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
| Slot | Props | Description |
|---|---|---|
default | ToggleButtonSlotProps | The button content. |
Emits
| Event | Payload | Description |
|---|---|---|
update:modelValue | [value: boolean] | - |



