Raiondesu / slider

Vue 3 slider component with multihandles, tooltips merging and formatting (+Tailwind support).

Home Page:https://vueform.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

npm CircleCI npm bundle size (scoped version) Discord npm

Vue 3 Slider






Sponsors


Other libraries

  • @vueform/multiselect - Vue 3 multiselect component with single select, multiselect and tagging options.
  • @vueform/toggle - Vue 3 toggle component with labels, custom slots and styling options.

Slider features

  • Vue 2 & 3 support
  • 100% coverage
  • TypeScript support
  • ESM support
  • Fully configurable
  • Single slider
  • Multiple sliders
  • Tooltips
  • Formatting
  • CSS vars support
  • Tailwind & utility class support
  • Based on noUiSlider

Demo

Check out our demo.

Installation

npm install @vueform/slider

Usage with Vue 3

<template>
  <div>
    <Slider v-model="value" />
  </div>
</template>

<script>
  import Slider from '@vueform/slider'

  export default {
    components: {
      Slider,
    },
    data() {
      return {
        value: 20
      }
    }
  }
</script>

<style src="@vueform/slider/themes/default.css"></style>

Using with Vue 2

When using Vue 2 install @vue/composition-api via npm/yarn first:

npm i @vue/composition-api --save-dev

Then install the plugin for Vue:

import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'

Vue.use(VueCompositionAPI)

After that make sure to change the imported Slider module to:

import Slider from '@vueform/slider/dist/slider.vue2.js'

Using with Nuxt.js

First you need install @nuxtjs/composition-api:

npm i @nuxtjs/composition-api --save-dev

Then you need to enable it as a module in nuxt.config.js:

{
  buildModules: [
    '@nuxtjs/composition-api'
  ]
}

After that make sure to change the imported module to Vue 2 version of Slider, as Nuxt.js still depends on that:

import Slider from '@vueform/slider/dist/slider.vue2.js'

Styling with CSS vars

The following CSS variables can be used to customize slider when using default.css:

--slider-bg: #D1D5DB;
--slider-connect-bg: #10B981;
--slider-connect-bg-disabled: #9CA3AF;
--slider-height: 6px;
--slider-vertical-height: 300px;
--slider-radius: 9999px;

--slider-handle-bg: #fff;
--slider-handle-border: 0;
--slider-handle-width: 16px;
--slider-handle-height: 16px;
--slider-handle-radius: 9999px;
--slider-handle-shadow: 0.5px 0.5px 2px 1px rgba(0,0,0,.32);
--slider-handle-shadow-active: 0.5px 0.5px 2px 1px rgba(0,0,0,.42);
--slider-handle-ring-width: 3px;
--slider-handle-ring-color: #10B98130;

--slider-tooltip-bg: #10B981;
--slider-tooltip-color: #fff;
--slider-tooltip-radius: 5px;
--slider-tooltip-min-width: 20px;
--slider-tooltip-font-size: 0.875rem;
--slider-tooltip-line-height: 1.25rem;
--slider-tooltip-font-weight: 600;
--slider-tooltip-py: 2px;
--slider-tooltip-px: 6px;
--slider-tooltip-arrow-size: 5px;
--slider-tooltip-distance: 3px;

Override them globally:

:root {
  --slider-connect-bg: #3B82F6;
  --slider-tooltip-bg: #3B82F6;
  --slider-handle-ring-color: #3B82F630;
}

Or on instance level:

<Slider
  v-model="value"
  class="slider-red"
/>

<Slider
  v-model="value"
  class="slider-blue"
/>
.slider-red {
  --slider-connect-bg: #EF4444;
  --slider-tooltip-bg: #EF4444;
  --slider-handle-ring-color: #EF444430;
}

.slider-blue {
  --slider-connect-bg: #3B82F6;
  --slider-tooltip-bg: #3B82F6;
  --slider-handle-ring-color: #3B82F630;
}

Styling with Tailwind CSS

To use the slider with Tailwind CSS you must add it as a plugin to tailwind.config.js:

// tailwind.config.js

module.exports = {
  // ...
  plugins: [
    require('@vueform/slider/tailwind'),
  ]
}

This plugin adds certain utilities and variants which are neccessary for the slider but Tailwind does not provide by default.

Once you've installed the plugin you can define utility classes for different parts of slider without having to require default.css. Here's a default styling for Tailwind CSS:

