Dashral Pro is on the wayGet 30% off at launch

Dashral

Segmented Control

SegmentedControl with motion: the picked option's card springs to the one you pick, a soft highlight follows the pointer, and options press in while held.

$ pnpm dlx shadcn@latest add https://dashral.com/r/motion-segmented-control.json

Installation

$ pnpm dlx shadcn@latest add https://dashral.com/r/motion-segmented-control.json

Adds components/dashral/motion/segmented-control.tsx, the Segmented Control it builds on (in components/dashral/), motion and the motion files every motion component shares. With the registry in your components.json:

$ pnpm dlx shadcn@latest add @dashral/motion-segmented-control

Usage

The same as Segmented Control, imported from components/dashral/motion/: swap the import and it moves.

example.tsx
import { SegmentedControl } from "@/components/dashral/motion/segmented-control"

<SegmentedControl aria-label="Range" value={range} onValueChange={setRange} options={["Day", "Week", "Month"]} />

Examples

Day, Week, Month

The card springs to the range you pick, the bars grow to their new heights one after another, and the total rolls to its new number.

Orders

2,520
Mon
Tue
Wed
Thu
Fri
Sat
Sun

Grid or list

Two icon options: every file glides from its tile to its row and back instead of the page snapping.

Files

  • Q3 report.pdf

    2.4 MB

  • Revenue.xlsx

    860 KB

  • Team photo.jpg

    3.1 MB

  • Roadmap.pdf

    1.2 MB

Compared with Default

Default

The picked option's card slides over in CSS.

Motion

The card springs to the option you pick with a touch of overshoot, a soft highlight glides after the pointer, and an option presses in while held.

How the two editions differ in general, and which to use where: Motion.

API reference

Every prop of Segmented Control, and every attribute of the element it renders. The Motion edition adds no props of its own.

SegmentedControl

Also takes every prop of Radix Radio Group(opens in a new tab).

PropTypeDefault
value / defaultValuestring—
onValueChange(value: string) => void

Called with the new value.

—
options(string | { value; label?; icon?; disabled?; "aria-label"? })[]

The segments. An icon-only one needs an aria-label.

—
labelReactNode

Shown above, linked to the control.

—
descriptionReactNode

A hint under the control.

—
errorboolean | ReactNode

true shows the error style; a message also shows under the control.

—
labelActionReactNode

At the end of the label's row, e.g. a “Forgot password?” link or the current value.

—
withAsteriskboolean

Marks the label with an asterisk, e.g. alongside required.

false
classNames{ root, label, description, error, group, item }

Classes for each part.

—
aria-labelstring

Without a label: names the choice, e.g. “Calendar view”.

—

Motion

  • The picked option's card is one element that springs from option to option with a touch of overshoot (motion's shared layout).
  • A softer highlight glides after the pointer from option to option, under the picked card too.
  • An option presses in to 96% on a spring while held.
  • With reduced motion the card and highlight jump, and nothing presses in.