DocsBlog
  • 1.7.0

  • Day

    Night

    Preview

    Switch mode
  • Cerberus

    Acheron

    Elysium

    Oceanus

Get Started
Components
Data Grid
Signals
Styling
Theming

Concepts

OverviewCompositionCerberus ContextTesting

Layout

Aspect RatioBleedBoxCenterContainerContainer QueryDividerFlexFloatGridGroupLink OverlayScrollableStackWrap

Components

AccordionAdmonitionAvatarButtonCarouselCheckboxClipboardCollapsibleComboboxConfirm ModalCTAModalDate PickerDialogFieldFieldsetFile UploaderIcon ButtonInputLoading StatesMarqueeNotificationsNumber InputPaginationPin InputPopoverProgressPrompt ModalRadioRatingSelectSliderSplit ButtonSwitchTableTabsTagTextTextareaToggleTooltip

Utilities

Client OnlyDownload TriggerEnvironmentFeature FlagsFocus TrapForFormat ByteFormat NumberFormat Relative TimeFrameHighlightJSON Tree ViewLocaleLocal StoragePortalPresenceShowsplitPropsTheme

Slider

Used to allow users to make selections from a range of values.

  • npm
  • source
  • recipe
  • Ark
import { Slider } from '@cerberus/react'

Usage

The Slider component is a controlled abstraction of the primitive slots to render a slider control.

Examples

Label

The Slider component supports adding header content (such as a label) through its children. This content is rendered within an HStack that justifyContent is set to space-between.

In this example, we include the Slider.ValueText which displays the current value of the slider.

Sizes

The Slider component supports different sizes through the size prop. The default size is lg.

Usage

You can control the style of the Slider by using the usage prop. The default usage is gradient.

Palette

You can customize the color palette of the Slider by using the palette prop. The default palette is action.

Note

Palettes are only customizable for non-gradient usages by nature of how CSS backgrounds work.

Range Slider

To create a range slider, set multiple values to the defaultValue prop.

Prevent Overlapping

Use the minStepsBetweenThumbs prop to avoid thumbs with the same value.

Collision Behavior

Use the thumbCollisionBehavior prop to control how thumbs interact when they collide. Options are "none" (default), "push", or "swap".

Value Text

To display the value text of the slider, use the Slider.ValueText slot.

Disabled

To disable the slider, use the disabled prop.

Steps

Use the step prop to define the step size of the slider which will create a discrete stop on value marker.

Marks

To display marks on the slider, use the marks prop.

Dragging Indicator

To display the dragging indicator, use the showIndicator prop.

Vertical

To display a vertical slider, use the orientation prop.

Controlled

When you want to control the slider value programmatically, use the onValueChange in combination with the value prop.

Store

An alternative way to control the Slider is to use the Provider component and the useSlider store hook.

This way you can access the slider state and methods from outside the slider.

Note

When using using the Provider component, you are opting out of the Slider abstraction which means you need to utilize the utility components mentioned in the Guides section.

Change End

Use the onValueChangeEnd prop to listen to the end of the slider change. This will fire when the user releases the slider thumb.

Customizing

You can fully customize every slot layer of the Slider using style props.

Guides

This abstraction renders the following shortcuts internally to streamline development.

Slider.Track

The Slider.Track and Slider.Range slots are used to render the track and range of the slider.

<SliderTrack>
  <SliderRange />
</SliderTrack>

Slider.Thumbs

The Slider.Thumb, Slider.DraggingIndicator, and Slider.HiddenInput slots are used to render the thumb of the slider.

<SliderThumb>
  <SliderDraggingIndicator />
  <SliderHiddenInput />
</SliderThumb>

If you want to render a range of thumbs, we also provide the Slider.Thumbs slot.

<Slider.Thumbs values={[25, 50]} />

Slider.Marks

The Slider.MarkerGroup and Slider.Marker slots are used to render the mark of the slider.

<SliderMarkerGroup>
  <SliderMarker />
</SliderMarkerGroup>

If you want to render a couple of marks, we also provide the Slider.Marks slot.

<Slider.Marks values={[0, 25, 50, 75, 100]} />

Custom CSS Variables

To help streamline custom styling, the slider uses a set of CSS variables that you can override:

'--slider-thumb-size': '1.5rem'   // size of the thumb
'--slider-track-size': '0.5rem'   // height of the track
'--slider-marker-center': '9px'   // the center position of the track
'--slider-marker-size': '0.06rem' // size of the marker
'--slider-marker-inset': '3px'    // distance from the track edge to the marker
'--slider-dragging-indicator-offset': '-2rem' // The gap between the thumb and the dragging indicator

