Skip to content
RTL Support: Full
Accessibility: Full
Translations: Not Needed

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


vue
<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


vue
<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


vue
<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


vue
<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


vue
<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

vue
<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…

vue
<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

vue
<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

vue
<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:

No events logged yet. Toggle or click the label above.
vue
<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 to aria-label for icon-only controls).
  • Keep aria-checked synchronized with the bound value. When variant="error", the component emits aria-invalid="true" automatically; in any other variant aria-invalid is omitted.
  • When the toggle controls another region, include aria-controls referencing that region’s id.

Imports

ts
import { HLToggle } from '@platform-ui/highrise'

Props

NameTypeDefaultDescription
idstringAuto (hr-toggle-*)The unique identifier for the toggle. Generated when omitted.
checkedValuestring | number | booleantrueThe value when toggle is checked
defaultValuebooleanundefinedInitial 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.
disabledbooleanfalseWhether the toggle is disabled
loadingbooleanfalseWhether 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'.
uncheckedValuestring | number | booleanfalseThe value when toggle is unchecked
valuestring | number | booleanundefinedCurrent 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.
labelstringundefinedThe 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

NameParametersDescription
@update:value(value: string | number | boolean) => voidEmitted when toggle value changes
@label:click(event: Event)=> voidEmitted when toggle label is clicked