<Slider v-model="value" :classes="{
  target: 'relative box-border user-select-none touch-none tap-highlight-transparent touch-callout-none disabled:cursor-not-allowed',
  focused: 'slider-focused',
  tooltipFocus: 'slider-tooltip-focus',
  tooltipDrag: 'slider-tooltip-drag',
  ltr: 'slider-ltr',
  rtl: 'slider-rtl',
  horizontal: 'slider-horizontal h-1.5',
  vertical: 'slider-vertical w-1.5 h-80',
  textDirectionRtl: 'slider-txt-rtl',
  textDirectionLtr: 'slider-txt-ltr',
  base: 'w-full h-full relative z-1 bg-gray-300 rounded',
  connects: 'w-full h-full relative overflow-hidden z-0 rounded',
  connect: 'absolute z-1 top-0 right-0 transform-origin-0 transform-style-flat h-full w-full bg-green-500 cursor-pointer tap:duration-300 tap:transition-transform disabled:bg-gray-400 disabled:cursor-not-allowed',
  origin: 'slider-origin absolute z-1 top-0 right-0 transform-origin-0 transform-style-flat h-1/10 w-1/10 h:h-0 txt-rtl-h:left-0 txt-rtl-h:right-auto v:w-0 tap:duration-300 tap:transition-transform',
  handle: 'absolute rounded-full bg-white border-0 shadow-slider cursor-grab focus:outline-none h:w-4 h:h-4 h:-top-1.5 h:-right-2 txt-rtl-h:-left-2 txt-rtl-h:right-auto v:w-4 v:h-4 v:-top-2 v:-right-1.25 disabled:cursor-not-allowed focus:ring focus:ring-green-500 focus:ring-opacity-30',
  touchArea: 'h-full w-full',
  tooltip: 'absolute block text-sm font-semibold whitespace-nowrap py-1 px-1.5 min-w-5 text-center text-white rounded border border-green-500 bg-green-500 transform h:-translate-x-1/2 h:left-1/2 h:bottom-6 h:arrow-bottom v:-translate-y-1/2 v:top-1/2 v:right-6 v:arrow-right disabled:bg-gray-400 disabled:border-gray-400 merge-h:translate-x-1/2 merge-h:left-auto merge-h:bottom-3.5 merge-v:-translate-x-4 merge-v:top-auto merge-v:right-1 tt-focus:hidden tt-focused:block tt-drag:hidden tt-dragging:block',
  tooltipHidden: 'slider-tooltip-hidden',
  active: 'slider-active shadow-slider-active cursor-grabbing',
  draggable: 'cursor-ew-resize v:cursor-ns-resize',
  tap: 'slider-state-tap',
  drag: 'slider-state-drag',
}" />

There are certain variants that help detecting different states/config of the slider:

  • h - applied when the slider is horizontal
  • v - applied when the slider is vertical
  • merge-h - applied when the slider is horizontal and tooltips are merged
  • merge-v - applied when the slider is horizontal and tooltips are merged
  • disabled - applied when the slider is disabled
  • txt-rtl-h - applied when the slider is horizontal and text direction is set to rtl
  • tap - applied when the slider bar is being taped to jump to certain position
  • tt-focus - applied when the slider should only display tooltips on focus (showToolip: 'focus') and the slider is not focused
  • tt-focused - applied when the slider should only display tooltips on focus and the slider is focused
  • tt-drag - applied when the slider should only display tooltips on drag (showToolip: 'drag') and the slider is not being dragged
  • tt-dragging - applied when the slider should only display tooltips on drag and the slider is being dragged

The target class receives ltr, rtl, horizontal, vertical, textDirectionRtl, textDirectionLtr, focused, tooltipFocus, tooltipDrag, tap, and drag classes when the related state is applied.

Certain classes does not define any styles (like .slider-horizontal, .slider-vertical) but only required to detect certain states. If you are changing the class list for any class name make sure to always keep the ones that start with slider- to be able to use the utilities mentioned above (h, v, etc).

In case you need to override the same type of utility you might use @neojp/tailwind-important-variant and use eg. bg-green-500!.

Support

Join our Discord channel or open an issue.

Basic props