Primitive Slots

The Slider exposes the following primitive slots:

ComponentDescription
ProviderThe Provider context to use in place of the Root for the hook-based store solution.
RootThe root element of the slider.
LabelThe label element of the slider.
ValueTextThe value text element of the slider.
ControlThe control element of the slider.
TrackThe track element of the slider.
RangeThe range element of the slider.
ThumbThe thumb element of the slider.
ThumbsAn abstraction of the Thumb and DraggingIndicator elements of the slider.
DraggingIndicatorThe dragging indicator element of the slider.
MarkerGroupThe marker group element of the slider.
MarkerThe marker element of the slider.
MarkerIndicatorThe marker indicator element of the slider.
MarksAn abstraction of the Marker elements of the slider.
HiddenInputThe hidden input element of the slider.

API

Root

PropTypeRequiredDescription
aria-labelstring[]NoThe aria-label of each slider thumb. Useful for providing an accessible name to the slider
aria-labelledbystring[]NoThe id of the elements that labels each slider thumb. Useful for providing an accessible name to the slider
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.
defaultValuenumber[]NoThe initial value of the slider when rendered.Use when you don't need to control the value of the slider.
disabledbooleanNoWhether the slider is disabled
formstringNoThe associate form of the underlying input element.
getAriaValueText(details: ValueTextDetails) => stringNoFunction that returns a human readable value for the slider thumb
idstringNoThe unique identifier of the machine.
idsPartial<Slots>NoThe ids of the elements in the slider. Useful for composition.
invalidbooleanNoWhether the slider is invalid
maxnumberNoThe maximum value of the slider
minnumberNoThe minimum value of the slider
minStepsBetweenThumbsnumberNoThe minimum permitted steps between multiple thumbs. minStepsBetweenThumbs * step should reflect the gap between the thumbs. step: 1 and minStepsBetweenThumbs: 10 => gap is 10
namestringNoThe name associated with each slider thumb (when used in a form)
onFocusChange(details: FocusChangeDetails) => voidNoFunction invoked when the slider's focused index changes
onValueChange(details: ValueChangeDetails) => voidNoFunction invoked when the value of the slider changes
onValueChangeEnd(details: ValueChangeDetails) => voidNoFunction invoked when the slider value change is done
orientation'horizontal' | 'vertical'NoThe orientation of the slider
origin'center' | 'start' | 'end'NoThe origin of the slider range. The track is filled from the origin to the thumb for single values.
readOnlybooleanNoWhether the slider is read-only
stepnumberNoThe step value of the slider
thumbAlignment'center' | 'contain'NoThe alignment of the slider thumb relative to the track
thumbCollisionBehavior'none' | 'push' | 'swap'NoControls how thumbs behave when they collide during pointer interactions.
thumbSize{ width: number; height: number }NoThe slider thumbs dimensions
valuenumber[]NoThe controlled value of the slider

Data Attributes:

AttributeValue
[data-scope]slider
[data-part]root
[data-disabled]Present when disabled
[data-orientation]The orientation of the slider
[data-dragging]Present when in the dragging state
[data-invalid]Present when invalid
[data-focus]Present when focused

CSS Variables:

VariableDescription
--slider-thumb-widthThe thumb width of the slider
--slider-thumb-heightThe thumb height of the slider
--slider-thumb-transformThe thumb transform of the slider
--slider-range-startThe range start of the slider
--slider-range-endThe range end of the slider
--translate-xThe horizontal translation value
--translate-yThe vertical translation value

Provider

PropTypeRequiredDescription
valueUseSliderReturnYes
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.

Control

PropTypeRequiredDescription
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.

Data Attributes

AttributeValue
[data-scope]slider
[data-part]control
[data-dragging]Present when in the dragging state
[data-disabled]Present when disabled
[data-orientation]The orientation of the control
[data-invalid]Present when invalid
[data-focus]Present when focused

DraggingIndicator

PropTypeRequiredDescription
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.

Data Attributes

AttributeValue
[data-scope]slider
[data-part]dragging-indicator
[data-orientation]The orientation of the draggingindicator
[data-state]"open" | "closed"

HiddenInput

PropTypeRequiredDescription
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.

Label

PropTypeRequiredDescription
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.

Data Attributes

AttributeValue
[data-scope]slider
[data-part]label
[data-disabled]Present when disabled
[data-orientation]The orientation of the label
[data-invalid]Present when invalid
[data-dragging]Present when in the dragging state
[data-focus]Present when focused

MarkerGroup

PropTypeRequiredDescription
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.

Data Attributes

