Slider
A slider input for selecting a single value or a range of values within a minimum and maximum.
<script setup lang="ts">
import { ref } from 'vue'
import { Slider } from 'frappe-ui'
const value = ref([25])
</script>
<template>
<div class="w-full max-w-md">
<Slider v-model="value" />
</div>
</template>Sizes
<script setup lang="ts">
import { ref } from 'vue'
import { Slider } from 'frappe-ui'
const small = ref([30])
const medium = ref([60])
</script>
<template>
<div class="flex flex-col gap-6 w-full max-w-md">
<Slider v-model="small" size="sm" label="Small" />
<Slider v-model="medium" size="md" label="Medium" />
</div>
</template>Range
Use a two-element modelValue to render two thumbs.
<script setup lang="ts">
import { ref } from 'vue'
import { Badge, Slider } from 'frappe-ui'
const value = ref([20, 80])
</script>
<template>
<div class="flex flex-col gap-3 w-full max-w-md">
<Slider v-model="value" label="Price range" />
<Badge class="w-fit !rounded-sm">{{ value.join(' – ') }}</Badge>
</div>
</template>Labeling
<script setup lang="ts">
import { computed, ref } from 'vue'
import { Checkbox, Slider } from 'frappe-ui'
const value = ref([40])
const required = ref(true)
const showError = ref(false)
const error = computed(() =>
showError.value ? 'Please pick a value greater than 50.' : '',
)
</script>
<template>
<div class="flex gap-8 items-start">
<Slider
v-model="value"
label="Volume"
description="Adjust the volume."
:error="error"
:required="required"
class="w-96"
/>
<div
class="flex flex-col gap-2 items-start border-l border-outline-gray-2 pl-6 shrink-0"
>
<Checkbox v-model="required" label="required" />
<Checkbox v-model="showError" label="show error" />
</div>
</div>
</template>value-commit
value-commit fires once when the user finishes dragging the slider — useful for triggering side effects only at drag end, not on every step.
<script setup lang="ts">
import { ref } from 'vue'
import { Slider } from 'frappe-ui'
const value = ref([50])
const commits = ref<number[][]>([])
function onValueCommit(committed: number[]) {
commits.value = [...commits.value, committed]
}
</script>
<!--
`value-commit` fires once at the end of a drag, not on every step.
Drag the slider thumb and release to log committed values below.
-->
<template>
<div class="flex flex-col gap-3 w-full max-w-md">
<Slider
v-model="value"
label="Drag and release to commit"
@value-commit="onValueCommit"
/>
<p class="text-p-sm text-ink-gray-6">
Commits: {{ commits.length ? commits.map((c) => c.join(',')).join(' · ') : '—' }}
</p>
</div>
</template>States
<script setup lang="ts">
import { ref } from 'vue'
import { Slider } from 'frappe-ui'
const a = ref([30])
const b = ref([30])
const c = ref([30])
const d = ref([30])
</script>
<template>
<div class="flex flex-col gap-6 w-full max-w-md">
<Slider v-model="a" label="Default" />
<Slider v-model="b" label="Required" required />
<Slider v-model="c" label="Disabled" disabled />
<Slider v-model="d" label="With error" error="Required." />
</div>
</template>API Reference
Show types
import type { ToggleSize } from '../../composables/inputTypes'
import type { InputLabelingProps } from '../../composables/useInputLabeling'
/**
* Value model for the Slider component.
* Use one number for a single-value slider or two numbers for a range slider.
*
* @example
* const single: SliderValue = [25]
*
* @example
* const range: SliderValue = [20, 80]
*/
export type SliderValue = number[]
export interface SliderProps extends InputLabelingProps {
/** Step interval between slider values. */
step?: number
/** Maximum allowed slider value. */
max?: number
/** Minimum allowed slider value. */
min?: number
/** Visual size of the slider. */
size?: ToggleSize
/** Disables the slider. */
disabled?: boolean
}
export interface SliderEmits {
/** Fired once when the user finishes dragging the slider. */
'value-commit': [value: SliderValue]
}Step interval between slider values.
Maximum allowed slider value.
Minimum allowed slider value.
Visual size of the slider.
Disables the slider.
Label rendered above (or beside, for binary controls) the input.
Helper text rendered below the input. Hidden when `error` is set.
Error message rendered below the input. When set, the control receives `aria-invalid="true"` and `data-state="invalid"`. May be either a string or an `Error` object whose `messages?: string[]` is rendered as stacked lines (with `Error.message` as the fallback).
Marks the field as required. Renders an asterisk next to the label and forwards `required` / `aria-required` to the underlying control.
HTML id of the underlying control. Auto-generated via `useId()` if omitted.
The current slider value (controlled).
| Slot | Payload |
|---|---|
label | { required: boolean; } Overrides the rendered label content. Receives `{ required }`. |
description | — Overrides the rendered description content. |
Overrides the rendered label content. Receives `{ required }`.
Overrides the rendered description content.
| Event | Payload |
|---|---|
update:modelValue | [value: SliderValue | undefined] Fired when the model value changes. |
value-commit | [value: SliderValue] Fired once when the user finishes committing the value. |
Fired when the model value changes.
Fired once when the user finishes committing the value.