WebberUI

Segmented Morph Toggle

A segmented control whose selected block flows and morphs to the new option on a spring.

A segmented control component: the selected block flows between options on a spring using a layoutId shared element, stretching slightly along the direction of travel and then springing back, so it glides into place like a liquid. It supports controlled and uncontrolled modes, three sizes, icons and disabled options, and comes with full keyboard operation built in.

Loading preview…
npx shadcn@latest add https://webberui.com/r/segmented-morph-toggle.json

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

<SegmentedMorphToggle />

Installation

npx shadcn@latest add https://webberui.com/r/segmented-morph-toggle.json

Or, once registries are configured in components.json, install it as @webberui/segmented-morph-toggle.

Usage

import { SegmentedMorphToggle } from "@/components/ui/segmented-morph-toggle";

const [period, setPeriod] = React.useState("monthly");

<SegmentedMorphToggle
  ariaLabel="Billing period"
  value={period}
  onChange={setPeriod}
  options={[
    { value: "monthly", label: "Monthly" },
    { value: "quarterly", label: "Quarterly" },
    { value: "yearly", label: "Yearly" },
  ]}
/>

Props

PropTypeDefaultDescription
optionsSegmentedMorphOption[]The option list; each entry has a unique value and a label, with optional icon and disabled
valuestringThe current value in controlled mode; once provided, it is fully controlled from outside
defaultValuestringthe first optionInitial value in uncontrolled mode
onChange(value: string) => voidCallback when the selected value changes
size"sm" | "md" | "lg""md"Size (padding and font size)
ariaLabelstringGroup label for assistive technology
classNamestringForwarded to the outermost container

Accessibility

  • Uses role="radiogroup" and role="radio", with the selected state marked by aria-checked
  • Roving tabindex: Tab only lands on the selected item, /// cycle within the group, and Home/End jump to the first and last
  • Disabled options are marked disabled, skipped automatically by keyboard navigation, and not clickable with the mouse either
  • When the user has "reduce motion" enabled at the system level, the block jumps straight to the new position without playing the liquid stretch animation
  • Name the group with ariaLabel so screen readers announce what the toggle is for

On this page