AttributeValue
[data-scope]slider
[data-part]marker-group
[data-orientation]The orientation of the markergroup

Marker

PropTypeRequiredDescription
valuenumberYes
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.

Data Attributes

AttributeValue
[data-scope]slider
[data-part]marker
[data-orientation]The orientation of the marker
[data-value]The value of the item
[data-disabled]Present when disabled
[data-state]

Range

PropTypeRequiredDescription
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.

Data Attributes

AttributeValue
[data-scope]slider
[data-part]range
[data-dragging]Present when in the dragging state
[data-focus]Present when focused
[data-invalid]Present when invalid
[data-disabled]Present when disabled
[data-orientation]The orientation of the range

Thumb

PropTypeRequiredDescription
indexnumberYes
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.
namestringNo

Data Attributes

AttributeValue
[data-scope]slider
[data-part]thumb
[data-index]The index of the item
[data-name]
[data-disabled]Present when disabled
[data-orientation]The orientation of the thumb
[data-focus]Present when focused
[data-dragging]Present when in the dragging state

Track

PropTypeRequiredDescription
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.

Data Attributes

AttributeValue
[data-scope]slider
[data-part]track
[data-disabled]Present when disabled
[data-invalid]Present when invalid
[data-dragging]Present when in the dragging state
[data-orientation]The orientation of the track
[data-focus]Present when focused

ValueText

PropTypeRequiredDescription
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.

Data Attributes

AttributeValue
[data-scope]slider
[data-part]value-text
[data-disabled]Present when disabled
[data-orientation]The orientation of the valuetext
[data-invalid]Present when invalid
[data-focus]Present when focused

On this page

Loading...

Loading...

Loading...

Loading...

Copy
Copy
import { HStack } from '@/styled-system/jsx'
import { Slider } from '@cerberus/react'

export function BasicDemo() {
  return (
    <HStack w="3/4">
      <Slider defaultValue={[30]} />
    </HStack>
  )
}
Copy
import { HStack } from '@/styled-system/jsx'
import { Slider } from '@cerberus/react'

export function RangeDemo() {
  return (
    <HStack w="3/4">
      <Slider defaultValue={[30, 80]} />
    </HStack>
  )
}
Copy
import { HStack } from '@/styled-system/jsx'
import { Slider } from '@cerberus/react'

export function OverlapDemo() {
  return (
    <HStack w="3/4">
      <Slider defaultValue={[30, 80]} minStepsBetweenThumbs={15} />
    </HStack>
  )
}
Copy
Copy
Copy
Copy
import { HStack } from '@/styled-system/jsx'
import { Slider } from '@cerberus/react'

export function StepsDemo() {
  return (
    <HStack w="3/4">
      <Slider defaultValue={[30]} step={10} />
    </HStack>
  )
}
Copy
Copy
Copy
0
Value: 0
Copy
'use client'

import { HStack, Stack } from '@/styled-system/jsx'
import { cerberus, Slider, Text } from '@cerberus/react'
import { useSignal } from '@cerberus/signals'

export function ControlledDemo() {
  const [value, setValue] = useSignal<Array<number>>([0])
  return (
    <Stack gap="xl" w="3/4">
      <Slider onValueChange={(details) => setValue(details.value)} value={value}>
        <Slider.Label>Controlled</Slider.Label>
        <Slider.ValueText />
      </Slider>

      <HStack gap="sm" w="full">
        <Text as="small" textStyle="body-sm">
          Value:{' '}
        </Text>
        <cerberus.code textStyle="mono-sm">{value}</cerberus.code>
      </HStack>
    </Stack>
  )
}
40
Value: 40
Copy
'use client'

import { HStack, Stack } from '@/styled-system/jsx'
import { cerberus, Slider, Text, useSlider } from '@cerberus/react'

export function StoreDemo() {
  const slider = useSlider({
    defaultValue: [40],
    thumbAlignment: 'center',
  })

  return (
    <Stack gap="xl" w="3/4">
      <Slider.Provider direction="horizontal" value={slider}>
        <HStack justify="space-between" w="full">
          <Slider.Label>Slider Store</Slider.Label>
          <Slider.ValueText />
        </HStack>

        <Slider.Control direction="horizontal">
          <Slider.Track direction="horizontal">
            <Slider.Range direction="horizontal" />
          </Slider.Track>
          <Slider.Thumbs direction="horizontal" value={slider.value} />
        </Slider.Control>
      </Slider.Provider>

      <HStack gap="sm" w="full">
        <Text as="small" textStyle="body-sm">
          Value:{' '}
        </Text>
        <cerberus.code textStyle="mono-sm">{slider.value}</cerberus.code>
      </HStack>
    </Stack>
  )
}
0
Value: 0
End Value: 0
Copy
'use client'

