<script setup>
import { Slider } from "@dicehub/kappa/components/slider";
</script>
<template>
<Slider.Root :default-value="[64]" :aria-label="['Mix level']">
<Slider.Label>Mix level</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb :index="0">
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
</template>Installation
Slider is part of the main Kappa package. Ark UI owns pointer input, value constraints, keyboard behavior, and slider semantics.
Barrel
import { Slider } from "@dicehub/kappa";Granular
import { Slider } from "@dicehub/kappa/components/slider";Usage
Compose a root with one Label, ValueText, Control, Track, Range, Thumb, and HiddenInput. Add one Thumb and HiddenInput pair for every value in a range slider.
<script setup>
import { Slider } from "@dicehub/kappa/components/slider";
</script>
<template>
<Slider.Root :default-value="[42]" :max="100" :step="1" :aria-label="['Opacity']">
<Slider.Label>Opacity</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track><Slider.Range /></Slider.Track>
<Slider.Thumb :index="0"><Slider.HiddenInput /></Slider.Thumb>
</Slider.Control>
</Slider.Root>
</template>Use a visible Slider.Label whenever possible. The label links to each generated thumb; use the per-thumb aria-label array for cases without visible text.
Composition
Slider.Root
├── Slider.Label
├── Slider.ValueText
├── Slider.Control
│ ├── Slider.Track
│ │ └── Slider.Range
│ └── Slider.Thumb
│ └── Slider.HiddenInput
├── Slider.MarkerGroup (optional)
│ └── Slider.Marker
├── Slider.DraggingIndicator (optional)
└── Slider.Context (optional)Ark UI provides range calculations, hidden form inputs, focus handling, and state attributes. Kappa provides the track geometry, token use, focus ring, marker layout, and size option.
Slider.MarkerGroup belongs after Slider.Control. Give every marker a numeric value; its position comes from the Ark machine.
Use Slider.Context to read the value or call an API method in a slot. Use RootProvider with useSlider when the machine is created outside the template.
<script setup>
import { Slider, useSlider } from "@dicehub/kappa/components/slider";
const api = useSlider({ defaultValue: [48] });
</script>
<template>
<Slider.RootProvider :value="api">
<!-- Compose Slider.Label, Control, Track, Range, Thumb, and HiddenInput. -->
</Slider.RootProvider>
</template>Examples
Range
Render two thumbs when a filter or interval needs a lower and upper bound.
<script setup>
import { Slider } from "@dicehub/kappa/components/slider";
</script>
<template>
<Slider.Root :default-value="[22, 78]" :min="0" :max="100" :aria-label="['Visible range']">
<Slider.Label>Visible range</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track><Slider.Range /></Slider.Track>
<Slider.Thumb :index="0"><Slider.HiddenInput /></Slider.Thumb>
<Slider.Thumb :index="1"><Slider.HiddenInput /></Slider.Thumb>
</Slider.Control>
</Slider.Root>
</template>Marks
Add non-interactive markers to make important values easy to scan.
<script setup>
import { Slider } from "@dicehub/kappa/components/slider";
</script>
<template>
<Slider.Root :default-value="[50]" :aria-label="['CPU limit']">
<Slider.Label>CPU limit</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track><Slider.Range /></Slider.Track>
<Slider.Thumb :index="0"><Slider.HiddenInput /></Slider.Thumb>
</Slider.Control>
<Slider.MarkerGroup>
<Slider.Marker :value="0">0%</Slider.Marker>
<Slider.Marker :value="50">50%</Slider.Marker>
<Slider.Marker :value="100">100%</Slider.Marker>
</Slider.MarkerGroup>
</Slider.Root>
</template>Vertical
Vertical controls use a block-size set by Kappa and Arrow Up or Arrow Down for keyboard input.
<script setup>
import { Slider } from "@dicehub/kappa/components/slider";
</script>
<template>
<Slider.Root
orientation="vertical"
:default-value="[68]"
:aria-label="['Temperature']"
>
<Slider.Label>Temperature</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track><Slider.Range /></Slider.Track>
<Slider.Thumb :index="0"><Slider.HiddenInput /></Slider.Thumb>
</Slider.Control>
</Slider.Root>
</template>Sizes
Small, base, and large sizes adjust track and thumb geometry without changing the value contract.
<script setup>
import { Slider } from "@dicehub/kappa/components/slider";
</script>
<template>
<Slider.Root size="sm" :default-value="[24]" :aria-label="['Small']">
<Slider.Label>Small</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track><Slider.Range /></Slider.Track>
<Slider.Thumb :index="0"><Slider.HiddenInput /></Slider.Thumb>
</Slider.Control>
</Slider.Root>
<Slider.Root size="lg" :default-value="[72]" :aria-label="['Large']">
<Slider.Label>Large</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track><Slider.Range /></Slider.Track>
<Slider.Thumb :index="0"><Slider.HiddenInput /></Slider.Thumb>
</Slider.Control>
</Slider.Root>
</template>States
Disabled, read-only, and invalid states keep clear visual and semantic differences.
<script setup>
import { Slider } from "@dicehub/kappa/components/slider";
</script>
<template>
<Slider.Root disabled :default-value="[30]" :aria-label="['Disabled']">
<Slider.Label>Disabled</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track><Slider.Range /></Slider.Track>
<Slider.Thumb :index="0"><Slider.HiddenInput /></Slider.Thumb>
</Slider.Control>
</Slider.Root>
<Slider.Root read-only invalid :default-value="[70]" :aria-label="['Read only']">
<Slider.Label>Read only</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track><Slider.Range /></Slider.Track>
<Slider.Thumb :index="0"><Slider.HiddenInput /></Slider.Thumb>
</Slider.Control>
</Slider.Root>
</template>Controlled
Use v-model when another control or application state owns the current value.
<script setup>
import { ref } from "vue";
import { Slider } from "@dicehub/kappa/components/slider";
const value = ref([36]);
</script>
<template>
<Slider.Root v-model="value" :aria-label="['Solver progress']">
<Slider.Label>Solver progress</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track><Slider.Range /></Slider.Track>
<Slider.Thumb :index="0"><Slider.HiddenInput /></Slider.Thumb>
</Slider.Control>
</Slider.Root>
<output aria-live="polite">{{ value[0] }}%</output>
</template>Centered Origin
Use origin="center" for offsets that should fill from the middle of the track.
<Slider.Root :default-value="[64]" origin="center" :aria-label="['Offset']">
<Slider.Label>Offset</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track><Slider.Range /></Slider.Track>
<Slider.Thumb :index="0"><Slider.HiddenInput /></Slider.Thumb>
</Slider.Control>
</Slider.Root>Accessibility
- Each thumb exposes
role=slider, its current value, range, orientation, and disabled state. - Use
Slider.Labelfor a visible accessible name. Use onearia-labeloraria-labelledbyentry per thumb when no visible label exists. - Keep a
Slider.HiddenInputinside every thumb when the value must submit with a native form. - Read-only sliders remain focusable but do not change their value. Disabled sliders are removed from focus and interaction.
- Focus-visible, invalid, forced-colors, reduced-motion, and dark-mode styles remain distinct.
Keyboard Support
| Key | Behavior |
|---|---|
Arrow keys | Increment or decrement the focused thumb along its orientation axis. |
PageUp / PageDown | Change the value by largeStep. |
Shift + Arrow keys | Change the value by largeStep. |
Home / End | Set the focused thumb to its minimum or maximum. |
API Reference
Slider.Root
| Prop | Type | Default | Description |
|---|---|---|---|
defaultValue / modelValue | number[] | [0] / — | Initial or controlled thumb values. |
min / max / step | number | 0 / 100 / 1 | Numeric range and keyboard granularity. |
orientation | "horizontal" | "vertical" | "horizontal" | Sets the track axis and keyboard axis. |
origin | "start" | "center" | "start" | Sets the fill origin for a single thumb. |
disabled / readOnly / invalid | boolean | false | Complete state flags owned by the Ark machine. |
aria-label / aria-labelledby | string[] | — | Optional per-thumb accessible names. Slider.Label is preferred for visible labels. |
largeStep | number | 10 × step | Increment used by Page keys and Shift + Arrow keys. |
minStepsBetweenThumbs | number | 0 | Minimum step gap between multiple thumbs. |
thumbAlignment | "center" | "contain" | "contain" | Controls whether thumbs extend beyond the track ends. |
thumbCollisionBehavior | "none" | "push" | "swap" | "none" | Controls multiple-thumb collision behavior. |
name / form | string | — | Associates hidden inputs with a native form. |
getAriaValueText | (details) => string | — | Formats each thumb's accessible value text. |
dir / id / ids / asChild / thumbSize | Ark UI types | Ark defaults | Direction, machine IDs, composition, and measured thumb sizing. |
size | "sm" | "base" | "lg" | "base" | Selects Kappa control geometry. It does not change values or behavior. |
Parts
| Part | Element | Description |
|---|---|---|
Slider.Root | div | Owns values, range, state, and slider semantics. |
Slider.RootProvider | div | Provides an externally created Ark slider machine. |
Slider.Label | label | Visible accessible label for the thumb inputs. |
Slider.ValueText | span | Current value text, or a custom slot. |
Slider.Control | div | Pointer interaction surface and positioning context. |
Slider.Track / Range | div | Track background and resolved active range. |
Slider.Thumb | div | Focusable slider thumb. Add one HiddenInput per thumb. |
Slider.HiddenInput | input | Native form value associated with its thumb. |
Slider.MarkerGroup / Marker | div / span | Non-interactive scale marks positioned by value. |
Slider.DraggingIndicator | span | Optional visual value shown while its thumb is dragged. |
Slider.Context | renderless | Exposes the Ark slider API to a slot. |
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue | number[] | Updates v-model after a value change. |
valueChange | SliderValueChangeDetails | Reports each value change. |
valueChangeEnd | SliderValueChangeDetails | Reports the end of a pointer or keyboard interaction. |
focusChange | SliderFocusChangeDetails | Reports the focused thumb index. |
Slots
| Slot | Description |
|---|---|
Root.default | Slider parts in the Ark anatomy order. |
Label / ValueText / Control / Track / Range | Visible content for each styled part. |
Thumb.default | HiddenInput and optional DraggingIndicator content. |
MarkerGroup.default / Marker.default | Scale marks and optional labels. |
Context.default | Receives the renderless slider API. |
Data Attributes
| Attribute | Value | Description |
|---|---|---|
data-slot | "slider" and part names | Identifies Kappa root and parts. |
data-scope / data-part | "slider" / Ark part | Ark UI anatomy markers. |
data-orientation | "horizontal" | "vertical" | Exposes the active axis on root and parts. |
data-disabled / data-invalid / data-dragging / data-focus | present | Exposes Ark interaction and validation states. |
data-readonly | present | Kappa marker for the read-only root state. |
data-size | "sm" | "base" | "lg" | Exposes the resolved Kappa geometry option. |
data-index / data-state / data-value | part-specific | Exposes thumb and marker identity and marker position state. |
Exports
| Export | Description |
|---|---|
Slider | Compound Ark-backed range control. |
SliderRoot / RootProvider / Label / ValueText / Control | Named root and interaction parts. |
SliderTrack / Range / Thumb / HiddenInput | Track, fill, thumb, and native form parts. |
SliderMarkerGroup / Marker / DraggingIndicator / Context | Scale, drag feedback, and renderless parts. |
SliderProps / *Props / SliderEmits / *Slots | Public Vue props, events, and slot contracts. |
SliderSize / SLIDER_* / isSliderSize / resolveSliderSize | Kappa geometry options and safe resolvers. |
useSlider / useSliderContext / sliderAnatomy | Ark UI composition exports. |