@empathyco/x-components
Version:
Empathy X Components
110 lines (107 loc) • 4.41 kB
JavaScript
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