import { HStack, Stack } from '@/styled-system/jsx'
import { cerberus, Slider, Text } from '@cerberus/react'
import { useSignal } from '@cerberus/signals'

export function ChangeEndDemo() {
  const [value, setValue] = useSignal<Array<number>>([0])
  const [endVal, setEndVal] = useSignal<Array<number>>([0])

  return (
    <Stack gap="xl" w="3/4">
      <Slider
        onValueChange={(details) => setValue(details.value)}
        onValueChangeEnd={(details) => setEndVal(details.value)}
        value={value}
      >
        <Slider.Label>Controlled</Slider.Label>
        <Slider.ValueText />
      </Slider>

      <Stack gap="sm">
        <HStack gap="sm" w="full">
          <Text as="small" textStyle="body-sm">
            Value:{' '}
          </Text>
          <cerberus.code textStyle="mono-sm">{value}</cerberus.code>
        </HStack>
        <HStack gap="sm" w="full">
          <Text as="small" textStyle="body-sm">
            End Value:{' '}
          </Text>
          <cerberus.code textStyle="mono-sm">{endVal[0]}</cerberus.code>
        </HStack>
      </Stack>
    </Stack>
  )
}
Copy
30
Copy
import { HStack } from '@/styled-system/jsx'
import { Slider } from '@cerberus/react'

export function LabelDemo() {
  return (
    <HStack w="3/4">
      <Slider defaultValue={[30]}>
        <Slider.Label>Amount of Corn</Slider.Label>
        <Slider.ValueText />
      </Slider>
    </HStack>
  )
}
30
Copy
import { HStack } from '@/styled-system/jsx'
import { Slider } from '@cerberus/react'

export function LabelDemo() {
  return (
    <HStack w="3/4">
      <Slider defaultValue={[30]}>
        <Slider.Label>Amount of Corn</Slider.Label>
        <Slider.ValueText />
      </Slider>
    </HStack>
  )
}
25
50
75
25%
50%
75%
25
50
75
25
50
75
30
0
25
50
75
100
30
0
25
50
75
0
25
50
75
100
100
import { Stack } from '@/styled-system/jsx'
import { For, Slider, SliderProps } from '@cerberus/react'
import recipesSpec from 'styled-system/specs/recipes.json'
import { getSacredNumber } from './utils'

const sizes = (recipesSpec.data.find((r) => r.name === 'slider')?.variants.size ??
  []) as SliderProps['size'][]

export function SizesDemo() {
  return (
    <Stack gap="md" w="3/4">
      <For each={sizes}>
        {(size, idx) => (
          <Slider key={String(size)} defaultValue={[getSacredNumber(idx)]} size={size}>
            <Slider.Label>Slider - {size} </Slider.Label>
          </Slider>
        )}
      </For>
    </Stack>
  )
}
import { Stack } from '@/styled-system/jsx'
import { Slider } from '@cerberus/react'

export function CollisionDemo() {
  return (
    <Stack gap="lg" w="3/4">
      <Slider defaultValue={[30, 80]} thumbCollisionBehavior="none">
        <Slider.Label>None</Slider.Label>
      </Slider>

      <Slider defaultValue={[30, 80]} thumbCollisionBehavior="push">
        <Slider.Label>Push</Slider.Label>
      </Slider>

      <Slider defaultValue={[30, 80]} thumbCollisionBehavior="swap">
        <Slider.Label>Swap</Slider.Label>
      </Slider>
    </Stack>
  )
}
import { Stack } from '@/styled-system/jsx'
import { For, Slider, SliderProps } from '@cerberus/react'
import recipesSpec from 'styled-system/specs/recipes.json'
import { getSacredNumber } from './utils'

const palettes = (recipesSpec.data.find((r) => r.name === 'slider')?.variants.palette ??
  []) as SliderProps['palette'][]

export function PaletteDemo() {
  return (
    <Stack gap="md" w="3/4">
      <For each={palettes}>
        {(palette, idx) => (
          <Slider
            key={String(palette)}
            defaultValue={[getSacredNumber(idx)]}
            palette={palette}
            usage="outlined"
          >
            <Slider.Label>Slider - {palette} </Slider.Label>
          </Slider>
        )}
      </For>
    </Stack>
  )
}
import { Stack } from '@/styled-system/jsx'
import { For, Slider, SliderProps } from '@cerberus/react'
import recipesSpec from 'styled-system/specs/recipes.json'
import { getSacredNumber } from './utils'

