
Group
A headless component for managing multi-selection with batch operations and tri-state support.
Usage
The Group component is a specialization of Selection that enforces multi-selection behavior and supports batch operations on arrays of IDs. It always uses array-based v-model binding.
Selected: apple, banana
Anatomy
<script lang="ts" setup>
import { Group } from '@vuetify/v0'
</script>
<template>
<Group.Root v-model="selected" v-slot="{ attrs }">
<div v-bind="attrs">
<Group.Item value="apple" v-slot="{ attrs }">
<button v-bind="attrs">Apple</button>
</Group.Item>
<Group.Item value="banana" v-slot="{ attrs }">
<button v-bind="attrs">Banana</button>
</Group.Item>
</div>
</Group.Root>
</template>Select All
The Group component exposes select-all helpers through its slot props for implementing “select all” checkbox patterns:
isNoneSelected: True when no items are selectedisAllSelected: True when all selectable items are selectedisMixed: True when some but not all are selectedselectAll: Selects all non-disabled itemsunselectAll: Unselects all items (respects mandatory option)toggleAll: Toggles between all selected and none selected
Selected: apple, banana
API
| Component | Description |
|---|---|
| Selection→ | Base selection component with single/multi modes |
| Single→ | Single-selection specialization |
| Composable | Description |
|---|---|
| useGroup→ | The underlying composable used by Group |
GroupRoot
The root component that manages multi-selection state with batch operations.
Props
interface GroupRootProps { namespace?: string disabled?: boolean enroll?: boolean mandatory?: boolean | 'force' }namespace: Namespace for dependency injection (default:'v0:group')disabled: Disables the entire group instanceenroll: Auto-select non-disabled items on registrationmandatory: Controls mandatory group behavior:false(default): No mandatory group enforcementtrue: Prevents deselecting the last selected item'force': Automatically selects the first non-disabled item on registration
v-model
v-model: T[]Always binds to an array of selected values.
Events
Event Payload Description update:model-valueT[]Emitted when the selection changes Slot Props
interface GroupRootSlotProps { isDisabled: boolean isNoneSelected: boolean isAllSelected: boolean isMixed: boolean select: (id: ID | ID[]) => void unselect: (id: ID | ID[]) => void toggle: (id: ID | ID[]) => void selectAll: () => void unselectAll: () => void toggleAll: () => void attrs: { 'aria-multiselectable': true } }isDisabled: Whether the group instance is disabledisNoneSelected: Whether no items are currently selectedisAllSelected: Whether all selectable (non-disabled) items are selectedisMixed: Whether some but not all selectable items are selectedselect: Select item(s) by IDunselect: Unselect item(s) by IDtoggle: Toggle item(s) selection state by IDselectAll: Select all selectable (non-disabled) itemsunselectAll: Unselect all items (respects mandatory option)toggleAll: Toggle between all selected and none selectedattrs: Object containing attributes to bind to the root element
Example
<script lang="ts" setup> import { Group } from '@vuetify/v0' </script> <template> <Group.Root v-model="selected" v-slot="{ attrs, toggleAll, isMixed, isAllSelected }"> <div v-bind="attrs"> <!-- Select all checkbox --> <button @click="toggleAll"> {{ isAllSelected ? '☑' : isMixed ? '☐' : '☐' }} Select All </button> <!-- GroupItem components --> </div> </Group.Root> </template>
GroupItem
Individual group items that register with the Group context. Supports tri-state (selected, unselected, mixed) for checkbox-like behavior.
Props
interface GroupItemProps<V = unknown> { id?: string label?: string value?: V disabled?: MaybeRef<boolean> indeterminate?: MaybeRef<boolean> namespace?: string }id: Unique identifier (auto-generated if not provided)label: Optional display label (passed through to slot, not used in registration)value: Value associated with this itemdisabled: Disables this specific itemindeterminate: Sets the indeterminate state (for checkboxes)namespace: Namespace for dependency injection (default:'v0:group')
Slot Props
interface GroupItemSlotProps<V = unknown> { id: string label?: string value: V | undefined isSelected: boolean isMixed: boolean isDisabled: boolean select: () => void unselect: () => void toggle: () => void mix: () => void unmix: () => void attrs: { 'aria-selected': boolean 'aria-disabled': boolean 'data-selected': true | undefined 'data-disabled': true | undefined 'data-mixed': true | undefined } }id: Unique identifier for this itemlabel: Optional display labelvalue: Value associated with this itemisSelected: Whether this item is currently selectedisMixed: Whether this item is in a mixed/indeterminate stateisDisabled: Whether this item is disabledselect: Select this itemunselect: Unselect this itemtoggle: Toggle this item’s group statemix: Set this item to mixed/indeterminate stateunmix: Clear mixed/indeterminate state from this itemattrs: Object containing all bindable attributes including ARIA and data attributes
Data Attributes
Attribute Description data-selectedPresent when this item is selected data-disabledPresent when this item is disabled data-mixedPresent when this item is in mixed/indeterminate state Accessibility
aria-selectedreflects selection statearia-disabledindicates disabled state
Example
<script lang="ts" setup> import { Group } from '@vuetify/v0' </script> <template> <!-- Simple usage with attrs spread --> <Group.Item value="apple" v-slot="{ attrs }"> <button v-bind="attrs">Apple</button> </Group.Item> <!-- With slot props for conditional styling --> <Group.Item value="banana" v-slot="{ isSelected, toggle }"> <button @click="toggle" :class="{ 'bg-blue-500': isSelected }"> Banana {{ isSelected ? '✓' : '' }} </button> </Group.Item> <!-- With tri-state support --> <Group.Item value="orange" v-slot="{ isSelected, isMixed, toggle }"> <button @click="toggle"> {{ isSelected ? '☑' : isMixed ? '☐' : '☐' }} Orange </button> </Group.Item> <!-- With data attributes for styling --> <Group.Item value="grape" class="data-[selected]:bg-blue-500 data-[disabled]:opacity-50 data-[mixed]:bg-gray-300" v-slot="{ attrs }" > <button v-bind="attrs">Grape</button> </Group.Item> </template>