Buttons & Toggles

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.

Bring this into your project

Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.

npx webberui@latest add segmented-morph-toggle.en

New project or installation trouble? Start here →

Playground

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

Active edited usageDefault props
<SegmentedMorphToggle/>

The complete example includes the preview layout and data. Install the component first, then paste this file into your project.

Installation

npx webberui@latest add https://webberui.com/r/segmented-morph-toggle.en.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
valuestring—The current value in controlled mode; once provided, it is fully controlled from outside
defaultValuestringthe first optionInitial value in uncontrolled mode
onChange(value: string) => void—Callback when the selected value changes
size"sm" | "md" | "lg""md"Size (padding and font size)
ariaLabelstring—Group label for assistive technology
classNamestring—Forwarded 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