All components outlinesolidsmmdlg
Slider
Range selection with track, filled range, and thumb in outline and solid variants.
123456789101112131415161718import { Slider } from "#components/ui/base-ui/slider.tsx";import { indigoPalette } from "@stylexblocks/ui/themes/palettes.ts";
export function Example() { return ( // variant/size resolve once on Root; parts inherit them via context <Slider.Root defaultValue={50} min={0} max={100} variant="outline" size="md" palette={indigoPalette}> <Slider.Control> <Slider.Track> <Slider.Indicator /> </Slider.Track> <Slider.Thumb aria-label="Volume" /> </Slider.Control> </Slider.Root> );}
// controlled: <Slider.Root value={value} onValueChange={setValue}>Variants
Sizes
Install
1npx stylexblocks add sliderSource
components/ui/base-ui/slider.tsx
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285import * as stylex from "@stylexjs/stylex";import { useContext } from "react";import { Slider as BaseSlider } from "@base-ui-components/react/slider";import { createSlotRecipeContext } from "#lib/base-ui/create-slot-recipe-context.tsx";import { defineSlotRecipe } from "#lib/recipe-props.ts";import { colorPalette } from '@stylexblocks/ui/color-palette.stylex.ts'import { fontSizes } from '@stylexblocks/ui/tokens/font-sizes.stylex.ts'import { radii } from '@stylexblocks/ui/tokens/radii.stylex.ts'import { semanticColors } from '@stylexblocks/ui/semantic-tokens/colors.stylex.ts'import { semanticShadows } from '@stylexblocks/ui/semantic-tokens/shadows.stylex.ts'import { sizes } from '@stylexblocks/ui/tokens/sizes.stylex.ts'import { spacing } from '@stylexblocks/ui/tokens/spacing.stylex.ts'
const sliderRoot = stylex.create({ base: { display: 'flex', flexDirection: 'column', gap: spacing._1, fontSize: fontSizes.sm, position: 'relative', isolation: 'isolate', touchAction: 'none', },})
const sliderRootSizes = stylex.create({ sm: { '--slider-thumb-size': sizes._4, '--slider-track-size': sizes._1_5, '--slider-marker-top': '6px', '--slider-marker-size': sizes._1, '--slider-marker-inset': '3px', }, md: { '--slider-thumb-size': sizes._5, '--slider-track-size': sizes._2, '--slider-marker-top': '8px', '--slider-marker-size': sizes._1, '--slider-marker-inset': '4px', }, lg: { '--slider-thumb-size': sizes._6, '--slider-track-size': sizes._2_5, '--slider-marker-top': '9px', '--slider-marker-size': sizes._1_5, '--slider-marker-inset': '5px', },})
const sliderRootOrientations = stylex.create({ vertical: { display: 'inline-flex', },})
const sliderControl = stylex.create({ base: { display: 'inline-flex', alignItems: 'center', position: 'relative', },})
const sliderControlOrientations = stylex.create({ vertical: { flexDirection: 'column', height: '100%', minWidth: 'var(--slider-thumb-size)', }, horizontal: { flexDirection: 'row', width: '100%', minHeight: 'var(--slider-thumb-size)', },})
const sliderTrack = stylex.create({ base: { overflow: 'hidden', borderRadius: radii.full, flex: 1, },})
const sliderTrackVariants = stylex.create({ outline: { boxShadow: semanticShadows.inset, backgroundColor: `color-mix(in oklch, ${semanticColors.bgEmphasized} 72%, transparent)`, }, solid: { backgroundColor: { default: colorPalette.subtle, ':is(:disabled, [disabled], [data-disabled])': semanticColors.bgMuted, }, },})
const sliderTrackOrientations = stylex.create({ vertical: { width: 'var(--slider-track-size)', }, horizontal: { height: 'var(--slider-track-size)', },})
const sliderRange = stylex.create({ base: { width: 'inherit', height: 'inherit', backgroundColor: { default: null, ':is(:disabled, [disabled], [data-disabled])': semanticColors.borderEmphasized, }, },})
const sliderRangeVariants = stylex.create({ outline: { backgroundColor: { default: colorPalette.solid, ':is(:disabled, [disabled], [data-disabled])': semanticColors.borderEmphasized, }, }, solid: { backgroundColor: { default: colorPalette.solid, ':is(:disabled, [disabled], [data-disabled])': semanticColors.borderEmphasized, }, },})
const sliderMarkerGroup = stylex.create({ base: { position: 'absolute', top: 'var(--slider-marker-top)', insetInline: 'var(--slider-marker-inset)', zIndex: 1, },})
const sliderMarker = stylex.create({ base: { '--marker-bg': 'var(--sui-colors-bg)', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: spacing._1_5, color: semanticColors.fgMuted, fontSize: fontSizes.xs, },})
const sliderMarkerIndicator = stylex.create({ base: { width: 'var(--slider-marker-size)', height: 'var(--slider-marker-size)', borderRadius: radii.full, backgroundColor: 'var(--marker-bg)', },})
const sliderThumb = stylex.create({ base: { width: 'var(--slider-thumb-size)', height: 'var(--slider-thumb-size)', display: 'flex', alignItems: 'center', justifyContent: 'center', outline: 'none', zIndex: 2, borderRadius: radii.full, ring: { default: null, ':focus-visible': '2px', }, ringColor: { default: null, ':focus-visible': colorPalette.focusRing, }, ringOffset: { default: null, ':focus-visible': '2px', }, ringOffsetColor: { default: null, ':focus-visible': semanticColors.bg, }, },})
const sliderThumbVariants = stylex.create({ outline: { borderWidth: '2px', borderColor: { default: colorPalette.solid, ':is(:disabled, [disabled], [data-disabled])': semanticColors.borderEmphasized, }, backgroundColor: { default: semanticColors.bg, ':is(:disabled, [disabled], [data-disabled])': semanticColors.borderEmphasized, }, }, solid: { backgroundColor: { default: colorPalette.solid, ':is(:disabled, [disabled], [data-disabled])': semanticColors.borderEmphasized, }, },})
const sliderThumbOrientations = stylex.create({ vertical: { left: '50%', translate: '-50% 0', }, horizontal: { top: '50%', translate: '0 -50%', },})
export type SliderSize = keyof typeof sliderRootSizes
export type SliderVariant = keyof typeof sliderTrackVariants
export type SliderOrientation = keyof typeof sliderRootOrientations
const sliderRecipe = defineSlotRecipe({ slots: { root: { styles: sliderRoot, sizes: sliderRootSizes, orientations: sliderRootOrientations, }, control: { styles: sliderControl, orientations: sliderControlOrientations }, track: { styles: sliderTrack, variants: sliderTrackVariants, orientations: sliderTrackOrientations, }, range: { styles: sliderRange, variants: sliderRangeVariants }, thumb: { styles: sliderThumb, variants: sliderThumbVariants, orientations: sliderThumbOrientations, }, }, defaultVariants: { size: "md", variant: "outline", orientation: "horizontal" },});
const { withProvider, withContext, VariantContext } = createSlotRecipeContext(sliderRecipe);
function SliderRootNode(props: React.ComponentProps<typeof BaseSlider.Root>) { const { orientation } = useContext(VariantContext); return <BaseSlider.Root {...props} orientation={orientation} />;}
/** * Slider — Base UI's slider wearing the slider slot recipe. * `<Slider.Root variant size orientation>` resolves the recipe once and * every part inherits it through context. Orientation is both a recipe axis * and a machine prop — RootNode forwards it from the helper VariantContext. */export const Slider = { Root: withProvider(SliderRootNode, "root", "SliderRoot"), Control: withContext(BaseSlider.Control, "control", "SliderControl"), Track: withContext(BaseSlider.Track, "track", "SliderTrack"), Indicator: withContext(BaseSlider.Indicator, "range", "SliderIndicator"), Thumb: withContext(BaseSlider.Thumb, "thumb", "SliderThumb"),};
export type SliderRootProps = React.ComponentProps<typeof Slider.Root>;export type SliderControlProps = React.ComponentProps<typeof Slider.Control>;export type SliderTrackProps = React.ComponentProps<typeof Slider.Track>;export type SliderIndicatorProps = React.ComponentProps<typeof Slider.Indicator>;export type SliderThumbProps = React.ComponentProps<typeof Slider.Thumb>;