UNPKG

@oruga-ui/oruga-next

Version:

UI components for Vue.js and CSS framework agnostic

536 lines (535 loc) 21.9 kB
"use strict"; /*! Oruga v0.11.0 | MIT License | github.com/oruga-ui/oruga */ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); const vue = require("vue"); const Tooltip_vue_vue_type_script_setup_true_lang = require("./Tooltip.vue_vue_type_script_setup_true_lang-BTZz3kR-.cjs"); const config = require("./config-eYBvpFOZ.cjs"); const fieldInjection = require("./fieldInjection-aGL6GpMR.cjs"); const defineClasses = require("./defineClasses-Cqhbv-UT.cjs"); const useParentProvider = require("./useParentProvider-CPNahRzD.cjs"); const helpers = require("./helpers.cjs"); const _hoisted_1 = ["tabindex", "aria-label", "aria-labelledby", "aria-valuenow", "aria-valuemin", "aria-valuemax", "aria-disabled", "onKeydown"]; const _hoisted_2 = { key: 0 }; const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({ ...{ isOruga: true, name: "OSliderThumb", configField: "slider", inheritAttrs: false }, __name: "SliderThumb", props: { sliderProps: {}, modelValue: {}, sliderSize: { type: Function }, thumbWrapperClasses: {}, thumbClasses: {} }, emits: ["update:model-value", "change", "dragstart", "dragend"], setup(__props, { expose: __expose, emit: __emit }) { const props = __props; const emits = __emit; const { parentField } = fieldInjection.injectField(); const isFocused = vue.ref(false); const dragging = vue.ref(false); const startX = vue.ref(0); const startPosition = vue.ref(0); const newPosition = vue.ref(); const oldValue = vue.ref(props.modelValue); const tooltip = vue.computed(() => props.sliderProps.tooltip); const tooltipAlways = vue.computed(() => props.sliderProps.tooltipAlways); const disabled = vue.computed(() => props.sliderProps.disabled); const max = vue.computed(() => props.sliderProps.max); const min = vue.computed(() => props.sliderProps.min); const step = vue.computed(() => props.sliderProps.step); const indicator = vue.computed(() => props.sliderProps.indicator); const ariaLabel = vue.computed(() => props.sliderProps.ariaLabel); const precision = vue.computed(() => { const precisions = [min.value, max.value, step.value].map((item) => { const decimal = ("" + item).split(".")[1]; return decimal ? decimal.length : 0; }); return Math.max(...precisions); }); const computedTooltipVariant = vue.computed( () => props.sliderProps.tooltipVariant ? props.sliderProps.tooltipVariant : props.sliderProps.variant ); const currentPosition = vue.computed( () => `${(props.modelValue - min.value) / (max.value - min.value) * 100}%` ); const wrapperStyle = vue.computed(() => ({ left: currentPosition.value })); const formattedValue = vue.computed(() => { if (typeof props.sliderProps.formatter !== "undefined") return props.sliderProps.formatter(props.modelValue); if (props.sliderProps.format === "percent") return new Intl.NumberFormat(props.sliderProps.locale, { style: "percent" }).format((props.modelValue - min.value) / (max.value - min.value)); return new Intl.NumberFormat(props.sliderProps.locale).format( props.modelValue ); }); function onFocus() { isFocused.value = true; } function onBlur() { isFocused.value = false; } function onButtonDown(event) { if (disabled.value) return; event.preventDefault(); onDragStart(event); if (config.isClient) { document.addEventListener("mousemove", onDragging); document.addEventListener("touchmove", onDragging); document.addEventListener("mouseup", onDragEnd); document.addEventListener("touchend", onDragEnd); document.addEventListener("contextmenu", onDragEnd); } } function onLeftKeyDown() { if (disabled.value || props.modelValue === min.value) return; newPosition.value = parseFloat(currentPosition.value) - step.value / (max.value - min.value) * 100; setPosition(newPosition.value); emits("change"); } function onRightKeyDown() { if (disabled.value || props.modelValue === max.value) return; newPosition.value = parseFloat(currentPosition.value) + step.value / (max.value - min.value) * 100; setPosition(newPosition.value); emits("change"); } function onHomeKeyDown() { if (disabled.value || props.modelValue === min.value) return; newPosition.value = 0; setPosition(newPosition.value); emits("change"); } function onEndKeyDown() { if (disabled.value || props.modelValue === max.value) return; newPosition.value = 100; setPosition(newPosition.value); emits("change"); } function onDragStart(event) { dragging.value = true; emits("dragstart"); if (event.type === "touchstart") event.clientX = event.touches[0].clientX; startX.value = event.clientX; startPosition.value = parseFloat(currentPosition.value); newPosition.value = startPosition.value; } function onDragging(event) { if (dragging.value) { if (event.type === "touchmove") event.clientX = event.touches[0].clientX; const diff = (event.clientX - startX.value) / props.sliderSize() * 100; newPosition.value = startPosition.value + diff; setPosition(newPosition.value); } } function onDragEnd() { dragging.value = false; emits("dragend"); if (props.modelValue !== oldValue.value) emits("change"); setPosition(newPosition.value); if (config.isClient) { document.removeEventListener("mousemove", onDragging); document.removeEventListener("touchmove", onDragging); document.removeEventListener("mouseup", onDragEnd); document.removeEventListener("touchend", onDragEnd); document.removeEventListener("contextmenu", onDragEnd); } } function setPosition(percent) { if (percent === void 0 || isNaN(percent)) return; if (percent < 0) percent = 0; else if (percent > 100) percent = 100; const stepLength = 100 / ((max.value - min.value) / step.value); const steps = Math.round(percent / stepLength); let value = steps * stepLength / 100 * (max.value - min.value) + min.value; value = parseFloat(value.toFixed(precision.value)); emits("update:model-value", value); if (!dragging.value && value !== oldValue.value) oldValue.value = value; } __expose({ setPosition }); return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock("div", { "data-oruga": "slider-thumb", class: vue.normalizeClass(_ctx.thumbWrapperClasses), style: vue.normalizeStyle(wrapperStyle.value) }, [ vue.createVNode(Tooltip_vue_vue_type_script_setup_true_lang._sfc_main, { label: formattedValue.value, variant: computedTooltipVariant.value, disabled: disabled.value || !tooltip.value, always: tooltipAlways.value || dragging.value || isFocused.value }, { default: vue.withCtx(() => { var _a; return [ vue.createElementVNode("div", vue.mergeProps(_ctx.$attrs, { class: _ctx.thumbClasses, tabindex: disabled.value ? void 0 : 0, role: "slider", "aria-label": ariaLabel.value, "aria-labelledby": (_a = vue.unref(parentField)) == null ? void 0 : _a.labelId, "aria-valuenow": _ctx.modelValue, "aria-valuemin": min.value, "aria-valuemax": max.value, "aria-disabled": disabled.value, "aria-orientation": "horizontal", onMousedown: onButtonDown, onTouchstartPassive: onButtonDown, onFocus, onBlur, onKeydown: [ vue.withKeys(vue.withModifiers(onLeftKeyDown, ["prevent"]), ["left"]), vue.withKeys(vue.withModifiers(onRightKeyDown, ["prevent"]), ["right"]), vue.withKeys(vue.withModifiers(onLeftKeyDown, ["prevent"]), ["down"]), vue.withKeys(vue.withModifiers(onRightKeyDown, ["prevent"]), ["up"]), vue.withKeys(vue.withModifiers(onHomeKeyDown, ["prevent"]), ["home"]), vue.withKeys(vue.withModifiers(onEndKeyDown, ["prevent"]), ["end"]) ] }), [ indicator.value ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_2, vue.toDisplayString(formattedValue.value), 1)) : vue.createCommentVNode("", true) ], 16, _hoisted_1) ]; }), _: 1 }, 8, ["label", "variant", "disabled", "always"]) ], 6); }; } }); const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({ ...{ isOruga: true, name: "OSliderTick", configField: "slider" }, __name: "SliderTick", props: { /** Override existing theme classes completely */ override: { type: Boolean, default: void 0 }, /** Value of single tick */ value: { type: Number, required: true }, /** Tick label */ label: { type: [String, Number], default: void 0 }, tickClass: { type: [String, Function, Array], default: void 0 }, /** Class when slider tick is hidden */ tickHiddenClass: { type: [String, Function, Array], default: void 0 }, /** Class of tick label */ tickLabelClass: { type: [String, Function, Array], default: void 0 } }, setup(__props) { const props = __props; const { parent } = useParentProvider.useProviderChild({ register: false }); const position = vue.computed(() => { const pos = (props.value - parent.value.min) / (parent.value.max - parent.value.min) * 100; return pos >= 0 && pos <= 100 ? pos : 0; }); const hidden = vue.computed( () => props.value === parent.value.min || props.value === parent.value.max ); const tickStyle = vue.computed(() => ({ left: position.value + "%" })); const rootClasses = defineClasses.defineClasses( ["tickClass", "o-slider__tick"], ["tickHiddenClass", "o-slider__tick--hidden", null, hidden] ); const tickLabelClasses = defineClasses.defineClasses([ "tickLabelClass", "o-slider__tick-label" ]); return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock("div", { "data-oruga": "slider-tick", class: vue.normalizeClass(vue.unref(rootClasses)), style: vue.normalizeStyle(tickStyle.value) }, [ _ctx.$slots.default || __props.label ? (vue.openBlock(), vue.createElementBlock("span", { key: 0, class: vue.normalizeClass(vue.unref(tickLabelClasses)) }, [ vue.renderSlot(_ctx.$slots, "default", {}, () => [ vue.createTextVNode(vue.toDisplayString(__props.label), 1) ]) ], 2)) : vue.createCommentVNode("", true) ], 6); }; } }); const _sfc_main = /* @__PURE__ */ vue.defineComponent({ ...{ isOruga: true, name: "OSlider", configField: "slider" }, __name: "Slider", props: { override: { type: Boolean, default: void 0 }, modelValue: { default: void 0 }, range: {}, min: { default: 0 }, max: { default: 100 }, step: { default: 1 }, variant: { default: () => config.getDefault("slider.variant") }, size: { default: () => config.getDefault("slider.size") }, ticks: { type: Boolean, default: false }, tooltip: { type: Boolean, default: () => config.getDefault("slider.tooltip", true) }, tooltipVariant: { default: () => config.getDefault("slider.tooltipVariant") }, tooltipAlways: { type: Boolean, default: false }, rounded: { type: Boolean, default: () => config.getDefault("slider.rounded", false) }, disabled: { type: Boolean, default: false }, lazy: { type: Boolean, default: false }, formatter: { type: Function, default: void 0 }, biggerSliderFocus: { type: Boolean, default: false }, indicator: { type: Boolean, default: false }, format: { default: () => config.getDefault("slider.format", "raw") }, locale: { default: () => config.getDefault("locale") }, ariaLabel: { default: () => config.getDefault("slider.ariaLabel") }, rootClass: {}, sizeClass: {}, disabledClass: {}, trackClass: {}, fillClass: {}, variantClass: {}, thumbWrapperClass: {}, thumbWrapperDraggingClass: {}, thumbClass: {}, thumbRoundedClass: {}, thumbDraggingClass: {}, tickClass: {}, tickHiddenClass: {}, tickLabelClass: {} }, emits: ["update:model-value", "change", "dragging", "dragstart", "dragend"], setup(__props, { expose: __expose, emit: __emit }) { const props = __props; const emits = __emit; const sliderRef = vue.useTemplateRef("sliderElement"); const thumbStartRef = vue.useTemplateRef("thumbStartComponent"); const thumbEndRef = vue.useTemplateRef("thumbEndComponent"); const provideData = vue.computed(() => ({ max: props.max, min: props.min })); useParentProvider.useProviderParent({ data: provideData }); const valueStart = vue.ref(0); const valueEnd = vue.ref(0); const dragging = vue.ref(false); const isThumbReversed = vue.ref(); const isTrackClickDisabled = vue.ref(); const minValue = vue.computed( () => Math.min(valueStart.value || props.min, valueEnd.value || props.max) ); const maxValue = vue.computed( () => Math.max(valueStart.value || props.min, valueEnd.value || props.max) ); const isRange = vue.computed(() => helpers.isTrueish(props.range)); const vmodel = vue.computed( () => isRange.value ? [minValue.value, maxValue.value] : valueStart.value || 0 ); vue.watch([valueStart, valueEnd], () => { if (isRange.value) isThumbReversed.value = valueStart.value && valueEnd.value ? valueStart.value > valueEnd.value : false; if (!props.lazy || !dragging.value) emits("update:model-value", vmodel.value); if (dragging.value) emits("dragging", vmodel.value); }); vue.watch( [() => props.min, () => props.max, () => props.modelValue], () => setValues(props.modelValue), { immediate: true } // initialise valueStart and valueEnd ); function setValues(newValue) { if (props.min > props.max) return; if (Array.isArray(newValue)) { const smallValue = typeof newValue[0] !== "number" || isNaN(newValue[0]) ? props.min : Math.min(Math.max(props.min, newValue[0]), props.max); const largeValue = typeof newValue[1] !== "number" || isNaN(newValue[1]) ? props.max : Math.max(Math.min(props.max, newValue[1]), props.min); valueStart.value = isThumbReversed.value ? largeValue : smallValue; valueEnd.value = isThumbReversed.value ? smallValue : largeValue; } else if (newValue !== void 0) { valueStart.value = isNaN(newValue) ? props.min : Math.min(props.max, Math.max(props.min, newValue)); valueEnd.value = 0; } else { valueStart.value = props.min; valueEnd.value = props.min; } } const tickValues = vue.computed(() => { if (!props.ticks || props.min > props.max || props.step === 0) return []; const result = []; for (let i = props.min + props.step; i < props.max; i = i + props.step) { result.push(i); } return result; }); const barSize = vue.computed( () => isRange.value ? `${100 * (maxValue.value - minValue.value) / (props.max - props.min)}%` : `${100 * (valueStart.value - props.min) / (props.max - props.min)}%` ); const barStart = vue.computed( () => isRange.value ? `${100 * (minValue.value - props.min) / (props.max - props.min)}%` : "0%" ); const barStyle = vue.computed(() => ({ width: barSize.value, left: barStart.value })); function getSliderSize() { var _a; return ((_a = sliderRef.value) == null ? void 0 : _a.getBoundingClientRect().width) || 0; } function onSliderClick(event) { if (props.disabled || isTrackClickDisabled.value) return; if (!sliderRef.value || !thumbStartRef.value || isRange.value && !thumbEndRef.value) return; const sliderOffsetLeft = sliderRef.value.getBoundingClientRect().left; const percent = (event.clientX - sliderOffsetLeft) / getSliderSize() * 100; const targetValue = props.min + percent * (props.max - props.min) / 100; const diffFirst = Math.abs(targetValue - valueStart.value); if (!isRange.value) { if (diffFirst < props.step / 2) return; thumbStartRef.value.setPosition(percent); } else { const diffSecond = Math.abs(targetValue - valueEnd.value); if (diffFirst <= diffSecond) { if (diffFirst < props.step / 2) return; thumbStartRef.value.setPosition(percent); } else { if (diffSecond < props.step / 2) return; if (isRange.value && thumbEndRef.value) thumbEndRef.value.setPosition(percent); } } emits("change", vmodel.value); } function onDragStart() { dragging.value = true; emits("dragstart"); } function onDragEnd() { isTrackClickDisabled.value = true; setTimeout(() => isTrackClickDisabled.value = false); dragging.value = false; emits("dragend"); if (props.lazy) emits("update:model-value", vmodel.value); } const rootClasses = defineClasses.defineClasses( ["rootClass", "o-slider"], [ "sizeClass", "o-slider--", vue.computed(() => props.size), vue.computed(() => !!props.size) ], [ "disabledClass", "o-slider--disabled", null, vue.computed(() => props.disabled) ] ); const trackClasses = defineClasses.defineClasses(["trackClass", "o-slider__track"]); const fillClasses = defineClasses.defineClasses( ["fillClass", "o-slider__fill"], [ "variantClass", "o-slider__fill--", vue.computed(() => props.variant), vue.computed(() => !!props.variant) ] ); const thumbWrapperClasses = defineClasses.defineClasses( ["thumbWrapperClass", "o-slider__thumb-wrapper"], [ "thumbWrapperDraggingClass", "o-slider__thumb-wrapper--dragging", null, dragging ] ); const thumbClasses = defineClasses.defineClasses( ["thumbClass", "o-slider__thumb"], ["thumbDraggingClass", "o-slider__thumb--dragging", null, dragging], [ "thumbRoundedClass", "o-slider__thumb--rounded", null, vue.computed(() => props.rounded) ] ); __expose({ value: vmodel }); return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock("div", { "data-oruga": "slider", class: vue.normalizeClass(vue.unref(rootClasses)), onClick: onSliderClick }, [ vue.createElementVNode("div", { ref: "sliderElement", class: vue.normalizeClass(vue.unref(trackClasses)) }, [ vue.createElementVNode("div", { class: vue.normalizeClass(vue.unref(fillClasses)), style: vue.normalizeStyle(barStyle.value) }, null, 6), _ctx.ticks ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 0 }, vue.renderList(tickValues.value, (val, key) => { return vue.openBlock(), vue.createBlock(_sfc_main$1, { key, value: val, "tick-class": _ctx.tickClass, "tick-hidden-class": _ctx.tickHiddenClass, "tick-label-class": _ctx.tickLabelClass }, null, 8, ["value", "tick-class", "tick-hidden-class", "tick-label-class"]); }), 128)) : vue.createCommentVNode("", true), vue.renderSlot(_ctx.$slots, "default"), vue.createVNode(_sfc_main$2, { ref: "thumbStartComponent", modelValue: valueStart.value, "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => valueStart.value = $event), "slider-props": props, "slider-size": getSliderSize, "thumb-classes": vue.unref(thumbClasses), "thumb-wrapper-classes": vue.unref(thumbWrapperClasses), onChange: _cache[1] || (_cache[1] = ($event) => emits("change", vmodel.value)), onDragstart: onDragStart, onDragend: onDragEnd }, null, 8, ["modelValue", "thumb-classes", "thumb-wrapper-classes"]), isRange.value ? (vue.openBlock(), vue.createBlock(_sfc_main$2, { key: 1, ref: "thumbEndComponent", modelValue: valueEnd.value, "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => valueEnd.value = $event), "slider-props": props, "slider-size": getSliderSize, "thumb-classes": vue.unref(thumbClasses), "thumb-wrapper-classes": vue.unref(thumbWrapperClasses), onChange: _cache[3] || (_cache[3] = ($event) => emits("change", vmodel.value)), onDragstart: onDragStart, onDragend: onDragEnd }, null, 8, ["modelValue", "thumb-classes", "thumb-wrapper-classes"])) : vue.createCommentVNode("", true) ], 2) ], 2); }; } }); const index = { install(app) { config.registerComponent(app, _sfc_main); config.registerComponent(app, _sfc_main$1); } }; exports.OSlider = _sfc_main; exports.OSliderTick = _sfc_main$1; exports.default = index; //# sourceMappingURL=slider.cjs.map