Name Type Default Description
id string slider The id attribute of slider container DOM.
disabled boolean false Whether the slider should be disabled.
min number 0 Minimum value of the slider.
max number 100 Maximum value of the slider.
step number 1 The jump between intervals. If -1 it enables fractions (eg. 1.23).
tooltips boolean true Whether tooltips should show above handlers.
showTooltip string 'always' When tooltips should be shown. Possible values: always|focus|drag.
merge number -1 The step distance between two handles when their tooltips should be merged (when step is -1 then 1 is assumed). Eg:

{ merge: 5, step: 10 }
-> values: 0, <=50 will merge
-> values: 0, 60 will not merge

{ merge: 5, step: -1 }
-> values: 0, <=5 will merge
-> values: 0, 5.01 will not merge
format object|function Formats the tooltip. It can be either a function that receives a value param and expects a string or number as return or an object with the following properties:
prefix - eg $ -> $100
suffix - eg USD -> 100USD
decimals - eg 2 -> 100.00
thousand - eg , - 1,000
orientation string 'horizontal' The orientation of the slider. Possible values: horizontal|vertical
direction string 'ltr' The direction of the slider. By default value increases left-to-right and top-to-bottom, which is reversed when using rtl. Possible values: ltr|rtl
classes object An object of class names that gets merged with the default values. Default:
{
  target: 'slider-target',
  ltr: 'slider-ltr',
  rtl: 'slider-rtl',
  horizontal: 'slider-horizontal',
  vertical: 'slider-vertical',
  textDirectionRtl: 'slider-txt-dir-rtl',
  textDirectionLtr: 'slider-txt-dir-ltr',
  base: 'slider-base',
  connects: 'slider-connects',
  connect: 'slider-connect',
  origin: 'slider-origin',
  handle: 'slider-handle',
  handleUpper: 'slider-handle-upper',
  handleLower: 'slider-handle-lower',
  touchArea: 'slider-touch-area',
  tooltip: 'slider-tooltip',
  active: 'slider-active',
  draggable: 'slider-draggable',
  tap: 'slider-state-tap',
  drag: 'slider-state-drag'
}

Events

Event Attributes Description
@change value Emitted when dragging the slider is finished or it's value changed by clicking, keyboard or programmatical set.
@update value Emitted in the same scenarios as changed, but also when the slider is being dragged.

Examples

Single slider

<template>
  <Slider
    v-model="value"
  />
</template>

<script>
  import Slider from '@vueform/slider'

  export default {
    components: { Slider },
    data: () => ({
      value: 20
    })
  }
</script>

JSFiddle - Example #1

Multiple slider

<template>
  <Slider
    v-model="value"
  />
</template>

<script>
  import Slider from '@vueform/slider'

  export default {
    components: { Slider },
    data: () => ({
      value: [20, 40]
    })
  }
</script>

JSFiddle - Example #2

Tooltip formatting

<template>
  <Slider
    v-model="value"
    :format="format"
  />
</template>

<script>
  import Slider from '@vueform/slider'

  export default {
    components: { Slider },
    data: () => ({
      value: 20,
      format: function (value) {
        return `${Math.round(value)}`
      }
    })
  }
</script>

JSFiddle - Example #3

Tooltip merging

<template>
  <Slider
    v-model="value"
    :merge="merge"
    :format="format"
  />
</template>

<script>
  import Slider from '@vueform/slider'

  export default {
    components: { Slider },
    data: () => ({
      value: [20, 30, 40],
      merge: 10,
      format: {
        prefix: '$',
        decimals: 2
      }
    })
  }
</script>

JSFiddle - Example #4

Vertical slider

<template>
  <Slider
    v-model="value"
  />
</template>

<script>
  import Slider from '@vueform/slider'

  export default {
    components: { Slider },
    data: () => ({
      value: 50,
      orientation: 'vertical',
      direction: 'rtl'
    })
  }
</script>

JSFiddle - Example #5

About Vueform

Vueform streamlines the entire form building process in Vue 2 & 3. It comes with 30+ elements, file uploads, element nesting, 50+ validators, conditions, form steps, i18n including reactive configuration, API access, ESM modules and many more. Check out our live demos or see all the features and sign up for beta to get early access.

License

MIT

About

Vue 3 slider component with multihandles, tooltips merging and formatting (+Tailwind support).

https://vueform.com

License:MIT License


Languages

Language:JavaScript 81.9%Language:SCSS 12.6%Language:Vue 5.5%