Skip to content

SwitchGroup ​

A switch group lays several switches out together. That is the whole of it: it owns no state, no shared name and no validation, so each Switch inside keeps its own name, its own value and its own selection. What it buys you is consistent spacing and one place to change the axis.

ts
import { SwitchGroup } from "ropav";
switch-group-basic.vue
vue
<script setup lang="ts">
import { Switch, SwitchContent, SwitchControl, SwitchGroup, SwitchThumb } from "ropav";

const settings = [
  { label: "Allow notifications", name: "notifications" },
  { label: "Marketing emails", name: "marketing" },
  { label: "Social media updates", name: "social" },
];
</script>

<template>
  <SwitchGroup>
    <Switch v-for="setting in settings" :key="setting.name" :name="setting.name" value="on">
      <SwitchContent>
        <SwitchControl>
          <SwitchThumb />
        </SwitchControl>
        {{ setting.label }}
      </SwitchContent>
    </Switch>
  </SwitchGroup>
</template>

Because each switch submits itself, a group inside a <form> needs nothing extra — every switch that is on contributes its own name and value to the form data.

Horizontal ​

switch-group-horizontal.vue
vue
<script setup lang="ts">
import { Switch, SwitchContent, SwitchControl, SwitchGroup, SwitchThumb } from "ropav";

const settings = ["Email", "Push", "SMS"];
</script>

<template>
  <SwitchGroup orientation="horizontal">
    <Switch v-for="setting in settings" :key="setting" :name="setting.toLowerCase()" value="on">
      <SwitchContent>
        <SwitchControl>
          <SwitchThumb />
        </SwitchControl>
        {{ setting }}
      </SwitchContent>
    </Switch>
  </SwitchGroup>
</template>

A horizontal group will run past its container rather than wrap, so give it something to do about that — class="overflow-x-auto", or shorter labels.

When a group is not enough ​

Switches that need one shared label, or one disabled state across all of them, want a Fieldset around them instead. This component is layout, and a screen reader is told nothing by it.

API ​

PropTypeDefaultDescription
orientation"horizontal" | "vertical""vertical"Layout orientation.

Slots: default.