UNPKG

maz-ui

Version:

A standalone components library for Vue.Js 3 & Nuxt.Js 3

206 lines (205 loc) 10.5 kB
import { defineComponent, ref, computed, watch, onMounted, onBeforeUnmount, nextTick, createElementBlock, openBlock, normalizeClass, normalizeStyle, createElementVNode, Fragment, renderList, toDisplayString } from "vue"; import { d as debounce } from "../chunks/debounce.Brzkn9pm.js"; import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper.B--vMWp3.js"; import '../assets/MazSlider.WcnBC9zc.css';function getOffset(elem) { const doc = document.documentElement, body = document.body, rect = elem.getBoundingClientRect(); return { y: rect.top + (window.pageYOffset || doc.scrollTop) - (doc.clientTop || body.clientTop || 0), x: rect.left + (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || body.clientLeft || 0) }; } function getPos(e, elem, isReverse = !1) { const event = "targetTouches" in e ? e.targetTouches[0] : e, offset = getOffset(elem), posObj = { x: event.pageX - offset.x, y: event.pageY - offset.y }; return { x: isReverse ? elem.offsetWidth - posObj.x : posObj.x, y: isReverse ? elem.offsetHeight - posObj.y : posObj.y }; } function isBetween(value, prev, next, direction) { return direction === "minus" ? prev ? value >= prev : !0 : next ? value <= next : !0; } function getOpacityCoeff(index, middle, length) { const currentIndex = index + 1, deviation = middle < currentIndex ? currentIndex - middle : middle - currentIndex; return 100 / length * deviation / 100; } const _hoisted_1 = ["aria-valuenow", "aria-valuemin", "aria-valuemax"], _hoisted_2 = ["data-label", "onMousedownPassive", "onTouchstartPassive", "onFocusPassive", "onBlurPassive", "onTouchendPassive", "onKeydownPassive"], _sfc_main = /* @__PURE__ */ defineComponent({ __name: "MazSlider", props: { modelValue: {}, labels: {}, min: { default: 0 }, max: { default: 100 }, step: { default: 1 }, size: {}, divider: { type: Boolean, default: !0 }, log: { type: Boolean, default: !1 }, color: { default: "primary" }, cursorAnim: { type: Boolean, default: !0 } }, emits: ["update:model-value"], setup(__props, { emit: __emit }) { const emits = __emit, MazSlider2 = ref(), activeCursor = ref(), buttonPositions = ref(), tmpValues = ref(), buttonStyles = ref([]), dividers = ref([]), computedValue = computed(() => typeof __props.modelValue == "number" ? [__props.modelValue] : __props.modelValue ? __props.modelValue : [0]), minLog = computed(() => Math.log(__props.min || 1)), maxLog = computed(() => Math.log(__props.max)), scale = computed(() => (maxLog.value - minLog.value) / (__props.max - __props.min)), range = computed(() => __props.max - __props.min), wrapperStyle = computed(() => ({ paddingTop: __props.labels ? "2.5em" : "1em" })), hasMultipleValues = computed(() => Array.isArray(__props.modelValue)); watch( () => __props.modelValue, () => tmpValues.value = computedValue.value, { immediate: !0 } ), watch( () => [computedValue.value, __props.min, __props.max, __props.log].join(","), () => buildComponent(!0) ); const resizeListenerFunction = debounce(() => buildComponent(), 300); onMounted(() => { buildComponent(!0), window.addEventListener("resize", resizeListenerFunction); }), onBeforeUnmount(() => { window.removeEventListener("resize", resizeListenerFunction); }); async function buildComponent(emitValue2) { emitValue2 === !0 && checkValues(), await calcPos(), await nextTick(); for (const [index] of computedValue.value.entries()) setBtnDividers(index); } function roundToStep(value) { return Math.round((value - __props.min) / __props.step) * __props.step + __props.min; } function cursorKeyDown(event, i) { event.key === "ArrowLeft" ? tmpValues.value && isBetween(tmpValues.value[i] - __props.step, tmpValues.value[i - 1], tmpValues.value[i + 1], "minus") && (tmpValues.value[i] = Math.max(__props.min, tmpValues.value[i] - __props.step), emitValue(tmpValues.value)) : event.key === "ArrowRight" && tmpValues.value && isBetween(tmpValues.value[i] + __props.step, tmpValues.value[i - 1], tmpValues.value[i + 1], "plus") && (tmpValues.value[i] = Math.min(__props.max, tmpValues.value[i] + __props.step), emitValue(tmpValues.value)); } function blurCursor(i) { activeCursor.value = void 0, setBtnStyle(i); } function checkValues() { const valuesChecked = computedValue.value.map((v) => { const checkedValue = v < __props.min ? __props.min : v > __props.max ? __props.max : v; return roundToStep(checkedValue); }); emitValue(valuesChecked), tmpValues.value = valuesChecked; } function emitValue(values) { const valueToEmit = hasMultipleValues.value ? [...values] : values[0]; emits("update:model-value", valueToEmit); } function getLabel(i) { return __props.labels ? __props.labels[i] : void 0; } function setBtnDividers(i) { setBtnStyle(i), __props.divider && setDividers(); } async function setBtnStyle(i) { await nextTick(); const currentCursor = document.querySelectorAll(".m-slider .m-slider__btn"); if (currentCursor) { const width = currentCursor[i]?.clientWidth + 16, btnStyle = { left: typeof buttonPositions.value?.[i] == "number" ? `${buttonPositions.value[i] - width / 2 || 1}px` : "" }; buttonStyles.value[i] = btnStyle; } } function setDividers() { if (buttonPositions.value) { const base = [...buttonPositions.value]; base.push(0); const baseLength = base.length, middle = Math.round(baseLength / 2); dividers.value = base.map((pos, i) => ({ left: i === 0 ? 0 : `${base[i - 1]}px`, // ATTENTION: buttonPositions.value[i - 1] right: i + 1 === baseLength ? 0 : `calc( 100% - ${pos}px )`, backgroundColor: middle === i + 1 ? void 0 : i < middle ? `rgba(255, 255, 255, ${getOpacityCoeff(i, middle, baseLength)})` : `rgba(0, 0, 0, ${getOpacityCoeff(i, middle, baseLength)})` // darken })); } } async function calcPos() { await nextTick(); const barWidth = MazSlider2.value?.clientWidth; typeof barWidth == "number" ? buttonPositions.value = tmpValues.value?.map( (v) => __props.log ? barWidth / __props.max * (__props.min + (Math.log(v) - minLog.value) / scale.value) : barWidth / range.value * (v - __props.min) ) : console.warn("[maz-ui][MazSlider] ref component not found"); } async function getCursorsValues() { await nextTick(); const barWidth = MazSlider2.value?.clientWidth; if (typeof barWidth == "number") return __props.log ? buttonPositions.value?.map((pos) => { const position = pos / (barWidth / __props.max), value = Math.exp((position - __props.min) * scale.value + minLog.value); return roundToStep(Math.round(value)); }) : buttonPositions.value?.map( (pos) => roundToStep(Math.round(pos / (barWidth / range.value)) + __props.min) ); console.warn("[maz-ui][MazSlider] ref component not found"); } function handleMousedown(_event, i) { activeCursor.value === void 0 && (activeCursor.value = i, setBtnDividers(i)); } async function handleMouseup() { if (activeCursor.value === void 0) return; const values = await getCursorsValues(); values && emitValue(values), activeCursor.value = void 0; } async function handleMousemove(event) { if (await nextTick(), activeCursor.value === void 0) return; const barWidth = MazSlider2.value?.clientWidth; if (buttonPositions.value) { const prevValue = buttonPositions.value[activeCursor.value - 1] || 0, nextValue = buttonPositions.value[activeCursor.value + 1] || barWidth; if (!MazSlider2.value) return console.error("[maz-ui](MazSlider/handleMousemove) MazSlider not available"); buttonPositions.value[activeCursor.value] = (() => { const movement = getPos(event, MazSlider2.value).x; return movement < prevValue ? prevValue : nextValue && movement > nextValue ? nextValue : movement; })(), tmpValues.value = await getCursorsValues(), setBtnDividers(activeCursor.value); } } return (_ctx, _cache) => (openBlock(), createElementBlock("div", { style: normalizeStyle([wrapperStyle.value, { fontSize: __props.size }]), class: normalizeClass(["m-slider m-reset-css", [`m-slider--${__props.color}`]]), role: "button", tabindex: "-1", onMousemovePassive: handleMousemove, onMouseupPassive: handleMouseup, onMouseleavePassive: handleMouseup, onTouchmovePassive: handleMousemove }, [ createElementVNode("div", { ref_key: "MazSlider", ref: MazSlider2, class: "m-slider__bar", role: "slider", "aria-valuenow": __props.modelValue?.toString(), "aria-valuemin": __props.min, "aria-valuemax": __props.max }, [ (openBlock(!0), createElementBlock(Fragment, null, renderList(dividers.value, (div, i) => (openBlock(), createElementBlock("div", { key: `divider-${i}`, style: normalizeStyle([div]), class: "m-slider__divider" }, null, 4))), 128)), (openBlock(!0), createElementBlock(Fragment, null, renderList(computedValue.value, (_btn, i) => (openBlock(), createElementBlock("button", { key: `cursor-${i}`, type: "button", "data-label": getLabel(i), class: normalizeClass(["m-slider__btn", { "active-cursor": i === activeCursor.value && __props.cursorAnim }]), style: normalizeStyle([buttonStyles.value[i]]), onMousedownPassive: ($event) => handleMousedown($event, i), onTouchstartPassive: ($event) => handleMousedown($event, i), onFocusPassive: ($event) => handleMousedown($event, i), onBlurPassive: ($event) => blurCursor(i), onTouchendPassive: ($event) => blurCursor(i), onKeydownPassive: ($event) => cursorKeyDown($event, i) }, [ createElementVNode("span", null, toDisplayString(tmpValues.value?.[i]), 1) ], 46, _hoisted_2))), 128)) ], 8, _hoisted_1) ], 38)); } }), MazSlider = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-8cc966c7"]]); export { MazSlider as default };