const variants = (recipesSpec.data.find((r) => r.name === 'slider')?.variants.usage ??
  []) as SliderProps['usage'][]

export function DisabledDemo() {
  return (
    <Stack gap="md" w="3/4">
      <For each={variants}>
        {(usage, idx) => (
          <Slider
            key={String(usage)}
            disabled
            defaultValue={[getSacredNumber(idx)]}
            size={usage === 'filled' ? 'sm' : 'lg'}
            usage={usage}
          >
            <Slider.Label>Slider - {usage} </Slider.Label>
          </Slider>
        )}
      </For>
    </Stack>
  )
}
import { Stack } from '@/styled-system/jsx'
import { Corn } from '@carbon/icons-react'
import { Slider } from '@cerberus/react'

export function MarksDemo() {
  return (
    <Stack gap="lg" w="3/4">
      <Slider defaultValue={[0]} marks={[25, 50, 75]} step={25}>
        <Slider.Label>With numbers</Slider.Label>
      </Slider>
      <Slider
        defaultValue={[0]}
        marks={[
          { value: 25, label: '25%' },
          { value: 50, label: '50%' },
          { value: 75, label: '75%' },
        ]}
      >
        <Slider.Label>With custom labels</Slider.Label>
      </Slider>
      <Slider
        defaultValue={[0]}
        marks={[
          { value: 25, label: <Corn /> },
          { value: 50, label: <Corn /> },
          { value: 75, label: <Corn /> },
        ]}
      >
        <Slider.Label>With Corn</Slider.Label>
      </Slider>

      <Slider defaultValue={[0]} marks={[25, 50, 75]} usage="filled" size="sm">
        <Slider.Label>Filled small size</Slider.Label>
      </Slider>
      <Slider defaultValue={[0]} marks={[25, 50, 75]} usage="outlined" size="md">
        <Slider.Label>Outlined medium size</Slider.Label>
      </Slider>
    </Stack>
  )
}
import { HStack } from '@/styled-system/jsx'
import { Slider } from '@cerberus/react'

export function DraggingIndicatorDemo() {
  return (
    <HStack gap="4xl" justify="center" w="3/4">
      <Slider defaultValue={[30]} marks={[0, 25, 50, 75, 100]} showIndicator />

      <Slider
        defaultValue={[30]}
        marks={[0, 25, 50, 75, 100]}
        orientation="vertical"
        showIndicator
        height="200px"
      />
    </HStack>
  )
}
import { HStack, VStack } from '@/styled-system/jsx'
import { VolumeMute } from '@carbon/icons-react'
import { Slider } from '@cerberus/react'

export function VerticalDemo() {
  return (
    <HStack gap="4xl" justify="center" w="3/4">
      <Slider defaultValue={[30]} height="200px" orientation="vertical" />

      <VStack gap="md">
        <Slider defaultValue={[0]} height="168px" orientation="vertical" />
        <VolumeMute />
      </VStack>

      <Slider
        defaultValue={[30]}
        marks={[0, 25, 50, 75, 100]}
        orientation="vertical"
        height="200px"
      />
    </HStack>
  )
}
import { Stack } from '@/styled-system/jsx'
import { For, Slider, SliderProps } from '@cerberus/react'
import recipesSpec from 'styled-system/specs/recipes.json'
import { getSacredNumber } from './utils'

const variants = (recipesSpec.data.find((r) => r.name === 'slider')?.variants.usage ??
  []) as SliderProps['usage'][]

export function UsageDemo() {
  return (
    <Stack gap="md" w="3/4">
      <For each={variants}>
        {(usage, idx) => (
          <Slider
            key={String(usage)}
            defaultValue={[getSacredNumber(idx)]}
            size={usage === 'filled' ? 'sm' : 'lg'}
            usage={usage}
          >
            <Slider.Label>Slider - {usage} </Slider.Label>
          </Slider>
        )}
      </For>
    </Stack>
  )
}

On this page

  • Usage
  • Examples
  • Label
  • Sizes
  • Usage
  • Palette
  • Range Slider
  • Prevent Overlapping
  • Collision Behavior
  • Value Text
  • Disabled
  • Steps
  • Marks
  • Dragging Indicator
  • Vertical
  • Controlled
  • Store
  • Change End
  • Customizing
  • Guides
  • `Slider.Track`
  • `Slider.Thumbs`
  • `Slider.Marks`
  • Custom CSS Variables
  • Primitive Slots
  • API
  • Root
  • Provider
  • Control
  • DraggingIndicator
  • HiddenInput
  • Label
  • MarkerGroup
  • Marker
  • Range
  • Thumb
  • Track
  • ValueText
  • Edit this page on Github