UNPKG

@empathyco/x-components

Version:
110 lines (107 loc) 4.41 kB
import { create } from 'nouislider'; import { defineComponent, ref, computed, onMounted, onUnmounted, watch } from 'vue'; /** * This component implements a range slider and prints the selected values. * It receives a threshold prop to set the limits and uses v-model to get and set * the selected values. * * It makes use of the nouslider library @see https://refreshless.com/nouislider/ * for the slider implementation. * */ var _sfc_main = defineComponent({ name: 'BaseSlider', props: { /** The threshold prop sets the limits for the slider. */ threshold: { type: Object, default: () => ({ min: 0, max: Number.MAX_SAFE_INTEGER }), }, /** The modelValue prop sets the initial values for the slider. */ modelValue: { type: Object, required: true, }, /** Class to be able to customize slider styles. */ contentClass: { type: String, default: '', }, }, /** * The component emits an event with the selected values whenever * the user changes the slider. */ emits: ['update:modelValue'], setup(props, { emit }) { /** The nouislider instance. */ let sliderInstance; /** The nouislider element reference. */ const slider = ref(); /** The selected min value. */ const minSelected = ref(props.modelValue?.min ?? props.threshold.min); /** The selected max value. */ const maxSelected = ref(props.modelValue?.max ?? props.threshold.max); /** The selected range as an array. */ const rangeSelected = computed(() => [minSelected.value, maxSelected.value]); /** The range for the nouislider. */ const slideRange = computed(() => ({ min: props.threshold.min, max: props.threshold.max })); onMounted(() => { // Create the slider instance sliderInstance = create(slider.value, { start: rangeSelected.value, range: slideRange.value, step: 1, connect: true, margin: 1, }); // Update the selected values when the slider update its values sliderInstance.on('update', ([min, max]) => { minSelected.value = Number(min); maxSelected.value = Number(max); }); // Emits the selected values when the slider values change sliderInstance.on('change', () => emit('update:modelValue', { min: minSelected.value, max: maxSelected.value })); }); onUnmounted(() => { // Waiting to finish the collapse animation before destroying it setTimeout(sliderInstance.destroy.bind(sliderInstance), 600); }); /** * Watch the threshold prop to update the slider state and emit the selected values. */ watch(() => props.threshold, ({ min, max }) => { sliderInstance.updateOptions({ range: slideRange.value, start: [min, max] }, false); emit('update:modelValue', { min, max }); }); /** * Watch the modelValue prop to update the slider state. * * @remarks It only update the values if the values are corrects. It means, * values within the threshold limits and not equal to the current values. * * @returns Undefined. */ watch([() => props.modelValue.min, () => props.modelValue.max], ([min, max]) => { // Check if the values are the same if (min === minSelected.value && max === maxSelected.value) { return; } // Validate the values const minValidated = min < props.threshold.min ? props.threshold.min : min; const maxValidated = max > props.threshold.max ? props.threshold.max : max; // Update the nouislider values sliderInstance.set([minValidated, maxValidated]); // Emit the selected values if (minValidated !== min || maxValidated !== max) { emit('update:modelValue', { min: minValidated, max: maxValidated }); } }); return { slider, rangeSelected, }; }, }); export { _sfc_main as default }; //# sourceMappingURL=base-slider.vue2.js.map