Skip to content

aaezekiel/split-slider

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

split-slider

A draggable split-ratio slider for React. Two labeled sides, spring snap, momentum, hash marks, dynamic caption. No dependencies.

Install

npm install split-slider

Usage

'use client'

import 'split-slider/styles.css'
import { SplitSlider } from 'split-slider'

export default function Demo() {
  return (
    <SplitSlider
      left="Design"
      right="Code"
      defaultValue={0.6}
      onValueChange={(v) => console.log(v)}
    />
  )
}

Controlled

const [ratio, setRatio] = useState(0.5)

<SplitSlider
  left="Design"
  right="Code"
  value={ratio}
  onValueChange={setRatio}
/>

With caption

formatCaption returns the text shown below the slider, recomputed as the value changes. The caption cross-fades between values.

<SplitSlider
  left="Design"
  right="Code"
  defaultValue={0.6}
  formatCaption={(v) => {
    const pct = Math.round(v * 100)
    if (pct <= 15) return 'Pure engineer'
    if (pct <= 30) return 'Engineer-forward'
    if (pct <= 45) return 'Code-leaning'
    if (pct <= 55) return 'Design engineer'
    if (pct <= 70) return 'Design-leaning'
    if (pct <= 85) return 'Art director'
    return 'Pure designer'
  }}
/>

Custom value formatter

<SplitSlider
  left="Light"
  right="Dark"
  defaultValue={0.4}
  formatValue={(v) => v.toFixed(2)}
/>

Behavior

  • Drag — pointer or touch on the track moves the divider
  • Snap — on release, the value snaps to the nearest step using an overdamped spring (no overshoot)
  • Momentum — drag velocity carries into the snap; pass momentum={false} to disable
  • Keyboard — focusable; arrow keys step by step, Shift+arrow doubles
  • Hash marks — appear during drag at every step interval, hidden behind labels and the moving split

Props

Prop Type Default
left string required
right string required
value number
defaultValue number 0.5
onValueChange (value: number) => void
onValueCommit (value: number) => void
step number 0.05
min number 0.1
max number 0.9
title string
formatCaption (value: number) => string
formatValue (value: number) => string v => Math.round(v * 100) + '%'
momentum boolean true
disabled boolean false
className string
aria-label string `${left} to ${right} ratio`

Styling

Default styles ship in split-slider/styles.css. The component uses scoped CSS variables under .split-slider-wrap so theming is local.

Variable Default (light) Default (dark)
--split-slider-primary #000000 #e2e2e2
--split-slider-subtle #f4f5f5 #242424
--split-slider-handle #888888 #888888
--split-slider-body rgba(0,0,0,0.85) rgba(255,255,255,0.70)
--split-slider-muted rgba(0,0,0,0.60) rgba(255,255,255,0.50)

Override per instance:

.my-slider {
  --split-slider-primary: #4f46e5;
  --split-slider-handle: #ffffff;
}
<SplitSlider className="my-slider" left="Design" right="Code" />

Accessibility

  • role="slider" with aria-valuemin, aria-valuemax, aria-valuenow (in percent)
  • Keyboard navigable with arrow keys
  • aria-label defaults to `${left} to ${right} ratio`; override via the aria-label prop
  • Selection is suppressed during drag to prevent text-highlight bleed onto surrounding content

License

MIT © Ezekiel Adewumi

About

A draggable split-ratio slider for React. Two labeled sides, spring snap, momentum, hash marks, dynamic caption. No dependencies.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors