Skip to content

A Vue range / slider component that supports one or more thumb

License

Notifications You must be signed in to change notification settings

wiidede/vue-range-multi

Repository files navigation

Vue Range Multi

npm version npm downloads bundle JSDocs License

Vue Range Multi Logo

A Vue range(slider) component that supports one or more thumb

  • ✨ Support for one or more thumbs.
  • 🔄 Auto-detect the type of model and display the corresponding thumb(s).
  • 🔀 Automatically sort the model values without sorting the DOM.
  • ➕ Ability to add or remove thumbs dynamically.
  • 🚫 Avoid duplicate thumbs by rejecting them.
  • 🍡 Smooth movement or jump movement over the stops.
  • 🎨 Customizable style and theme.
  • 🌓 Supports dark mode.
  • 📍 Render content above or below the thumb(render function / slot).
  • 🏷 Support display marks under the track.

Demo

Demo

Quick Start

  1. Install
pnpm add vue-range-multi
  1. Use in Vue

in SFC

<script setup lang="ts">
import { ref } from 'vue'
import { Range } from 'vue-range-multi'
import 'vue-range-multi/style.css'

const model = ref<number>(0)
</script>

<template>
  <Range v-model="model" />
</template>

install globally

// main.ts
import { Range } from 'vue-range-multi'
import 'vue-range-multi/style.css'

app.component('MRange', Range)
declare module 'vue' {
  export interface GlobalComponents {
    MRange: typeof import('vue-range-multi')['Range']
  }
}

unplugin-vue-components

import { VueRangeMultiResolver } from 'vue-range-multi'

// and then add `VueRangeMultiResolver()` into resolvers
// type of options
interface VueRangeMultiResolverOptions {
  /**
   * The name of the component. It should always CapitalCase
   *
   * @default 'MRange'
   */
  name?: string
}

Props

generic="T = any, U = number | RangeData<T>"

Name Type Description Default
v-model:modelValue* U \ U[] Model value. It will automatically detect the type of model and show the corresponding thumb(s) []
min number The minimum value allowed 0
max number The maximum value allowed 100
step number Step 1
vertical boolean Determines if the range is vertical. Note that it will generate new classes like 'm-range-v-xxx' false
addable boolean Determines if new data can be added/deleted. You can specify the data to be added by addData prop false
addData (value: number) => RangeData<T, U> Data to be added. This will only effect while modelValue is RangeData[]. It will return { value } by default undefined
limit number the limit can be add undefined
smooth boolean Determines if the thumb(s) should only be displayed on the stop points or not false
deduplicate boolean Determines if the thumb(s) can be duplicated true
rangeHighlight boolean Determines if the range between the minimum and maximum values should be highlighted. This only has an effect when the modelValue is an array with a length of 2 false
showStops boolean | number Determines if dots should be displayed on the track. When set to a number, dots will only be displayed if the number of stops is less than the specified value 12
size 'small' | 'medium' | 'large' Track size 'small'
thumbType 'circle' | 'square' | 'rect' Thumb type(default 'rect' while size is 'large', otherwise 'small') 'circle' | 'rect'
thumbSize 'small' | 'medium' | 'large' Thumb size 'medium'
renderTop (data: U) => VNode A render function for displaying content above the thumb undefined
renderTopOnActive boolean Specifies whether to render only while the thumb is active false
renderBottom (data: U) => VNode A render function for displaying content below the thumb undefined
renderBottomOnActive boolean Specifies whether to render only while the thumb is active false
marks RangeMarks Show marks under the track undefined

slots

Name Type Description
top { data: U } render above the thumb, only effect while renderTop is undefined
bottom { data: U } render below the thumb, only effect while renderBottom is undefined

types

export type RangeValueType<T> = number | RangeData<T>
export interface RangeData<T, U = RangeValueType<T>> {
  value: number
  data?: T
  disabled?: boolean
  unremovable?: boolean
  renderTop?: RangeRenderFn<T, U>
  renderBottom?: RangeRenderFn<T, U>
}
export type RangeRenderFn<T, U = RangeValueType<T>> = (data: U) => VNode
export type RangeValue<T, U = RangeValueType<T>> = U | U[]
export type RangeMarks = Record<number, string | {
  label: string
  style?: CSSProperties
  class?: string
}>

theme

If you want to customize the theme, just use CSS variables to override the default theme.

.m-range-theme {
  --c-primary: #409eff; /* primary color */
  --c-fill: #e4e7ed; /* track's fill color */
  --c-fill-stop: #f5f5f5; /* stop's fill color */
  --c-fill-thumb: #fff; /* thumb's fill color */
}

License

MIT License © 2023-PRESENT wiidede