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

Toggle Group

Group of toggles for multiple selections

Default

Renders a single group of toggles where one option is active at a time.

INFO

HLToggleGroup only shares a size with its child toggles — it does not track a selected value. To get radio-like single-select behaviour, the example gives each HLToggle a distinct :value="i" and binds them all to one shared :checkedValue="active" ref: a toggle reads as "on" only when active equals its own value. The @update:value / @label:click handlers update that shared active ref, so selecting one option deactivates the rest. For the full value/emits contract of the individual toggle, see Toggle.

Whatsapp

SMS

Phone

Linkedin

Instagram

Youtube

Facebook

vue
<template>
  <HLToggleGroup>
    <HLSpace>
      <HLToggle
        v-for="i in options"
        :checkedValue="active"
        :id="'lg-' + i"
        :key="i"
        :value="i"
        :label="i"
        @update:value="(val)=>onClick(val,i)"
        @label:click="(eve)=>lableClicked(eve,i)"
        >{{ i }}</HLToggle
      >
    </HLSpace>
  </HLToggleGroup>
</template>

<script setup lang="ts">
import { HLToggle, HLSpace, HLToggleGroup } from '@platform-ui/highrise'
import { options, active, onClick, lableClicked } from './options'
</script>
ts
import { ref } from 'vue'

export const options = ['Whatsapp', 'SMS', 'Phone', 'Linkedin', 'Instagram', 'Youtube', 'Facebook']
export const active = ref('Whatsapp')

export const onClick = (val, i) => {
  active.value = i
  if (!val) {
    active.value = true
  }
}

export const lableClicked = (event, i) => {
  if (active.value == i) {
    active.value = false
  } else {
    active.value = i
  }
}

All Sizes

Shows the toggle group rendered across each supported size value.

Size: lg

Whatsapp

SMS

Phone

Linkedin

Instagram

Youtube

Facebook

Size: md

Whatsapp

SMS

Phone

Linkedin

Instagram

Youtube

Facebook

Size: sm

Whatsapp

SMS

Phone

Linkedin

Instagram

Youtube

Facebook

Size: xs

Whatsapp

SMS

Phone

Linkedin

Instagram

Youtube

Facebook

Size: 2xs

Whatsapp

SMS

Phone

Linkedin

Instagram

Youtube

Facebook

Size: 3xs

Whatsapp

SMS

Phone

Linkedin

Instagram

Youtube

Facebook

vue
<template>
  <HLToggleGroup size="sm">
    <HLSpace>
      <HLToggle
        v-for="i in options"
        :checkedValue="active"
        :id="'lg-' + i"
        :key="i"
        :value="i"
        :label="i"
        @update:value="(val)=>onClick(val,i)"
        @label:click="(eve)=>lableClicked(eve,i)"
      >
        {{ i }}
      </HLToggle>
    </HLSpace>
  </HLToggleGroup>
</template>

<script setup lang="ts">
import { HLToggle, HLSpace, HLToggleGroup } from '@platform-ui/highrise'
import { options, active, onClick, lableClicked } from './options'
</script>
ts
import { ref } from 'vue'

export const options = ['Whatsapp', 'SMS', 'Phone', 'Linkedin', 'Instagram', 'Youtube', 'Facebook']
export const active = ref('Whatsapp')

export const onClick = (val, i) => {
  active.value = i
  if (!val) {
    active.value = true
  }
}

export const lableClicked = (event, i) => {
  if (active.value == i) {
    active.value = false
  } else {
    active.value = i
  }
}

Event Testing

The group itself emits nothing — the interactive events come from the HLToggle children. Each toggle emits @update:value with its new checked state, and @label:click when its label is clicked. This example logs both.

SMS

Email

Phone

Event Log:

No events logged yet. Toggle an option above.
vue
<template>
  <HLToggleGroup>
    <HLSpace>
      <HLToggle
        v-for="option in options"
        :key="option"
        :id="'events-' + option"
        :value="active === option"
        :label="option"
        @update:value="(val) => handleUpdate(val, option)"
        @label:click="() => handleLabelClick(option)"
      >
        {{ option }}
      </HLToggle>
    </HLSpace>
  </HLToggleGroup>
  <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 an option 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, HLSpace, HLToggleGroup } from '@platform-ui/highrise'

const options = ['SMS', 'Email', 'Phone']
const active = ref('SMS')
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()
  }
}
const handleUpdate = (checked: boolean, option: string) => {
  // Single-select: turning one on activates it; turning the active one off clears it
  active.value = checked ? option : ''
  addEventLog(`@update:value → ${option}: ${checked}`)
}
const handleLabelClick = (option: string) => {
  addEventLog(`@label:click → ${option}`)
}
</script>

Accessibility

  • Present the collection as role="group" / radiogroup and describe it with aria-label / aria-labelledby.
  • Update each child’s aria-pressed / aria-checked so the current selection is announced.
  • Route helper or limit messaging through aria-describedby on the group container.

Imports

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

Props

NameTypeDefaultDescription
size'lg' | 'md' | 'sm' | 'xs' | '2xs' | '3xs''md'Size of all toggles in the group

Slots

NameParametersDescription
default()The content slot for toggle items