docs / sula / sula-segmented

SulaSegmented

a segmented control whose active indicator is a liquid droplet. pick a new segment and a drop pinches off the old pill, travels on a thinning neck, and merges into the new one.

intensity · assertsrsc · client

provenance

authored in usva

layer

sula

intensity

asserts · one per region. it is the focal point

composition

brand surfaces: a theme switcher on a portfolio, a view toggle on a heroit mirrors SegmentedControl exactly, keyboard and semantics includeddense or task-bound UI takes the plain SegmentedControl. there the effect is noiseone sula member per region

a11y

role="radiogroup", each segment a radio with aria-checked and roving tabindex · the canvas and icons are aria-hiddenjest-axe

dependencies

motion · ogl · sula-core + sula-motion from the same package
live demo · try it out
customize
sizesegment height and padding
fluidoff renders the plain sliding pill
baredrops the track fill and border
shine0 matte glass, 1 full neon rim
0.6
usagecopy
import { SulaSegmented } from "@usva-ui/react/sula/sula-segmented";

<SulaSegmented
  shine={0.6}
  items={items}
  value={value}
  onValueChange={setValue}
/>

props

proptypedefaultnotes
itemsSulaSegmentedItem[]each entry is { value, label, icon? }. the segments are real buttons, measured at rest.
valuestringcontrolled: the selected value.
defaultValuestringuncontrolled: the value selected on mount. falls back to the first item.
onValueChange(value: string) => voidfires when a segment is picked, by click or by arrow key.
size"sm" | "md""md"segment height and padding.
fluidbooleantruefalse renders the plain sliding pill and mounts no canvas. also the automatic path under reduced motion or missing WebGL2, and what the server always renders.
barebooleanfalsedrops the track fill and border, leaving the indicator on a bare surface.
backdropstringthe colour the glass tints against. defaults to the bg token.
tintstringthe glass itself. defaults to the surface-2 token.
accentColorstringrim light and glow. defaults to the accent token.
shinenumber0 is flat matte glass, 1 is the full neon rim. derived from the backdrop when unset.

get it

bun add @usva-ui/reactcopy
usagecopy
import { SulaSegmented } from "@usva-ui/react/sula/sula-segmented";

<SulaSegmented
  items={[
    { value: "kajo", label: "Kajo" },
    { value: "sisu", label: "Sisu" },
    { value: "savi", label: "Savi" },
  ]}
  value={theme}
  onValueChange={setTheme}
/>