UNPKG

vue-3-slider-component

Version:

A highly customized slider component for Vue 3

1,386 lines (1,385 loc) 45.7 kB
(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode('.vue-slider-dot{position:absolute;transition:all 0s;z-index:5}.vue-slider-dot:focus{outline:none}.vue-slider-dot-tooltip{position:absolute;visibility:hidden}.vue-slider-dot-hover:hover .vue-slider-dot-tooltip,.vue-slider-dot-tooltip-show{visibility:visible}.vue-slider-dot-tooltip-top{top:-10px;left:50%;transform:translate(-50%,-100%)}.vue-slider-dot-tooltip-bottom{bottom:-10px;left:50%;transform:translate(-50%,100%)}.vue-slider-dot-tooltip-left{left:-10px;top:50%;transform:translate(-100%,-50%)}.vue-slider-dot-tooltip-right{right:-10px;top:50%;transform:translate(100%,-50%)}.vue-slider-marks{position:relative;width:100%;height:100%}.vue-slider-mark{position:absolute;z-index:1}.vue-slider-ltr .vue-slider-mark,.vue-slider-rtl .vue-slider-mark{width:0;height:100%;top:50%}.vue-slider-ltr .vue-slider-mark-step,.vue-slider-rtl .vue-slider-mark-step{top:0}.vue-slider-ltr .vue-slider-mark-label,.vue-slider-rtl .vue-slider-mark-label{top:100%;margin-top:10px}.vue-slider-ltr .vue-slider-mark{transform:translate(-50%,-50%)}.vue-slider-ltr .vue-slider-mark-step{left:0}.vue-slider-ltr .vue-slider-mark-label{left:50%;transform:translate(-50%)}.vue-slider-rtl .vue-slider-mark{transform:translate(50%,-50%)}.vue-slider-rtl .vue-slider-mark-step{right:0}.vue-slider-rtl .vue-slider-mark-label{right:50%;transform:translate(50%)}.vue-slider-ttb .vue-slider-mark,.vue-slider-btt .vue-slider-mark{width:100%;height:0;left:50%}.vue-slider-ttb .vue-slider-mark-step,.vue-slider-btt .vue-slider-mark-step{left:0}.vue-slider-ttb .vue-slider-mark-label,.vue-slider-btt .vue-slider-mark-label{left:100%;margin-left:10px}.vue-slider-btt .vue-slider-mark{transform:translate(-50%,50%)}.vue-slider-btt .vue-slider-mark-step{top:0}.vue-slider-btt .vue-slider-mark-label{top:50%;transform:translateY(-50%)}.vue-slider-ttb .vue-slider-mark{transform:translate(-50%,-50%)}.vue-slider-ttb .vue-slider-mark-step{bottom:0}.vue-slider-ttb .vue-slider-mark-label{bottom:50%;transform:translateY(50%)}.vue-slider-mark-step,.vue-slider-mark-label{position:absolute}.vue-slider-disabled{opacity:.5;cursor:not-allowed}.vue-slider-rail{background-color:#ccc;border-radius:15px}.vue-slider-process{background-color:#3498db;border-radius:15px}.vue-slider-mark{z-index:4}.vue-slider-mark:first-child .vue-slider-mark-step,.vue-slider-mark:last-child .vue-slider-mark-step{display:none}.vue-slider-mark-step{width:100%;height:100%;border-radius:50%;background-color:#00000029}.vue-slider-mark-label{font-size:14px;white-space:nowrap}.vue-slider-dot-handle{cursor:pointer;width:100%;height:100%;border-radius:50%;background-color:#fff;box-sizing:border-box;box-shadow:.5px .5px 2px 1px #00000052}.vue-slider-dot-handle-focus{box-shadow:0 0 1px 2px #3498db5c}.vue-slider-dot-handle-disabled{cursor:not-allowed;background-color:#ccc}.vue-slider-dot-tooltip-inner{font-size:14px;white-space:nowrap;padding:2px 5px;min-width:20px;text-align:center;color:#fff;border-radius:5px;border-color:#3498db;background-color:#3498db;box-sizing:content-box}.vue-slider-dot-tooltip-inner:after{content:"";position:absolute}.vue-slider-dot-tooltip-inner-top:after{top:100%;left:50%;transform:translate(-50%);height:0;width:0;border-color:transparent;border-style:solid;border-width:5px;border-top-color:inherit}.vue-slider-dot-tooltip-inner-bottom:after{bottom:100%;left:50%;transform:translate(-50%);height:0;width:0;border-color:transparent;border-style:solid;border-width:5px;border-bottom-color:inherit}.vue-slider-dot-tooltip-inner-left:after{left:100%;top:50%;transform:translateY(-50%);height:0;width:0;border-color:transparent;border-style:solid;border-width:5px;border-left-color:inherit}.vue-slider-dot-tooltip-inner-right:after{right:100%;top:50%;transform:translateY(-50%);height:0;width:0;border-color:transparent;border-style:solid;border-width:5px;border-right-color:inherit}.vue-slider-dot-tooltip-wrapper{opacity:0;transition:all .3s}.vue-slider-dot-tooltip-wrapper-show{opacity:1}.vue-slider{position:relative;box-sizing:content-box;-webkit-user-select:none;user-select:none;display:block;-webkit-tap-highlight-color:rgba(0,0,0,0)}.vue-slider-rail{position:relative;width:100%;height:100%;transition-property:width,height,left,right,top,bottom}.vue-slider-process{position:absolute;z-index:1}')),document.head.appendChild(e)}}catch(r){console.error("vite-plugin-css-injected-by-js",r)}})(); var N = Object.defineProperty; var T = (s, t, e) => t in s ? N(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e; var l = (s, t, e) => (T(s, typeof t != "symbol" ? t + "" : t, e), e); import { openBlock as u, createElementBlock as f, normalizeClass as g, renderSlot as c, createElementVNode as D, normalizeStyle as p, toDisplayString as I, createCommentVNode as w, resolveComponent as L, mergeProps as m, Fragment as P, renderList as R, createBlock as U, withCtx as A, createVNode as _ } from "vue"; const B = (s, t) => { const e = s.__vccOpts || s; for (const [i, a] of t) e[i] = a; return e; }, W = { emits: ["drag-start"], props: { value: { type: [Number, String], // number | string default: 0 }, tooltip: { type: String, // 'none' | 'always' | 'focus' | 'hover' | 'active' required: !0 }, dotStyle: { type: Array, // ([key: string]: any)[] default: () => ({}) }, tooltipStyle: { type: Array, // ([key: string]: any)[] default: () => ({}) }, tooltipPlacement: { type: String, // 'top' | 'right' | 'bottom' | 'left' required: !0 }, tooltipFormatter: { type: [String, Array, Object, Function], default: void 0 }, focus: { type: Boolean, default: !1 }, disabled: { type: Boolean, default: !1 } }, computed: { dotClasses() { return [ "vue-slider-dot", { "vue-slider-dot-hover": this.tooltip === "hover" || this.tooltip === "active", "vue-slider-dot-disabled": this.disabled, "vue-slider-dot-focus": this.focus } ]; }, handleClasses() { return [ "vue-slider-dot-handle", { "vue-slider-dot-handle-disabled": this.disabled, "vue-slider-dot-handle-focus": this.focus } ]; }, tooltipClasses() { return [ "vue-slider-dot-tooltip", [`vue-slider-dot-tooltip-${this.tooltipPlacement}`], { "vue-slider-dot-tooltip-show": this.showTooltip } ]; }, tooltipInnerClasses() { return [ "vue-slider-dot-tooltip-inner", [`vue-slider-dot-tooltip-inner-${this.tooltipPlacement}`], { "vue-slider-dot-tooltip-inner-disabled": this.disabled, "vue-slider-dot-tooltip-inner-focus": this.focus } ]; }, showTooltip() { switch (this.tooltip) { case "always": return !0; case "none": return !1; case "focus": case "active": return !!this.focus; default: return !1; } }, tooltipValue() { return this.tooltipFormatter ? typeof this.tooltipFormatter == "string" ? this.tooltipFormatter.replace(/\{value\}/, String(this.value)) : this.tooltipFormatter(this.value) : this.value; } }, methods: { dragStart(s) { if (this.disabled) return !1; this.$emit("drag-start"); } } }, K = ["aria-valuetext"], q = { class: "vue-slider-dot-tooltip-text" }; function $(s, t, e, i, a, r) { return u(), f("div", { ref: "dot", class: g(r.dotClasses), "aria-valuetext": r.tooltipValue, onMousedown: t[0] || (t[0] = (...n) => r.dragStart && r.dragStart(...n)), onTouchstartPassive: t[1] || (t[1] = (...n) => r.dragStart && r.dragStart(...n)) }, [ c(s.$slots, "dot", {}, () => [ D("div", { class: g(r.handleClasses), style: p(e.dotStyle) }, null, 6) ]), e.tooltip !== "none" ? (u(), f("div", { key: 0, class: g(r.tooltipClasses) }, [ c(s.$slots, "tooltip", {}, () => [ D("div", { class: g(r.tooltipInnerClasses), style: p(e.tooltipStyle) }, [ D("span", q, I(r.tooltipValue), 1) ], 6) ]) ], 2)) : w("", !0) ], 42, K); } const M = /* @__PURE__ */ B(W, [["render", $]]), X = { props: { mark: { type: Object, // Mark required: !0 }, hideLabel: { type: Boolean, default: !1 }, stepStyle: { type: Object, // [key: string]: any default: void 0 }, stepActiveStyle: { type: Object, // [key: string]: any default: void 0 }, labelStyle: { type: Object, // [key: string]: any default: void 0 }, labelActiveStyle: { type: Object, // [key: string]: any default: void 0 } }, computed: { marksClasses() { return [ "vue-slider-mark", { "vue-slider-mark-active": this.mark.active } ]; }, stepClasses() { return [ "vue-slider-mark-step", { "vue-slider-mark-step-active": this.mark.active } ]; }, labelClasses() { return [ "vue-slider-mark-label", { "vue-slider-mark-label-active": this.mark.active } ]; } }, methods: { labelClickHandle(s) { s.stopPropagation(), this.$emit("pressLabel", this.mark.pos); } } }; function G(s, t, e, i, a, r) { return u(), f("div", { class: g(r.marksClasses) }, [ c(s.$slots, "step", {}, () => [ D("div", { class: g(r.stepClasses), style: p([ e.stepStyle, e.mark.style, e.mark.active ? e.stepActiveStyle : null, e.mark.active ? e.mark.activeStyle : null ]) }, null, 6) ]), e.hideLabel ? w("", !0) : c(s.$slots, "label", { key: 0 }, () => [ D("div", { class: g(r.labelClasses), style: p([ e.labelStyle, e.mark.labelStyle, e.mark.active ? e.labelActiveStyle : null, e.mark.active ? e.mark.labelActiveStyle : null ]), onClick: t[0] || (t[0] = (...n) => r.labelClickHandle && r.labelClickHandle(...n)) }, I(e.mark.label), 7) ]) ], 2); } const z = /* @__PURE__ */ B(X, [["render", G]]), k = (s) => typeof s == "number" ? `${s}px` : s, Z = (s) => { const t = document.documentElement, e = document.body, i = s.getBoundingClientRect(); return { y: i.top + (window.pageYOffset || t.scrollTop) - (t.clientTop || e.clientTop || 0), x: i.left + (window.pageXOffset || t.scrollLeft) - (t.clientLeft || e.clientLeft || 0) }; }, J = (s, t, e) => { const i = "targetTouches" in s ? s.targetTouches[0] : s, a = Z(t), r = { x: i.pageX - a.x, y: i.pageY - a.y }; return { x: e ? t.offsetWidth - r.x : r.x, y: e ? t.offsetHeight - r.y : r.y }; }, Q = (s, t) => { if (t.hook) { const e = t.hook(s); if (typeof e == "function") return e; if (!e) return null; } switch (s.keyCode) { case 38: return (e) => t.direction === "ttb" ? e - 1 : e + 1; case 39: return (e) => t.direction === "rtl" ? e - 1 : e + 1; case 40: return (e) => t.direction === "ttb" ? e + 1 : e - 1; case 37: return (e) => t.direction === "rtl" ? e + 1 : e - 1; case 35: return () => t.max; case 36: return () => t.min; case 33: return (e) => e + 10; case 34: return (e) => e - 10; default: return null; } }; class y { constructor(t) { l(this, "num"); this.num = t; } decimal(t, e) { const i = this.num, a = this.getDecimalLen(i), r = this.getDecimalLen(t); let n = 0; switch (e) { case "+": n = this.getExponent(a, r), this.num = (this.safeRoundUp(i, n) + this.safeRoundUp(t, n)) / n; break; case "-": n = this.getExponent(a, r), this.num = (this.safeRoundUp(i, n) - this.safeRoundUp(t, n)) / n; break; case "*": this.num = this.safeRoundUp( this.safeRoundUp(i, this.getExponent(a)), this.safeRoundUp(t, this.getExponent(r)) ) / this.getExponent(a + r); break; case "/": n = this.getExponent(a, r), this.num = this.safeRoundUp(i, n) / this.safeRoundUp(t, n); break; case "%": n = this.getExponent(a, r), this.num = this.safeRoundUp(i, n) % this.safeRoundUp(t, n) / n; break; } return this; } plus(t) { return this.decimal(t, "+"); } minus(t) { return this.decimal(t, "-"); } multiply(t) { return this.decimal(t, "*"); } divide(t) { return this.decimal(t, "/"); } remainder(t) { return this.decimal(t, "%"); } toNumber() { return this.num; } getDecimalLen(t) { const e = `${t}`.split("e"); return (`${e[0]}`.split(".")[1] || "").length - (e[1] ? +e[1] : 0); } getExponent(t, e) { return Math.pow(10, e !== void 0 ? Math.max(t, e) : t); } // fix: 9999999.99995 * 100000 = 999999999994.9999 safeRoundUp(t, e) { return Math.round(t * e); } } var Y = /* @__PURE__ */ ((s) => (s[s.VALUE = 1] = "VALUE", s[s.INTERVAL = 2] = "INTERVAL", s[s.MIN = 3] = "MIN", s[s.MAX = 4] = "MAX", s[s.ORDER = 5] = "ORDER", s))(Y || {}); const tt = { 1: 'The type of the "value" is illegal', 2: 'The prop "interval" is invalid, "(max - min)" must be divisible by "interval"', 3: 'The "value" must be greater than or equal to the "min".', 4: 'The "value" must be less than or equal to the "max".', 5: 'When "order" is false, the parameters "minRange", "maxRange", "fixed", "enabled" are invalid.' }; class et { constructor(t) { l(this, "dotsPos", []); // The position of each slider l(this, "dotsValue", []); // The value of each slider l(this, "data"); l(this, "enableCross"); l(this, "fixed"); l(this, "max"); l(this, "min"); l(this, "interval"); l(this, "minRange"); l(this, "maxRange"); l(this, "order"); l(this, "marks"); l(this, "included"); l(this, "process"); l(this, "adsorb"); l(this, "dotOptions"); l(this, "onError"); l(this, "cacheRangeDir", {}); this.data = t.data, this.max = t.max, this.min = t.min, this.interval = t.interval, this.order = t.order, this.marks = t.marks, this.included = t.included, this.process = t.process, this.adsorb = t.adsorb, this.dotOptions = t.dotOptions, this.onError = t.onError, this.order ? (this.minRange = t.minRange || 0, this.maxRange = t.maxRange || 0, this.enableCross = t.enableCross, this.fixed = t.fixed) : ((t.minRange || t.maxRange || !t.enableCross || t.fixed) && this.emitError( 5 /* ORDER */ ), this.minRange = 0, this.maxRange = 0, this.enableCross = !0, this.fixed = !1), this.setValue(t.value); } setValue(t) { this.setDotsValue( Array.isArray(t) ? this.order ? [...t].sort((e, i) => this.getIndexByValue(e) - this.getIndexByValue(i)) : [...t] : [t], !0 ); } setDotsValue(t, e) { this.dotsValue = t, e && this.syncDotsPos(); } // Set the slider position setDotsPos(t) { const e = this.order ? [...t].sort((i, a) => i - a) : t; this.dotsPos = e, this.setDotsValue( e.map((i) => this.getValueByPos(i)), this.adsorb ); } // Get value by position getValueByPos(t) { let e = this.parsePos(t); if (this.included) { let i = 100; this.markList.forEach((a) => { const r = Math.abs(a.pos - t); r < i && (i = r, e = a.value); }); } return e; } // Sync slider position syncDotsPos() { this.dotsPos = this.dotsValue.map((t) => this.parseValue(t)); } /** * Get all the marks * * @readonly * @type {Mark[]} * @memberof Control */ get markList() { if (!this.marks) return []; const t = (e, i) => { const a = this.parseValue(e); return { pos: a, value: e, label: e, active: this.isActiveByPos(a), ...i }; }; return this.marks === !0 ? this.getValues().map((e) => t(e)) : Object.prototype.toString.call(this.marks) === "[object Object]" ? Object.keys(this.marks).sort((e, i) => +e - +i).map((e) => { const i = this.marks[e]; return t(e, typeof i != "string" ? i : { label: i }); }) : Array.isArray(this.marks) ? this.marks.map((e) => t(e)) : typeof this.marks == "function" ? this.getValues().map((e) => ({ value: e, result: this.marks(e) })).filter(({ result: e }) => !!e).map(({ value: e, result: i }) => t(e, i)) : []; } /** * Get the most recent slider index by position * * @param {number} pos * @returns {number} * @memberof Control */ getRecentDot(t) { const e = this.dotsPos.filter((i, a) => !(this.getDotOption(a) && this.getDotOption(a).disabled)).map((i) => Math.abs(i - t)); return e.indexOf(Math.min(...e)); } /** * Get index by value * * @param {Value} value * @returns {number} * @memberof Control */ getIndexByValue(t) { return this.data ? this.data.indexOf(t) : new y(+t).minus(this.min).divide(this.interval).toNumber(); } /** * Get value by index * * @param {index} number * @returns {Value} * @memberof Control */ getValueByIndex(t) { return t < 0 ? t = 0 : t > this.total && (t = this.total), this.data ? this.data[t] : new y(t).multiply(this.interval).plus(this.min).toNumber(); } /** * Set the position of a single slider * * @param {number} pos * @param {number} index */ setDotPos(t, e) { t = this.getValidPos(t, e).pos; const i = t - this.dotsPos[e]; if (!i) return; let a = new Array(this.dotsPos.length); this.fixed ? a = this.getFixedChangePosArr(i, e) : this.minRange || this.maxRange ? a = this.getLimitRangeChangePosArr(t, i, e) : a[e] = i, this.setDotsPos(this.dotsPos.map((r, n) => r + (a[n] || 0))); } /** * In fixed mode, get the position of all slider changes * * @param {number} changePos Change distance of a single slider * @param {number} index slider index * @returns {DotsPosChangeArray} * @memberof Control */ getFixedChangePosArr(t, e) { return this.dotsPos.forEach((i, a) => { if (a !== e) { const { pos: r, inRange: n } = this.getValidPos(i + t, a); n || (t = Math.min(Math.abs(r - i), Math.abs(t)) * (t < 0 ? -1 : 1)); } }), this.dotsPos.map((i) => t); } /** * In minRange/maxRange mode, get the position of all slider changes * * @param {number} pos position of a single slider * @param {number} changePos Change distance of a single slider * @param {number} index slider index * @returns {DotsPosChangeArray} * @memberof Control */ getLimitRangeChangePosArr(t, e, i) { const a = [{ index: i, changePos: e }], r = e; return [this.minRange, this.maxRange].forEach((n, S) => { if (!n) return !1; const o = S === 0, h = e > 0; let b = 0; o ? b = h ? 1 : -1 : b = h ? -1 : 1; const H = (V, j) => { const E = Math.abs(V - j); return o ? E < this.minRangeDir : E > this.maxRangeDir; }; let v = i + b, x = this.dotsPos[v], C = t; for (; this.isPos(x) && H(x, C); ) { const { pos: V } = this.getValidPos(x + r, v); a.push({ index: v, changePos: V - x }), v = v + b, C = V, x = this.dotsPos[v]; } }), this.dotsPos.map((n, S) => { const o = a.filter((h) => h.index === S); return o.length ? o[0].changePos : 0; }); } isPos(t) { return typeof t == "number"; } /** * Get a valid position by pos * * @param {number} pos * @param {number} index * @returns {{ pos: number, inRange: boolean }} */ getValidPos(t, e) { const i = this.valuePosRange[e]; let a = !0; return t < i[0] ? (t = i[0], a = !1) : t > i[1] && (t = i[1], a = !1), { pos: t, inRange: a }; } /** * Calculate the position of the slider by value * * @param {Value} val * @returns {number} */ parseValue(t) { if (this.data) t = this.data.indexOf(t); else if (typeof t == "number" || typeof t == "string") { if (t = +t, t < this.min) return this.emitError( 3 /* MIN */ ), 0; if (t > this.max) return this.emitError( 4 /* MAX */ ), 0; if (typeof t != "number" || t !== t) return this.emitError( 1 /* VALUE */ ), 0; t = new y(t).minus(this.min).divide(this.interval).toNumber(); } const e = new y(t).multiply(this.gap).toNumber(); return e < 0 ? 0 : e > 100 ? 100 : e; } /** * Calculate the value by position * * @param {number} pos * @returns {Value} * @memberof Control */ parsePos(t) { const e = Math.round(t / this.gap); return this.getValueByIndex(e); } /** * Determine if the location is active * * @param {number} pos * @returns {boolean} * @memberof Control */ isActiveByPos(t) { return this.processArray.some(([e, i]) => t >= e && t <= i); } /** * Get each value * * @returns {Value[]} * @memberof Control */ getValues() { if (this.data) return this.data; { const t = []; for (let e = 0; e <= this.total; e++) t.push(new y(e).multiply(this.interval).plus(this.min).toNumber()); return t; } } /** * Calculate the distance of the range * @param range number */ getRangeDir(t) { return t ? new y(t).divide( new y(this.data ? this.data.length - 1 : this.max).minus(this.data ? 0 : this.min).toNumber() ).multiply(100).toNumber() : 100; } emitError(t) { this.onError && this.onError(t, tt[t]); } get processArray() { if (this.process) { if (typeof this.process == "function") return this.process(this.dotsPos); if (this.dotsPos.length === 1) return [[0, this.dotsPos[0]]]; if (this.dotsPos.length > 1) return [[Math.min(...this.dotsPos), Math.max(...this.dotsPos)]]; } return []; } /** * The total number of values * * @type {number} * @memberof Control */ get total() { let t = 0; return this.data ? t = this.data.length - 1 : t = new y(this.max).minus(this.min).divide(this.interval).toNumber(), t - Math.floor(t) !== 0 ? (this.emitError( 2 /* INTERVAL */ ), 0) : t; } // Distance between each value get gap() { return 100 / this.total; } // The minimum distance between the two sliders get minRangeDir() { return this.cacheRangeDir[this.minRange] ? this.cacheRangeDir[this.minRange] : this.cacheRangeDir[this.minRange] = this.getRangeDir(this.minRange); } // Maximum distance between the two sliders get maxRangeDir() { return this.cacheRangeDir[this.maxRange] ? this.cacheRangeDir[this.maxRange] : this.cacheRangeDir[this.maxRange] = this.getRangeDir(this.maxRange); } getDotOption(t) { return Array.isArray(this.dotOptions) ? this.dotOptions[t] : this.dotOptions; } getDotRange(t, e, i) { if (!this.dotOptions) return i; const a = this.getDotOption(t); return a && a[e] !== void 0 ? this.parseValue(a[e]) : i; } /** * Sliding range of each slider * * @type {Array<[number, number]>} * @memberof Control */ get valuePosRange() { const t = this.dotsPos, e = []; return t.forEach((i, a) => { e.push([ Math.max( this.minRange ? this.minRangeDir * a : 0, this.enableCross ? 0 : t[a - 1] || 0, this.getDotRange(a, "min", 0) ), Math.min( this.minRange ? 100 - this.minRangeDir * (t.length - 1 - a) : 100, this.enableCross ? 100 : t[a + 1] || 100, this.getDotRange(a, "max", 100) ) ]); }), e; } get dotsIndex() { return this.dotsValue.map((t) => this.getIndexByValue(t)); } } class st { constructor(t) { l(this, "map"); l(this, "states", 0); this.map = t; } add(t) { this.states |= t; } delete(t) { this.states &= ~t; } toggle(t) { this.has(t) ? this.delete(t) : this.add(t); } has(t) { return !!(this.states & t); } } const O = 4, d = { // StateMap None: 0, Drag: 2, Focus: 4 }, it = { emits: ["update:modelValue", "change", "drag-start", "drag-end", "dragging", "error"], components: { VueSliderDot: M, VueSliderMark: z }, props: { modelValue: { type: [Number, String, Array], default: 0 }, silent: { type: Boolean, default: !1 }, direction: { type: String, default: "ltr", validator: (s) => ["ltr", "rtl", "ttb", "btt"].indexOf(s) > -1 }, width: { type: [Number, String], default: void 0 }, height: { type: [Number, String], default: void 0 }, dotSize: { type: [Array, Number], // The size of the slider, optional [width, height] | size default: 14 }, contained: { type: Boolean, default: !1 }, min: { type: Number, default: 0 }, max: { type: Number, default: 100 }, interval: { type: Number, default: 1 }, disabled: { type: Boolean, default: !1 }, clickable: { type: Boolean, default: !0 }, dragOnClick: { type: Boolean, default: !0 }, duration: { type: Number, default: 0.5 }, data: { type: [Object, Array], // Value[] | object[] | DataObject default: void 0 }, dataValue: { type: String, default: "value" }, dataLabel: { type: String, default: "label" }, lazy: { type: Boolean, default: !1 }, tooltip: { type: String, default: "active", validator: (s) => ["none", "always", "focus", "hover", "active"].indexOf(s) > -1 }, tooltipPlacement: { type: [String, Array], default: void 0, validator: (s) => (Array.isArray(s) ? s : [s]).every( (t) => ["top", "right", "bottom", "left"].indexOf(t) > -1 ) }, tooltipFormatter: { type: [String, Array, Function], default: "" }, useKeyboard: { type: Boolean, default: !0 }, keydownHook: { type: [Boolean, Function], default: void 0 }, enableCross: { type: Boolean, default: !0 }, fixed: { type: Boolean, default: !1 }, order: { type: Boolean, default: !0 }, minRange: { type: Number, default: void 0 }, maxRange: { type: Number, default: void 0 }, marks: { type: [Boolean, Object, Array, Function], default: !1 }, process: { type: [Boolean, Function], default: !0 }, zoom: { type: [Number], default: void 0 }, included: { type: [Boolean], default: !1 }, adsorb: { type: [Boolean], default: !1 }, hideLabel: { type: [Boolean], default: !1 }, dotOptions: { type: Object, default: void 0 }, dotAttrs: { type: Object, default: void 0 }, railStyle: { type: Object, default: null }, processStyle: { type: Object, default: null }, dotStyle: { type: Object, default: null }, tooltipStyle: { type: Object, default: null }, stepStyle: { type: Object, default: null }, stepActiveStyle: { type: Object, default: null }, labelStyle: { type: Object, default: null }, labelActiveStyle: { type: Object, default: null } }, data() { return { control: null, // Control instance states: new st(d), scale: 1, focusDotIndex: 0 }; }, computed: { tailSize() { return k((this.isHorizontal ? this.height : this.width) || O); }, containerClasses() { return [ "vue-slider", [`vue-slider-${this.direction}`], { "vue-slider-disabled": this.disabled } ]; }, containerStyles() { const [s, t] = Array.isArray(this.dotSize) ? this.dotSize : [this.dotSize, this.dotSize], e = this.width ? k(this.width) : this.isHorizontal ? "auto" : k(O), i = this.height ? k(this.height) : this.isHorizontal ? k(O) : "auto"; return { padding: this.contained ? `${t / 2}px ${s / 2}px` : this.isHorizontal ? `${t / 2}px 0` : `0 ${s / 2}px`, width: e, height: i }; }, processArray() { return this.control.processArray.map(([s, t, e], i) => { s > t && ([s, t] = [t, s]); const a = this.isHorizontal ? "width" : "height"; return { start: s, end: t, index: i, style: { [this.isHorizontal ? "height" : "width"]: "100%", [this.isHorizontal ? "top" : "left"]: 0, [this.mainDirection]: `${s}%`, [a]: `${t - s}%`, transitionProperty: `${a},${this.mainDirection}`, transitionDuration: `${this.animateTime}s`, ...this.processStyle, ...e } }; }); }, dotBaseStyle() { const [s, t] = Array.isArray(this.dotSize) ? this.dotSize : [this.dotSize, this.dotSize]; let e; return this.isHorizontal ? e = { transform: `translate(${this.isReverse ? "50%" : "-50%"}, -50%)`, "-WebkitTransform": `translate(${this.isReverse ? "50%" : "-50%"}, -50%)`, top: "50%", [this.direction === "ltr" ? "left" : "right"]: "0" } : e = { transform: `translate(-50%, ${this.isReverse ? "50%" : "-50%"})`, "-WebkitTransform": `translate(-50%, ${this.isReverse ? "50%" : "-50%"})`, left: "50%", [this.direction === "btt" ? "bottom" : "top"]: "0" }, { width: `${s}px`, height: `${t}px`, ...e }; }, mainDirection() { switch (this.direction) { case "ltr": return "left"; case "rtl": return "right"; case "btt": return "bottom"; case "ttb": return "top"; } }, isHorizontal() { return this.direction === "ltr" || this.direction === "rtl"; }, isReverse() { return this.direction === "rtl" || this.direction === "btt"; }, tooltipDirections() { const s = this.tooltipPlacement || (this.isHorizontal ? "top" : "left"); return Array.isArray(s) ? s : this.dots.map(() => s); }, dots() { return this.control.dotsPos.map((s, t) => ({ pos: s, index: t, value: this.control.dotsValue[t], focus: this.states.has(d.Focus) && this.focusDotIndex === t, disabled: this.disabled, style: this.dotStyle, ...(Array.isArray(this.dotOptions) ? this.dotOptions[t] : this.dotOptions) || {} })); }, animateTime() { return this.states.has(d.Drag) ? 0 : this.duration; }, canSort() { return this.order && !this.minRange && !this.maxRange && !this.fixed && this.enableCross; }, sliderData() { return this.isObjectArrayData(this.data) ? this.data.map((s) => s[this.dataValue]) : this.isObjectData(this.data) ? Object.keys(this.data) : this.data; }, sliderMarks() { if (this.marks) return this.marks; if (this.isObjectArrayData(this.data)) return (s) => { const t = { label: s }; return this.data.some((e) => e[this.dataValue] === s ? (t.label = e[this.dataLabel], !0) : !1), t; }; if (this.isObjectData(this.data)) return this.data; }, sliderTooltipFormatter() { if (this.tooltipFormatter) return this.tooltipFormatter; if (this.isObjectArrayData(this.data)) return (s) => { let t = "" + s; return this.data.some((e) => e[this.dataValue] === s ? (t = e[this.dataLabel], !0) : !1), t; }; if (this.isObjectData(this.data)) { const s = this.data; return (t) => s[t]; } }, // Slider value and component internal value are inconsistent isNotSync() { const s = this.control.dotsValue; return Array.isArray(this.modelValue) ? this.modelValue.length !== s.length || this.modelValue.some((t, e) => t !== s[e]) : this.modelValue !== s[0]; }, /** * Get the drag range of the slider * * @private * @param {number} index slider index * @returns {[number, number]} range [start, end] * @memberof VueSlider */ dragRange() { const s = this.dots[this.focusDotIndex - 1], t = this.dots[this.focusDotIndex + 1]; return [s ? s.pos : -1 / 0, t ? t.pos : 1 / 0]; } }, created() { this.initControl(); }, mounted() { this.bindEvent(); }, beforeUnmount() { this.unbindEvent(); }, methods: { isObjectData(s) { return !!s && Object.prototype.toString.call(s) === "[object Object]"; }, isObjectArrayData(s) { return !!s && Array.isArray(s) && s.length > 0 && typeof s[0] == "object"; }, bindEvent() { document.addEventListener("touchmove", this.dragMove, { passive: !1 }), document.addEventListener("touchend", this.dragEnd, { passive: !1 }), document.addEventListener("mousedown", this.blurHandle), document.addEventListener("mousemove", this.dragMove, { passive: !1 }), document.addEventListener("mouseup", this.dragEnd), document.addEventListener("mouseleave", this.dragEnd), document.addEventListener("keydown", this.keydownHandle); }, unbindEvent() { document.removeEventListener("touchmove", this.dragMove), document.removeEventListener("touchend", this.dragEnd), document.removeEventListener("mousedown", this.blurHandle), document.removeEventListener("mousemove", this.dragMove), document.removeEventListener("mouseup", this.dragEnd), document.removeEventListener("mouseleave", this.dragEnd), document.removeEventListener("keydown", this.keydownHandle); }, setScale() { const s = new y( Math.floor(this.isHorizontal ? this.$refs.rail.offsetWidth : this.$refs.rail.offsetHeight) ); this.zoom !== void 0 && s.multiply(this.zoom), s.divide(100), this.scale = s.toNumber(); }, initControl() { this.control = new et({ value: this.modelValue, data: this.sliderData, enableCross: this.enableCross, fixed: this.fixed, max: this.max, min: this.min, interval: this.interval, minRange: this.minRange, maxRange: this.maxRange, order: this.order, marks: this.sliderMarks, included: this.included, process: this.process, adsorb: this.adsorb, dotOptions: this.dotOptions, onError: this.emitError }), this.syncValueByPos(), [ "data", "enableCross", "fixed", "max", "min", "interval", "minRange", "maxRange", "order", "marks", "process", "adsorb", "included", "dotOptions" ].forEach((s) => { this.$watch(s, (t) => { if (s === "data" && Array.isArray(this.control.data) && Array.isArray(t) && this.control.data.length === t.length && t.every((e, i) => e === this.control.data[i])) return !1; switch (s) { case "data": case "dataLabel": case "dataValue": this.control.data = this.sliderData; break; case "mark": this.control.marks = this.sliderMarks; break; default: this.control[s] = t; } ["data", "max", "min", "interval"].indexOf(s) > -1 && this.control.syncDotsPos(); }); }); }, syncValueByPos() { const s = this.control.dotsValue; if (this.isDiff(s, Array.isArray(this.modelValue) ? this.modelValue : [this.modelValue])) { const t = s.length === 1 ? s[0] : [...s]; this.$emit("change", t, this.focusDotIndex), this.$emit("update:modelValue", t, this.focusDotIndex); } }, isDiff(s, t) { return s.length !== t.length || s.some((e, i) => e !== t[i]); }, emitError(s, t) { this.silent || console.error(`[VueSlider error]: ${t}`), this.$emit("error", s, t); }, dragStartOnProcess(s) { if (this.dragOnClick) { this.setScale(); const t = this.getPosByEvent(s), e = this.control.getRecentDot(t); if (this.dots[e].disabled) return; this.dragStart(e), this.control.setDotPos(t, this.focusDotIndex), this.lazy || this.syncValueByPos(); } }, dragStart(s) { this.focusDotIndex = s, this.setScale(), this.states.add(d.Drag), this.states.add(d.Focus), this.$emit("drag-start", this.focusDotIndex); }, dragMove(s) { if (!this.states.has(d.Drag)) return !1; s.preventDefault(); const t = this.getPosByEvent(s); this.isCrossDot(t), this.control.setDotPos(t, this.focusDotIndex), this.lazy || this.syncValueByPos(); const e = this.control.dotsValue; this.$emit("dragging", e.length === 1 ? e[0] : [...e], this.focusDotIndex); }, // If the component is sorted, then when the slider crosses, toggle the currently selected slider index isCrossDot(s) { if (this.canSort) { const t = this.focusDotIndex; let e = s; if (e > this.dragRange[1] ? (e = this.dragRange[1], this.focusDotIndex++) : e < this.dragRange[0] && (e = this.dragRange[0], this.focusDotIndex--), t !== this.focusDotIndex) { const i = this.$refs[`dot-${this.focusDotIndex}`]; i && i.$el && i.$el.focus(), this.control.setDotPos(e, t); } } }, dragEnd(s) { if (!this.states.has(d.Drag)) return !1; setTimeout(() => { this.lazy && this.syncValueByPos(), this.included && this.isNotSync ? this.control.setValue(this.modelValue) : this.control.syncDotsPos(), this.states.delete(d.Drag), (!this.useKeyboard || "targetTouches" in s) && this.states.delete(d.Focus), this.$emit("drag-end", this.focusDotIndex); }); }, blurHandle(s) { if (!this.states.has(d.Focus) || !this.$refs.container || this.$refs.container.contains(s.target)) return !1; this.states.delete(d.Focus); }, clickHandle(s) { if (!this.clickable || this.disabled) return !1; if (this.states.has(d.Drag)) return; this.setScale(); const t = this.getPosByEvent(s); this.setValueByPos(t); }, focus(s = 0) { this.states.add(d.Focus), this.focusDotIndex = s; }, blur() { this.states.delete(d.Focus); }, getValue() { const s = this.control.dotsValue; return s.length === 1 ? s[0] : s; }, getIndex() { const s = this.control.dotsIndex; return s.length === 1 ? s[0] : s; }, setValue(s) { this.control.setValue(Array.isArray(s) ? [...s] : [s]), this.syncValueByPos(); }, setIndex(s) { const t = Array.isArray(s) ? s.map((e) => this.control.getValueByIndex(e)) : this.control.getValueByIndex(s); this.setValue(t); }, setValueByPos(s) { const t = this.control.getRecentDot(s); if (this.disabled || this.dots[t].disabled) return !1; this.focusDotIndex = t, this.control.setDotPos(s, t), this.syncValueByPos(), this.useKeyboard && this.states.add(d.Focus), setTimeout(() => { this.included && this.isNotSync ? this.control.setValue(this.modelValue) : this.control.syncDotsPos(); }); }, keydownHandle(s) { if (!this.useKeyboard || !this.states.has(d.Focus)) return !1; const t = this.included && this.marks, e = Q(s, { direction: this.direction, max: t ? this.control.markList.length - 1 : this.control.total, min: 0, hook: this.keydownHook }); if (e) { s.preventDefault(); let i = -1, a = 0; t ? (this.control.markList.some((r, n) => r.value === this.control.dotsValue[this.focusDotIndex] ? (i = e(n), !0) : !1), i < 0 ? i = 0 : i > this.control.markList.length - 1 && (i = this.control.markList.length - 1), a = this.control.markList[i].pos) : (i = e( this.control.getIndexByValue(this.control.dotsValue[this.focusDotIndex]) ), a = this.control.parseValue(this.control.getValueByIndex(i))), this.isCrossDot(a), this.control.setDotPos(a, this.focusDotIndex), this.syncValueByPos(); } }, getPosByEvent(s) { return J(s, this.$refs.rail, this.isReverse)[this.isHorizontal ? "x" : "y"] / this.scale; } }, watch: { modelValue: { handler() { this.control && !this.states.has(d.Drag) && this.isNotSync && (this.control.setValue(this.modelValue), this.syncValueByPos()); }, deep: !0 } } }, rt = { key: 0, class: "vue-slider-marks" }; function at(s, t, e, i, a, r) { const n = L("VueSliderMark"), S = L("VueSliderDot"); return u(), f("div", m({ ref: "container", class: r.containerClasses, style: r.containerStyles, onClick: t[1] || (t[1] = (...o) => r.clickHandle && r.clickHandle(...o)), onTouchstartPassive: t[2] || (t[2] = (...o) => r.dragStartOnProcess && r.dragStartOnProcess(...o)), onMousedown: t[3] || (t[3] = (...o) => r.dragStartOnProcess && r.dragStartOnProcess(...o)) }, s.$attrs), [ D("div", { ref: "rail", class: "vue-slider-rail", style: p(e.railStyle) }, [ (u(!0), f(P, null, R(r.processArray, (o, h) => c(s.$slots, "process", m({ ref_for: !0 }, { ...o }), () => [ (u(), f("div", { class: "vue-slider-process", key: `process-${h}`, style: p(o.style) }, null, 4)) ])), 256)), r.sliderMarks ? (u(), f("div", rt, [ (u(!0), f(P, null, R(a.control.markList, (o, h) => c(s.$slots, "mark", m({ ref_for: !0 }, { ...o }), () => [ (u(), U(n, { key: `mark-${h}`, mark: o, hideLabel: e.hideLabel, style: p({ [r.isHorizontal ? "height" : "width"]: "100%", [r.isHorizontal ? "width" : "height"]: r.tailSize, [r.mainDirection]: `${o.pos}%` }), stepStyle: e.stepStyle, stepActiveStyle: e.stepActiveStyle, labelStyle: e.labelStyle, labelActiveStyle: e.labelActiveStyle, onPressLabel: (b) => e.clickable && r.setValueByPos(b) }, { step: A(() => [ c(s.$slots, "step", m({ ref_for: !0 }, { ...o })) ]), label: A(() => [ c(s.$slots, "label", m({ ref_for: !0 }, { ...o })) ]), _: 2 }, 1032, ["mark", "hideLabel", "style", "stepStyle", "stepActiveStyle", "labelStyle", "labelActiveStyle", "onPressLabel"])) ])), 256)) ])) : w("", !0), (u(!0), f(P, null, R(r.dots, (o, h) => (u(), f(P, null, [ _(S, m({ ref_for: !0, ref: `dot-${h}`, value: o.value, disabled: o.disabled, focus: o.focus, "dot-style": [ o.style, o.disabled ? o.disabledStyle : null, o.focus ? o.focusStyle : null ], tooltip: o.tooltip || e.tooltip, "tooltip-style": [ e.tooltipStyle, o.tooltipStyle, o.disabled ? o.tooltipDisabledStyle : null, o.focus ? o.tooltipFocusStyle : null ], "tooltip-formatter": Array.isArray(r.sliderTooltipFormatter) ? r.sliderTooltipFormatter[h] : r.sliderTooltipFormatter, "tooltip-placement": r.tooltipDirections[h], style: [ r.dotBaseStyle, { [r.mainDirection]: `${o.pos}%`, transition: `${r.mainDirection} ${r.animateTime}s` } ], "onDrag-start": () => r.dragStart(h), role: "slider", "aria-valuenow": o.value, "aria-valuemin": this.min, "aria-valuemax": this.max, "aria-orientation": this.isHorizontal ? "horizontal" : "vertical", tabindex: "0", onFocus: () => !o.disabled && r.focus(h), onBlur: t[0] || (t[0] = () => r.blur()) }, { ...e.dotAttrs }), { dot: A(() => [ c(s.$slots, "dot", m({ ref_for: !0 }, { ...o })) ]), tooltip: A(() => [ c(s.$slots, "tooltip", m({ ref_for: !0 }, { ...o })) ]), _: 2 }, 1040, ["value", "disabled", "focus", "dot-style", "tooltip", "tooltip-style", "tooltip-formatter", "tooltip-placement", "style", "onDrag-start", "aria-valuenow", "aria-valuemin", "aria-valuemax", "aria-orientation", "onFocus"]), c(s.$slots, "default", m({ ref_for: !0 }, { value: r.getValue() })) ], 64))), 256)) ], 4) ], 16); } const F = /* @__PURE__ */ B(it, [["render", at]]); F.VueSliderMark = z; F.VueSliderDot = M; export { Y as ERROR_TYPE, M as VueSliderDot, z as VueSliderMark, F as default };