UNPKG

vue-cesium

Version:
536 lines (531 loc) 18.2 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); require('../../../directives/index.js'); var useDark = require('../../../composables/private/use-dark.js'); var useForm = require('../../../composables/private/use-form.js'); var format = require('../../../utils/private/format.js'); var event = require('../../../utils/private/event.js'); var util = require('../../../utils/util.js'); var render = require('../../../utils/private/render.js'); var shared = require('@vue/shared'); var index = require('../../../directives/touch-pan/index.js'); "use strict"; const markerPrefixClass = "vc-slider__marker-labels"; const defaultMarkerConvertFn = (v) => ({ value: v }); const defaultMarkerLabelRenderFn = ({ marker }) => vue.h( "div", { key: marker.value, style: marker.style, class: marker.classes }, marker.label ); const keyCodes = [34, 37, 40, 33, 39, 38]; const useSliderProps = { ...useDark.useDarkProps, ...useForm.useFormProps, min: { type: Number, default: 0 }, max: { type: Number, default: 100 }, innerMin: Number, innerMax: Number, step: { type: Number, default: 1, validator: (v) => v >= 0 }, snap: Boolean, vertical: Boolean, reverse: Boolean, hideSelection: Boolean, color: String, markerLabelsClass: String, label: Boolean, labelColor: String, labelTextColor: String, labelAlways: Boolean, switchLabelSide: Boolean, markers: [Boolean, Number], markerLabels: [Boolean, Array, Object, Function], switchMarkerLabelsSide: Boolean, trackImg: String, trackColor: String, innerTrackImg: String, innerTrackColor: String, selectionColor: String, selectionImg: String, thumbSize: { type: String, default: "20px" }, trackSize: { type: String, default: "4px" }, disable: Boolean, readonly: Boolean, dense: Boolean, tabindex: [String, Number], thumbColor: String, thumbPath: { type: String, default: "M 4, 10 a 6,6 0 1,0 12,0 a 6,6 0 1,0 -12,0" } }; const useSliderEmits = ["pan", "update:modelValue", "change"]; function useSlider({ updateValue, updatePosition, getDragging, formAttrs }) { const { props, emit, slots, proxy } = vue.getCurrentInstance(); const isDark = useDark["default"](props); const injectFormInput = useForm.useFormInject(formAttrs); const active = vue.ref(false); const preventFocus = vue.ref(false); const focus = vue.ref(false); const dragging = vue.ref(false); const axis = vue.computed(() => props.vertical === true ? "--v" : "--h"); const labelSide = vue.computed(() => "-" + (props.switchLabelSide === true ? "switched" : "standard")); const isReversed = vue.computed(() => props.reverse === true); const innerMin = vue.computed(() => isNaN(props.innerMin) === true || props.innerMin < props.min ? props.min : props.innerMin); const innerMax = vue.computed(() => isNaN(props.innerMax) === true || props.innerMax > props.max ? props.max : props.innerMax); const editable = vue.computed(() => props.disable !== true && props.readonly !== true && innerMin.value < innerMax.value); const decimals = vue.computed(() => (String(props.step).trim().split(".")[1] || "").length); const step = vue.computed(() => props.step === 0 ? 1 : props.step); const tabindex = vue.computed(() => editable.value === true ? props.tabindex || 0 : -1); const trackLen = vue.computed(() => props.max - props.min); const innerBarLen = vue.computed(() => innerMax.value - innerMin.value); const innerMinRatio = vue.computed(() => convertModelToRatio(innerMin.value)); const innerMaxRatio = vue.computed(() => convertModelToRatio(innerMax.value)); const positionProp = vue.computed( () => props.vertical === true ? isReversed.value === true ? "bottom" : "top" : isReversed.value === true ? "right" : "left" ); const sizeProp = vue.computed(() => props.vertical === true ? "height" : "width"); const thicknessProp = vue.computed(() => props.vertical === true ? "width" : "height"); const orientation = vue.computed(() => props.vertical === true ? "vertical" : "horizontal"); const attributes = vue.computed(() => { const acc = { role: "slider", "aria-valuemin": innerMin.value, "aria-valuemax": innerMax.value, "aria-orientation": orientation.value, "data-step": props.step }; if (props.disable === true) { acc["aria-disabled"] = "true"; } else if (props.readonly === true) { acc["aria-readonly"] = "true"; } return acc; }); const classes = vue.computed( () => `vc-slider vc-slider${axis.value} vc-slider--${active.value === true ? "" : "in"}active inline no-wrap ` + (props.vertical === true ? "row" : "column") + (props.disable === true ? " disabled" : " vc-slider--enabled" + (editable.value === true ? " vc-slider--editable" : "")) + (focus.value === "both" ? " vc-slider--focus" : "") + (props.label || props.labelAlways === true ? " vc-slider--label" : "") + (props.labelAlways === true ? " vc-slider--label-always" : "") + (isDark.value === true ? " vc-slider--dark" : "") + (props.dense === true ? " vc-slider--dense vc-slider--dense" + axis.value : "") ); function getPositionClass(name) { const cls = "vc-slider__" + name; return `${cls} ${cls}${axis.value} ${cls}${axis.value}${labelSide.value}`; } function getAxisClass(name) { const cls = "vc-slider__" + name; return `${cls} ${cls}${axis.value}`; } const selectionBarClass = vue.computed(() => { const color = props.selectionColor || props.color; return "vc-slider__selection absolute" + (color !== void 0 ? ` text-${color}` : ""); }); const markerClass = vue.computed(() => getAxisClass("markers") + " absolute overflow-hidden"); const trackContainerClass = vue.computed(() => getAxisClass("track-container")); const pinClass = vue.computed(() => getPositionClass("pin")); const labelClass = vue.computed(() => getPositionClass("label")); const textContainerClass = vue.computed(() => getPositionClass("text-container")); const markerLabelsContainerClass = vue.computed( () => getPositionClass("marker-labels-container") + (props.markerLabelsClass !== void 0 ? ` ${props.markerLabelsClass}` : "") ); const trackClass = vue.computed(() => "vc-slider__track relative-position no-outline" + (props.trackColor !== void 0 ? ` bg-${props.trackColor}` : "")); const trackStyle = vue.computed(() => { const acc = { [thicknessProp.value]: props.trackSize }; if (props.trackImg !== void 0) { acc.backgroundImage = `url(${props.trackImg}) !important`; } return acc; }); const innerBarClass = vue.computed(() => "vc-slider__inner absolute" + (props.innerTrackColor !== void 0 ? ` bg-${props.innerTrackColor}` : "")); const innerBarStyle = vue.computed(() => { const acc = { [positionProp.value]: `${100 * innerMinRatio.value}%`, [sizeProp.value]: `${100 * (innerMaxRatio.value - innerMinRatio.value)}%` }; if (props.innerTrackImg !== void 0) { acc.backgroundImage = `url(${props.innerTrackImg}) !important`; } return acc; }); function convertRatioToModel(ratio) { const { min, max, step: step2 } = props; let model = min + ratio * (max - min); if (step2 > 0) { const modulo = (model - min) % step2; model += (Math.abs(modulo) >= step2 / 2 ? (modulo < 0 ? -1 : 1) * step2 : 0) - modulo; } if (decimals.value > 0) { model = parseFloat(model.toFixed(decimals.value)); } return format.between(model, innerMin.value, innerMax.value); } function convertModelToRatio(model) { return trackLen.value === 0 ? 0 : (model - props.min) / trackLen.value; } function getDraggingRatio(evt, dragging2) { const pos = event.position(evt), val = props.vertical === true ? format.between((pos.top - dragging2.top) / dragging2.height, 0, 1) : format.between((pos.left - dragging2.left) / dragging2.width, 0, 1); return format.between(isReversed.value === true ? 1 - val : val, innerMinRatio.value, innerMaxRatio.value); } const markerStep = vue.computed(() => util.isNumber(props.markers) === true ? props.markers : step.value); const markerTicks = vue.computed(() => { const acc = []; const step2 = markerStep.value; const max = props.max; let value = props.min; do { acc.push(value); value += step2; } while (value < max); acc.push(max); return acc; }); const markerLabelClass = vue.computed(() => { const prefix = ` ${markerPrefixClass}${axis.value}-`; return markerPrefixClass + `${prefix}${props.switchMarkerLabelsSide === true ? "switched" : "standard"}${prefix}${isReversed.value === true ? "rtl" : "ltr"}`; }); const markerLabelsList = vue.computed(() => { if (props.markerLabels === false) { return null; } return getMarkerList(props.markerLabels).map((entry, index) => ({ index, value: entry.value, label: entry.label || entry.value, classes: markerLabelClass.value + (entry.classes !== void 0 ? " " + entry.classes : ""), style: { ...getMarkerLabelStyle(entry.value), ...entry.style || {} } })); }); const markerScope = vue.computed(() => ({ markerList: markerLabelsList.value, markerMap: markerLabelsMap.value, classes: markerLabelClass.value, // TODO ts definition getStyle: getMarkerLabelStyle })); const markerStyle = vue.computed(() => { if (innerBarLen.value !== 0) { const size = 100 * markerStep.value / innerBarLen.value; return { ...innerBarStyle.value, backgroundSize: props.vertical === true ? `2px ${size}%` : `${size}% 2px` }; } return null; }); function getMarkerList(def) { if (def === false) { return null; } if (def === true) { return markerTicks.value.map(defaultMarkerConvertFn); } if (typeof def === "function") { return markerTicks.value.map((value) => { const item = def(value); return shared.isObject(item) === true ? { ...item, value } : { value, label: item }; }); } const filterFn = ({ value }) => value >= props.min && value <= props.max; if (Array.isArray(def) === true) { return def.map((item) => shared.isObject(item) === true ? item : { value: item }).filter(filterFn); } return Object.keys(def).map((key) => { const item = def[key]; const value = Number(key); return shared.isObject(item) === true ? { ...item, value } : { value, label: item }; }).filter(filterFn); } function getMarkerLabelStyle(val) { return { [positionProp.value]: `${100 * (val - props.min) / trackLen.value}%` }; } const markerLabelsMap = vue.computed(() => { if (props.markerLabels === false) { return null; } const acc = {}; markerLabelsList.value.forEach((entry) => { acc[entry.value] = entry; }); return acc; }); function getMarkerLabelsContent() { if (slots["marker-label-group"] !== void 0) { return slots["marker-label-group"](markerScope.value); } const fn = slots["marker-label"] || defaultMarkerLabelRenderFn; return markerLabelsList.value.map( (marker) => fn({ marker, ...markerScope.value }) ); } const panDirective = vue.computed(() => { return [ [ index["default"], onPan, void 0, { [orientation.value]: true, prevent: true, stop: true, mouse: true, mouseAllDir: true } ] ]; }); function onPan(event) { if (event.isFinal === true) { if (dragging.value !== void 0) { updatePosition(event.evt); event.touch === true && updateValue(true); dragging.value = void 0; emit("pan", "end"); } active.value = false; focus.value = false; } else if (event.isFirst === true) { dragging.value = getDragging(event.evt); updatePosition(event.evt); updateValue(); active.value = true; emit("pan", "start"); } else { updatePosition(event.evt); updateValue(); } } function onBlur() { focus.value = false; } function onActivate(evt) { updatePosition(evt, getDragging(evt)); updateValue(); preventFocus.value = true; active.value = true; document.addEventListener("mouseup", onDeactivate, true); } function onDeactivate() { preventFocus.value = false; active.value = false; updateValue(true); onBlur(); document.removeEventListener("mouseup", onDeactivate, true); } function onMobileClick(evt) { updatePosition(evt, getDragging(evt)); updateValue(true); } function onKeyup(evt) { if (keyCodes.includes(evt.keyCode)) { updateValue(true); } } function getTextContainerStyle(ratio) { if (props.vertical === true) { return null; } const p = ratio; return { transform: `translateX(calc(${2 * p - 1} * ${props.thumbSize} / 2 + ${50 - 100 * p}%))` }; } function getThumbRenderFn(thumb) { const focusClass = vue.computed( () => preventFocus.value === false && (focus.value === thumb.focusValue || focus.value === "both") ? " vc-slider--focus" : "" ); const classes2 = vue.computed( () => `vc-slider__thumb vc-slider__thumb${axis.value} vc-slider__thumb${axis.value}-${isReversed.value === true ? "rtl" : "ltr"} absolute non-selectable` + focusClass.value + (thumb.thumbColor.value !== void 0 ? ` text-${thumb.thumbColor.value}` : "") ); const style = vue.computed(() => ({ width: props.thumbSize, height: props.thumbSize, [positionProp.value]: `${100 * thumb.ratio.value}%`, zIndex: focus.value === thumb.focusValue ? 2 : void 0 })); const pinColor = vue.computed(() => thumb.labelColor.value !== void 0 ? ` text-${thumb.labelColor.value}` : ""); const textContainerStyle = vue.computed(() => getTextContainerStyle(thumb.ratio.value)); const textClass = vue.computed(() => "vc-slider__text" + (thumb.labelTextColor.value !== void 0 ? ` text-${thumb.labelTextColor.value}` : "")); return () => { const thumbContent = [ vue.h( "svg", { class: "vc-slider__thumb-shape absolute-full", viewBox: "0 0 20 20", "aria-hidden": "true" }, [vue.h("path", { d: props.thumbPath })] ), vue.h("div", { class: "vc-slider__focus-ring fit" }) ]; if (props.label === true || props.labelAlways === true) { thumbContent.push( vue.h( "div", { class: pinClass.value + " absolute fit no-pointer-events" + pinColor.value }, [ vue.h( "div", { class: labelClass.value, style: { minWidth: props.thumbSize } }, [ vue.h( "div", { class: textContainerClass.value, style: textContainerStyle.value }, [vue.h("span", { class: textClass.value }, thumb.label.value)] ) ] ) ] ) ); if (props.name !== void 0 && props.disable !== true) { injectFormInput(thumbContent, "push"); } } return vue.h( "div", { class: classes2.value, style: style.value, ...thumb.getNodeData() }, thumbContent ); }; } function getContent(selectionBarStyle, trackContainerTabindex, trackContainerEvents, injectThumb) { const trackContent = []; props.innerTrackColor !== "transparent" && trackContent.push( vue.h("div", { key: "inner", class: innerBarClass.value, style: innerBarStyle.value }) ); props.selectionColor !== "transparent" && trackContent.push( vue.h("div", { key: "selection", class: selectionBarClass.value, style: selectionBarStyle.value }) ); props.markers !== false && trackContent.push( vue.h("div", { key: "marker", class: markerClass.value, style: markerStyle.value }) ); injectThumb(trackContent); const content = [ render.hDir( "div", { key: "trackC", class: trackContainerClass.value, tabindex: trackContainerTabindex.value, ...trackContainerEvents.value }, [ vue.h( "div", { class: trackClass.value, style: trackStyle.value }, trackContent ) ], "slide", editable.value, () => panDirective.value ) ]; if (props.markerLabels !== false) { const action = props.switchMarkerLabelsSide === true ? "unshift" : "push"; content[action]( vue.h( "div", { key: "markerL", class: markerLabelsContainerClass.value }, getMarkerLabelsContent() ) ); } return content; } vue.onBeforeUnmount(() => { document.removeEventListener("mouseup", onDeactivate, true); }); return { state: { active, focus, preventFocus, dragging, editable, classes, tabindex, attributes, step, decimals, trackLen, innerMin, innerMinRatio, innerMax, innerMaxRatio, positionProp, sizeProp, isReversed }, methods: { onActivate, onMobileClick, onBlur, onKeyup, getContent, getThumbRenderFn, convertRatioToModel, convertModelToRatio, getDraggingRatio } }; } exports["default"] = useSlider; exports.keyCodes = keyCodes; exports.useSliderEmits = useSliderEmits; exports.useSliderProps = useSliderProps; //# sourceMappingURL=use-slider.js.map