Skip to content

Switch


vue
<template>
  <PeachyInput.Input>
    <PeachySwitch.Input v-model:on="on">
      <PeachySwitch.Indicator>
        <div class="dot" />
      </PeachySwitch.Indicator>

      Switch
    </PeachySwitch.Input>
  </PeachyInput.Input>
</template>

<script lang="ts" setup>
  import { ref } from "vue";

  import { PeachyInput, PeachySwitch } from "@/index";

  const on = ref(false);
</script>
css
.peachy-switch__input {
  color: var(--text);
  cursor: pointer;
  font-size: 100%;

  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--gap);

  background: none;
  border: none;

  border-radius: 99rem;
  padding: 0.25rem;
}

.peachy-switch__indicator {
  position: relative;

  border-radius: 99rem;
  background-color: var(--button-bg);
  border: 1px solid var(--border);
  width: 3rem;
  height: 1.5rem;
}

.peachy-switch__indicator .dot {
  position: absolute;
  width: 1.75rem;
  height: 1.75rem;
  top: calc(calc(0.25rem / 2) * -1);

  border-radius: 100%;

  transition:
    background-color 0.25s,
    left 0.25s;
}

.peachy-switch__input[aria-pressed="false"] .dot {
  background-color: var(--dimmed-text);
  left: calc(calc(0.25rem / 2) * -1);
}

.peachy-switch__input[aria-pressed="true"] .dot {
  background-color: var(--brand-button-bg);
  left: calc(3rem - 1.75rem);
}

.peachy-switch__input:hover .dot,
.peachy-switch__input:focus-visible .dot {
  background-color: var(--brand-color);
}

Anatomy

Switch does not require a separate <PeachyInput.Label /> as the Input is a button.

vue
<template>
  <PeachyInput.Input>
    <PeachySwitch.Input>
      <PeachySwitch.Indicator />
      Label
    </PeachySwitch.Input>
  </PeachyInput.Input>
</template>

<script lang="ts" setup>
  import { PeachyInput, PeachySwitch } from "typeach";
</script>

Props & Emits

Input


Props

NameDefaultTypeDescription
onfalseboolean?
disabledfalseboolean?
readOnlyfalseboolean?
requiredfalseboolean?The component only labels it as required with aria-required and does not deal with any error messages for you.

Emits

@Payload
update:onboolean
validateboolean
clear-validation

Styling

CSS Selectors

Follows our CSS classes convention.


State selectors

SelectorDescriptionFor
[aria-pressed="true"]For a switch that is on.
  • Input

Accessibility

Resources: Scott O'Hara's Switch Component: Toggle Button

READONLY

The switch is really just a button with the area-pressed attribute to determine if it's checked or not, so readonly is not really a concept it knows about. However, for consistency, readonly is an option - which makes the button focusable but removes the functionality.

Keyboard interactions

KeyAction
Enter or SpaceToggles the switch.