Slider
This component somehow reminds me of a sliding rheostat, and this piece of music. 😂
Basic Usage
Pass modelValue to enter controlled mode. If not passed or is undefined, it will be in uncontrolled mode, where you can pass the defaultValue prop as the default value.
Controlled
Uncontrolled
<template>
<px-space direction="vertical">
<h4>Controlled</h4>
<px-slider v-model="input"></px-slider>
<px-input-number v-model="input" :min="0" :max="100"></px-input-number>
<h4>Uncontrolled</h4>
<px-slider :default-value="50"></px-slider>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const input = ref(0)
</script>
<style lang="css" scoped>
.px-slider,
.px-input-number {
width: 400px;
}
</style>Range Selection
The range prop enables range selection.
<template>
<px-space direction="vertical">
<px-slider v-model="input"></px-slider>
<px-slider :default-value="[25, 50]" range></px-slider>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const input = ref([0, 10])
</script>
<style lang="css" scoped>
.px-slider {
width: 400px;
}
</style>Value Range, Step & Precision
min and max set the numerical range. step sets the step size; when it is 0, the step size is not limited.
The precision parameter controls the minimum precision of the numerical value. It takes an integer in [0, 100]; when it is null, the minimum precision is not limited.
Setting the
precisionparameter is primarily intended to handle unexpected approximate values resulting from precision loss in JS floating-point calculations.
<template>
<px-space direction="vertical">
<px-slider v-model="input0" :min="0" :max="114514" :step="114"></px-slider>
<px-input-number v-model="input0" :min="0" :max="114514" :step="114"></px-input-number>
<px-slider v-model="input1" :min="0" :max="114514" :step="0"></px-slider>
<px-input-number v-model="input1"></px-input-number>
<px-slider v-model="input2" :min="0" :max="114514" :step="0" :precision="null"></px-slider>
<px-input-number v-model="input2"></px-input-number>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const input0 = ref(0)
const input1 = ref(0)
const input2 = ref(0)
</script>
<style lang="css" scoped>
.px-slider,
.px-input-number {
width: 400px;
}
</style>Readonly & Disabled
readonly sets it to read-only, disabled sets it to disabled. The only difference between them is almost just the styling.
<template>
<px-space direction="vertical">
<px-slider :default-value="75" readonly></px-slider>
<px-slider :default-value="25" disabled></px-slider>
</px-space>
</template>
<style lang="css" scoped>
.px-slider {
width: 400px;
}
</style>Marks
marks sets the marks on the slider. When step is set to 'mark', only values at the marks can be selected.
<template>
<px-space direction="vertical">
<px-slider v-model="input0" :marks="marks" :step="0.01"></px-slider>
<px-slider v-model="input1" :marks="marks" step="mark"></px-slider>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const input0 = ref(50)
const input1 = ref(50)
const marks = [{ value: 15.87, label: 'μ-σ' }, 50, { value: 84.13, label: 'μ+σ' }]
</script>
<style lang="css" scoped>
.px-slider {
width: 400px;
}
</style>Label Rendering
The mark slot customizes the rendering of labels of marks.
<template>
<px-space direction="vertical">
<px-slider v-model="input0" :marks="marks" :step="0.01">
<template #mark="{ value, label }">
<div
style="display: flex; align-items: center"
:style="{ color: value < 50 ? '#FF7D00' : '#00B42A' }"
>
<IconAnalytics style="margin-right: 4px"></IconAnalytics>
{{ label || 'μ' }}
</div>
</template>
</px-slider>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { IconAnalytics } from '@pixelium/web-vue/icon-hn/es'
const input0 = ref(50)
const marks = [{ value: 15.87, label: 'μ-σ' }, 50, { value: 84.13, label: 'μ+σ' }]
</script>
<style lang="css" scoped>
.px-slider {
width: 400px;
}
</style>Vertical Orientation
direction sets the orientation of the slider. When vertical, the height defaults to the container's height, but you can also set the height yourself.
<template>
<px-space>
<px-slider v-model="input" direction="vertical"></px-slider>
<px-slider v-model="input" direction="vertical" :marks="marks"></px-slider>
<px-slider v-model="input" range direction="vertical"></px-slider>
<px-slider v-model="input" range direction="vertical" :marks="marks">
<template #mark="{ value, label }">
<div
style="display: flex; align-items: center"
:style="{ color: value < 30 ? '#FF7D00' : '#00B42A' }"
>
<IconBolt style="margin-right: 4px"></IconBolt>
{{ label || 'μ' }}
</div>
</template>
</px-slider>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { IconBolt } from '@pixelium/web-vue/icon-hn/es'
const input = ref(0)
const marks = [
{ value: 0, label: '0%' },
{ value: 25, label: '25%' },
{ value: 50, label: '50%' },
{ value: 75, label: '75%' },
{ value: 100, label: '100%' }
]
</script>
<style lang="css" scoped>
.px-slider {
height: 400px;
margin-right: 48px;
}
</style>Track Reversal
direction sets the orientation of the slider. When vertical, the height defaults to the container's height, but you can also set the height yourself.
<template>
<px-space>
<px-space direction="vertical">
<px-slider v-model="input" :marks="marks"></px-slider>
<px-slider v-model="inputRange" range :marks="marks"></px-slider>
<px-slider v-model="input" reverse :marks="marks"></px-slider>
<px-slider v-model="inputRange" reverse range :marks="marks"></px-slider>
</px-space>
<px-space>
<px-slider v-model="input" direction="vertical" :marks="marks"></px-slider>
<px-slider v-model="inputRange" range direction="vertical" :marks="marks"></px-slider>
<px-slider v-model="input" reverse direction="vertical" :marks="marks"></px-slider>
<px-slider
v-model="inputRange"
reverse
range
direction="vertical"
:marks="marks"
></px-slider>
</px-space>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const marks = [
{ value: 0, label: '0°C' },
{ value: 20, label: '20°C' },
{ value: 37, label: '37°C' },
{ value: 100, label: '100°C' },
50
]
const inputRange = ref([0, 10])
const input = ref(37)
</script>
<style lang="css" scoped>
.px-slider__horizontal {
width: 400px;
}
.px-slider__vertical {
height: 400px;
margin-right: 24px;
margin-left: 24px;
}
</style>Thumb Indicator
You can use the thumb, thumb-start, and thumb-end slots to customize the content inside the thumbs.
<template>
<px-space direction="vertical">
<px-slider :default-value="50">
<template #thumb>
<IconHumanRun></IconHumanRun>
</template>
</px-slider>
<px-slider :default-value="[25, 50]" range>
<template #thumb-start> L </template>
<template #thumb-end> R </template>
</px-slider>
</px-space>
</template>
<script lang="ts" setup>
import { IconHumanRun } from '@pixelium/web-vue/icon-pa/es'
</script>
<style lang="css" scoped>
.px-slider {
width: 400px;
}
</style>API
SliderProps
| Attribute | Type | Optional | Default | Description | Version |
|---|---|---|---|---|---|
| modelValue | number | [number, number] | null | True | | The value of the slider (controlled mode), supports v-model. | 0.0.3 |
| defaultValue | number | [number, number] | null | True | | The default value of the slider (uncontrolled mode). | 0.0.3 |
| min | number | True | 0 | The minimum value of the slider (inclusive). | 0.0.3 |
| max | number | True | 100 | The maximum value of the slider (inclusive). | 0.0.3 |
| range | boolean | True | false | Range selection. | 0.0.3 |
| disabled | boolean | True | false | Disabled state. | 0.0.3 |
| readonly | boolean | True | false | Read-only state. | 0.0.3 |
| step | number | 'mark' | True | 1 | The step size of the values. | 0.0.3 |
| marks | (number | { value: number; label?: string })[] | True | | Marks on the slider. | 0.0.3 |
| direction | 'horizontal' | 'vertical' | True | 'horizontal' | The orientation of the slider. | 0.0.3 |
| reverse | boolean | True | false | Whether to reverse the track. | 0.0.3 |
| precision | number | null | True | 8 | 0.0.3 | |
| tooltip | boolean | True | true | Whether to enable text tooltip. | 0.0.3 |
| tooltipProps | Omit<TooltipProps, 'visible' | 'content'> & EmitEvent<TooltipEvents> | True | | Props for the Tooltip component in single-value mode. | 0.0.3 |
| tooltipStartProps | Omit<TooltipProps, 'visible' | 'content'> & EmitEvent<TooltipEvents> | True | | Props for the first Tooltip component in range selection mode. | 0.0.3 |
| tooltipEndProps | Omit<TooltipProps, 'visible' | 'content'> & EmitEvent<TooltipEvents> | True | | Props for the second Tooltip component in range selection mode. | 0.0.3 |
SliderEvent
| Attribute | Type | Optional | Default | Description | Version |
|---|---|---|---|---|---|
| 'update:modelValue' | | False | | 0.0.3 | |
| change | | False | | 0.0.3 | |
| dragStart | | False | | 0.0.3 | |
| dragEnd | | False | | 0.0.3 | |
| markSelect | | False | | 0.0.3 | |
| focus | | False | | 0.0.3 | |
| blur | | False | | 0.0.3 |
SliderSlots
| Slot | Parameter | Description | Version |
|---|---|---|---|
| mark | value: number, label: string | undefined | Rendering of mark labels. | 0.0.3 |
| thumb | | Content of the thumb in single-value mode. | 0.0.3 |
| thumb-start | | Content of the first thumb in range selection mode. | 0.0.3 |
| thumb-end | | Content of the second thumb in range selection mode. | 0.0.3 |
| tooltip-content | value: number | Content of the text tooltip. | 0.0.3 |
EmitEvent
export type EmitEvent<T extends Record<string, any>> = {
[K in keyof T as `on${Capitalize<K & string>}`]?: (...args: T[K]) => void
}2
3