react-segmented-choice

Build accessible, customizable segmented controls for React

react-segmented-choice is a React segmented-control library built on native radio inputs. Use one component for sliding toggles, option pickers, toolbar controls and tab-like UI, then shape the surface, indicator and labels with CSS variables. The same component powers every example below, from sliding pill switches to Ant-style filter bars, range-like pickers and icon rails.

Basic Example

The plain horizontal control: text labels, default skin and medium sizing.

1 / 17 - Text

One segmented control, many UI shapes

Accessible radio semantics

Real radio inputs, labels, keyboard movement and form-friendly state keep the component understandable to browsers and assistive tech.

CSS-first customization

Use stable classes, data attributes and CSS variables to style the track, indicator, option labels and focus states without a design-system wrapper.

Animated control patterns

Drag selection, smooth indicator motion and cloned active content support toggles, pickers, toolbar controls and tab-like UI.

Render the control, then shape it with CSS

Render the accessible default, then customize the surface, option pills, active state and focus color from scoped CSS variables.

Install
pnpm add react-segmented-choice
# or
npm install react-segmented-choice
# or
yarn add react-segmented-choice
Quick usage
import { SegmentedChoice } from 'react-segmented-choice';
import 'react-segmented-choice/styles.css';

export function ReportRange() {
  return (
    <SegmentedChoice
      ariaLabel="Report range"
      className="my-custom-component"
      defaultValue="segmented"
      optionSizing="equal"
      options={[
        { value: 'react', label: 'React' },
        { value: 'segmented', label: 'Segmented' },
        { value: 'choice', label: 'Choice' },
      ]}
    />
  );
}
CSS styling
.my-custom-component {
  --rsc-surface: #f8fafc;
  --rsc-border-color: #e5e7eb;
  --rsc-border-radius: 999px;
  --rsc-option-radius: 999px;
  --rsc-option-padding-inline: 14px;
  --rsc-text-color: #4b5563;
  --rsc-active-text-color: #ffffff;
  --rsc-indicator-color: #7c3aed;
  --rsc-focus-ring-color: rgba(124, 58, 237, 0.26);
}

.my-custom-component.rsc-root .rsc-option-content {
  transition: color 200ms ease;
}

.my-custom-component.rsc-root[data-dragging="true"]
  .rsc-option[data-selected="true"]:not([data-previewed="true"])
  .rsc-option-content {
  color: var(--rsc-text-color);
}

.my-custom-component.rsc-root[data-dragging="true"]
  .rsc-option[data-previewed="true"]
  .rsc-option-content {
  color: var(--rsc-active-text-color);
}

Use the docs for API details and Storybook when you want to see the recipes in motion.

react-custom-switcher is the legacy predecessor. react-segmented-choice carries those original ideas forward as a cleaner, more flexible segmented control for current React projects.