Toggle
Atomic toggle element
Unchecked
Toggles in the off state across all sizes.
Toggle Label
Toggle Label
Toggle Label
Toggle Label
Toggle Label
Toggle Label
<template>
<HLSpace align="center" justify="flex-start">
<HLToggle id="toggle-unchecked-3xs" v-model:value="value1" size="3xs" label="Toggle Label" />
<HLToggle id="toggle-unchecked-2xs" v-model:value="value2" size="2xs" label="Toggle Label" />
<HLToggle id="toggle-unchecked-xs" v-model:value="value3" size="xs" label="Toggle Label" />
</HLSpace>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { HLToggle, HLSpace } from '@platform-ui/highrise'
const value1 = ref(false)
const value2 = ref(false)
const value3 = ref(false)
</script>Checked
Toggles in the on state across all sizes.
Toggle Label
Toggle Label
Toggle Label
Toggle Label
Toggle Label
Toggle Label
<template>
<HLSpace align="center" justify="flex-start">
<HLToggle id="toggle-checked-3xs" v-model:value="value1" size="3xs" label="Toggle Label" />
<HLToggle id="toggle-checked-2xs" v-model:value="value2" size="2xs" label="Toggle Label" />
<HLToggle id="toggle-checked-xs" v-model:value="value3" size="xs" label="Toggle Label" />
</HLSpace>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { HLToggle, HLSpace } from '@platform-ui/highrise'
const value1 = ref(true)
const value2 = ref(true)
const value3 = ref(true)
</script>Disabled - Unchecked
Off-state toggles that are non-interactive via the disabled prop.
Toggle Label
Toggle Label
Toggle Label
Toggle Label
Toggle Label
Toggle Label
<template>
<HLSpace align="center" justify="flex-start">
<HLToggle id="toggle-disabled-unchecked-3xs" v-model:value="value1" disabled size="3xs" label="Toggle Label" />
<HLToggle id="toggle-disabled-unchecked-2xs" v-model:value="value2" disabled size="2xs" label="Toggle Label" />
<HLToggle id="toggle-disabled-unchecked-xs" v-model:value="value3" disabled size="xs" label="Toggle Label" />
</HLSpace>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { HLToggle, HLSpace } from '@platform-ui/highrise'
const value1 = ref(false)
const value2 = ref(false)
const value3 = ref(false)
</script>Disabled - Checked
On-state toggles that are non-interactive via the disabled prop.
Toggle Label
Toggle Label
Toggle Label
Toggle Label
Toggle Label
Toggle Label
<template>
<HLSpace align="center" justify="flex-start">
<HLToggle id="toggle-disabled-checked-3xs" v-model:value="value1" disabled size="3xs" label="Toggle Label" />
<HLToggle id="toggle-disabled-checked-2xs" v-model:value="value2" disabled size="2xs" label="Toggle Label" />
<HLToggle id="toggle-disabled-checked-xs" v-model:value="value3" disabled size="xs" label="Toggle Label" />
</HLSpace>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { HLToggle, HLSpace } from '@platform-ui/highrise'
const value1 = ref(true)
const value2 = ref(true)
const value3 = ref(true)
</script>Error - Checked
On-state toggles using variant="error" to show the error styling.
Toggle Label
Toggle Label
Toggle Label
Toggle Label
Toggle Label
Toggle Label
<template>
<HLSpace align="center" justify="flex-start">
<HLToggle id="toggle-error-checked-3xs" v-model:value="value1" variant="error" size="3xs" label="Toggle Label" />
<HLToggle id="toggle-error-checked-2xs" v-model:value="value2" variant="error" size="2xs" label="Toggle Label" />
<HLToggle id="toggle-error-checked-xs" v-model:value="value3" variant="error" size="xs" label="Toggle Label" />
</HLSpace>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { HLToggle, HLSpace } from '@platform-ui/highrise'
const value1 = ref(true)
const value2 = ref(true)
const value3 = ref(true)
</script>Error - Unchecked
Off-state toggles using variant="error" to show the error styling.
Toggle Label
Toggle Label
Toggle Label
Toggle Label
Toggle Label
Toggle Label
<template>
<HLSpace align="center" justify="flex-start">
<HLToggle id="toggle-error-unchecked-3xs" v-model:value="value1" variant="error" size="3xs" label="Toggle Label" />
<HLToggle id="toggle-error-unchecked-2xs" v-model:value="value2" variant="error" size="2xs" label="Toggle Label" />
<HLToggle id="toggle-error-unchecked-xs" v-model:value="value3" variant="error" size="xs" label="Toggle Label" />
</HLSpace>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { HLToggle, HLSpace } from '@platform-ui/highrise'
const value1 = ref(false)
const value2 = ref(false)
const value3 = ref(false)
</script>Loading
Set loading to show a spinner inside the toggle's handle while an async change is in flight — for example, while persisting the new state to a server.
Saving…
Saving…
<template>
<HLToggle id="toggle-loading-on" v-model:value="value" loading label="Saving…" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { HLToggle } from '@platform-ui/highrise'
const value = ref(true)
</script>Uncontrolled with defaultValue
Use defaultValue to set the starting state without binding v-model:value — the toggle then tracks its own state internally. Reach for this when you only care about the value at submit time and don't need it in reactive state.
INFO
defaultValue and value are alternatives, not partners. If you bind value (via v-model:value or :value), it drives the toggle and defaultValue is ignored.
Uncontrolled (starts on)
Controlled
<template>
<!-- Uncontrolled: no v-model, the toggle owns its state -->
<HLToggle id="toggle-uncontrolled" :default-value="true" label="Uncontrolled (starts on)" />
<!-- Controlled: the bound ref is the source of truth -->
<HLToggle id="toggle-controlled" v-model:value="value" label="Controlled" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { HLToggle } from '@platform-ui/highrise'
const value = ref(true)
</script>Custom Checked Values
By default the toggle emits true when on and false when off. Use checkedValue and uncheckedValue to emit your own values instead — handy when binding straight to an API that expects strings or numbers.
Notifications
Bound value: off
<template>
<HLToggle
id="toggle-custom-values"
v-model:value="value"
checked-value="on"
unchecked-value="off"
label="Notifications"
/>
<p>Bound value: {{ value }}</p>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { HLToggle } from '@platform-ui/highrise'
// Holds 'on' / 'off' rather than true / false
const value = ref('off')
</script>Event Testing
The toggle emits @update:value with its new value when toggled, and @label:click when its label is clicked. This example logs both.
Toggle me
Event Log:
<template>
<HLToggle
id="toggle-events"
v-model:value="value"
label="Toggle me"
@update:value="val => addEventLog('@update:value → ' + val)"
@label:click="addEventLog('@label:click')"
/>
<div class="text-sm">
<p class="font-bold mb-2">Event Log:</p>
<div v-if="eventLog.length === 0" class="text-gray-500">No events logged yet. Toggle or click the label above.</div>
<div v-for="(log, index) in eventLog" :key="index" class="text-gray-700">{{ log.timestamp }}: {{ log.event }}</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { HLToggle } from '@platform-ui/highrise'
const value = ref(false)
const eventLog = ref<{ event: string; timestamp: string }[]>([])
const addEventLog = (event: string) => {
eventLog.value.unshift({ event, timestamp: new Date().toLocaleTimeString() })
if (eventLog.value.length > 5) {
eventLog.value.pop()
}
}
</script>Accessibility
- Connect the toggle to visible text through
aria-labelledby(fallback toaria-labelfor icon-only controls). - Keep
aria-checkedsynchronized with the bound value. Whenvariant="error", the component emitsaria-invalid="true"automatically; in any other variantaria-invalidis omitted. - When the toggle controls another region, include
aria-controlsreferencing that region’s id.
Imports
import { HLToggle } from '@platform-ui/highrise'Props
| Name | Type | Default | Description |
|---|---|---|---|
| id | string | Auto (hr-toggle-*) | The unique identifier for the toggle. Generated when omitted. |
| checkedValue | string | number | boolean | true | The value when toggle is checked |
| defaultValue | boolean | undefined | Initial value for uncontrolled use — the toggle then manages its own state internally. Use this instead of value when you don't bind v-model:value; ignored when value is set. |
| disabled | boolean | false | Whether the toggle is disabled |
| loading | boolean | false | Whether the toggle is in loading state |
| size | 'lg' | 'md' | 'sm' | 'xs' | '2xs' | '3xs' | 'md' | The size of the toggle. Falls back to the surrounding HLToggleGroup size, then the HLForm size, then 'md'. |
| uncheckedValue | string | number | boolean | false | The value when toggle is unchecked |
| value | string | number | boolean | undefined | Current value for controlled use — bind with v-model:value (or pair :value with @update:value). When set, it drives the toggle and defaultValue is ignored. |
| label | string | undefined | The label text for the toggle |
| variant | 'default' | 'error' | 'default' | Visual state of the toggle. Set error to mark it as invalid: the track gains a red outline, the focus ring turns red, and the toggle is announced as invalid to screen readers. |
Emits
| Name | Parameters | Description |
|---|---|---|
@update:value | (value: string | number | boolean) => void | Emitted when toggle value changes |
@label:click | (event: Event)=> void | Emitted when toggle label is clicked |