UNPKG

@aplus-frontend/antdv

Version:

Vue basic component library maintained based on ant-design-vue

594 lines (593 loc) 18.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _vue = require("vue"); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classNames = _interopRequireDefault(require("../../_util/classNames")); var _vueTypes = _interopRequireWildcard(require("../../_util/vue-types")); var _BaseMixin = _interopRequireDefault(require("../../_util/BaseMixin")); var _propsUtil = require("../../_util/props-util"); var _Track = _interopRequireDefault(require("./common/Track")); var _createSlider = _interopRequireDefault(require("./common/createSlider")); var utils = _interopRequireWildcard(require("./utils")); var _initDefaultProps = _interopRequireDefault(require("../../_util/props-util/initDefaultProps")); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } const trimAlignValue = _ref => { let { value, handle, bounds, props } = _ref; const { allowCross, pushable } = props; const thershold = Number(pushable); const valInRange = utils.ensureValueInRange(value, props); let valNotConflict = valInRange; if (!allowCross && handle != null && bounds !== undefined) { if (handle > 0 && valInRange <= bounds[handle - 1] + thershold) { valNotConflict = bounds[handle - 1] + thershold; } if (handle < bounds.length - 1 && valInRange >= bounds[handle + 1] - thershold) { valNotConflict = bounds[handle + 1] - thershold; } } return utils.ensureValuePrecision(valNotConflict, props); }; const rangeProps = { defaultValue: _vueTypes.default.arrayOf(_vueTypes.default.number), value: _vueTypes.default.arrayOf(_vueTypes.default.number), count: Number, pushable: (0, _vueTypes.withUndefined)(_vueTypes.default.oneOfType([_vueTypes.default.looseBool, _vueTypes.default.number])), allowCross: { type: Boolean, default: undefined }, disabled: { type: Boolean, default: undefined }, reverse: { type: Boolean, default: undefined }, tabindex: _vueTypes.default.arrayOf(_vueTypes.default.number), prefixCls: String, min: Number, max: Number, autofocus: { type: Boolean, default: undefined }, ariaLabelGroupForHandles: Array, ariaLabelledByGroupForHandles: Array, ariaValueTextFormatterGroupForHandles: Array, draggableTrack: { type: Boolean, default: undefined } }; const Range = (0, _vue.defineComponent)({ compatConfig: { MODE: 3 }, name: 'Range', mixins: [_BaseMixin.default], inheritAttrs: false, props: (0, _initDefaultProps.default)(rangeProps, { count: 1, allowCross: true, pushable: false, tabindex: [], draggableTrack: false, ariaLabelGroupForHandles: [], ariaLabelledByGroupForHandles: [], ariaValueTextFormatterGroupForHandles: [] }), emits: ['beforeChange', 'afterChange', 'change'], displayName: 'Range', data() { const { count, min, max } = this; const initialValue = Array(...Array(count + 1)).map(() => min); const defaultValue = (0, _propsUtil.hasProp)(this, 'defaultValue') ? this.defaultValue : initialValue; let { value } = this; if (value === undefined) { value = defaultValue; } const bounds = value.map((v, i) => trimAlignValue({ value: v, handle: i, props: this.$props })); const recent = bounds[0] === max ? 0 : bounds.length - 1; return { sHandle: null, recent, bounds }; }, watch: { value: { handler(val) { const { bounds } = this; this.setChangeValue(val || bounds); }, deep: true }, min() { const { value } = this; this.setChangeValue(value || this.bounds); }, max() { const { value } = this; this.setChangeValue(value || this.bounds); } }, methods: { setChangeValue(value) { const { bounds } = this; let nextBounds = value.map((v, i) => trimAlignValue({ value: v, handle: i, bounds, props: this.$props })); if (bounds.length === nextBounds.length) { if (nextBounds.every((v, i) => v === bounds[i])) { return null; } } else { nextBounds = value.map((v, i) => trimAlignValue({ value: v, handle: i, props: this.$props })); } this.setState({ bounds: nextBounds }); if (value.some(v => utils.isValueOutOfRange(v, this.$props))) { const newValues = value.map(v => { return utils.ensureValueInRange(v, this.$props); }); this.$emit('change', newValues); } }, onChange(state) { const isNotControlled = !(0, _propsUtil.hasProp)(this, 'value'); if (isNotControlled) { this.setState(state); } else { const controlledState = {}; ['sHandle', 'recent'].forEach(item => { if (state[item] !== undefined) { controlledState[item] = state[item]; } }); if (Object.keys(controlledState).length) { this.setState(controlledState); } } const data = (0, _extends2.default)((0, _extends2.default)({}, this.$data), state); const changedValue = data.bounds; this.$emit('change', changedValue); }, positionGetValue(position) { const bounds = this.getValue(); const value = this.calcValueByPos(position); const closestBound = this.getClosestBound(value); const index = this.getBoundNeedMoving(value, closestBound); const prevValue = bounds[index]; if (value === prevValue) return null; const nextBounds = [...bounds]; nextBounds[index] = value; return nextBounds; }, onStart(position) { const { bounds } = this; this.$emit('beforeChange', bounds); const value = this.calcValueByPos(position); this.startValue = value; this.startPosition = position; const closestBound = this.getClosestBound(value); this.prevMovedHandleIndex = this.getBoundNeedMoving(value, closestBound); this.setState({ sHandle: this.prevMovedHandleIndex, recent: this.prevMovedHandleIndex }); const prevValue = bounds[this.prevMovedHandleIndex]; if (value === prevValue) return; const nextBounds = [...bounds]; nextBounds[this.prevMovedHandleIndex] = value; this.onChange({ bounds: nextBounds }); }, onEnd(force) { const { sHandle } = this; this.removeDocumentEvents(); if (!sHandle) { this.dragTrack = false; } if (sHandle !== null || force) { this.$emit('afterChange', this.bounds); } this.setState({ sHandle: null }); }, onMove(e, position, dragTrack, startBounds) { utils.pauseEvent(e); const { $data: state, $props: props } = this; const maxValue = props.max || 100; const minValue = props.min || 0; if (dragTrack) { let pos = props.vertical ? -position : position; pos = props.reverse ? -pos : pos; const max = maxValue - Math.max(...startBounds); const min = minValue - Math.min(...startBounds); const ratio = Math.min(Math.max(pos / (this.getSliderLength() / 100), min), max); const nextBounds = startBounds.map(v => Math.floor(Math.max(Math.min(v + ratio, maxValue), minValue))); if (state.bounds.map((c, i) => c === nextBounds[i]).some(c => !c)) { this.onChange({ bounds: nextBounds }); } return; } const { bounds, sHandle } = this; const value = this.calcValueByPos(position); const oldValue = bounds[sHandle]; if (value === oldValue) return; this.moveTo(value); }, onKeyboard(e) { const { reverse, vertical } = this.$props; const valueMutator = utils.getKeyboardValueMutator(e, vertical, reverse); if (valueMutator) { utils.pauseEvent(e); const { bounds, sHandle } = this; const oldValue = bounds[sHandle === null ? this.recent : sHandle]; const mutatedValue = valueMutator(oldValue, this.$props); const value = trimAlignValue({ value: mutatedValue, handle: sHandle, bounds, props: this.$props }); if (value === oldValue) return; const isFromKeyboardEvent = true; this.moveTo(value, isFromKeyboardEvent); } }, getClosestBound(value) { const { bounds } = this; let closestBound = 0; for (let i = 1; i < bounds.length - 1; i += 1) { if (value >= bounds[i]) { closestBound = i; } } if (Math.abs(bounds[closestBound + 1] - value) < Math.abs(bounds[closestBound] - value)) { closestBound += 1; } return closestBound; }, getBoundNeedMoving(value, closestBound) { const { bounds, recent } = this; let boundNeedMoving = closestBound; const isAtTheSamePoint = bounds[closestBound + 1] === bounds[closestBound]; if (isAtTheSamePoint && bounds[recent] === bounds[closestBound]) { boundNeedMoving = recent; } if (isAtTheSamePoint && value !== bounds[closestBound + 1]) { boundNeedMoving = value < bounds[closestBound + 1] ? closestBound : closestBound + 1; } return boundNeedMoving; }, getLowerBound() { return this.bounds[0]; }, getUpperBound() { const { bounds } = this; return bounds[bounds.length - 1]; }, /** * Returns an array of possible slider points, taking into account both * `marks` and `step`. The result is cached. */ getPoints() { const { marks, step, min, max } = this; const cache = this.internalPointsCache; if (!cache || cache.marks !== marks || cache.step !== step) { const pointsObject = (0, _extends2.default)({}, marks); if (step !== null) { for (let point = min; point <= max; point += step) { pointsObject[point] = point; } } const points = Object.keys(pointsObject).map(parseFloat); points.sort((a, b) => a - b); this.internalPointsCache = { marks, step, points }; } return this.internalPointsCache.points; }, moveTo(value, isFromKeyboardEvent) { const nextBounds = [...this.bounds]; const { sHandle, recent } = this; const handle = sHandle === null ? recent : sHandle; nextBounds[handle] = value; let nextHandle = handle; if (this.$props.pushable !== false) { this.pushSurroundingHandles(nextBounds, nextHandle); } else if (this.$props.allowCross) { nextBounds.sort((a, b) => a - b); nextHandle = nextBounds.indexOf(value); } this.onChange({ recent: nextHandle, sHandle: nextHandle, bounds: nextBounds }); if (isFromKeyboardEvent) { // known problem: because setState is async, // so trigger focus will invoke handler's onEnd and another handler's onStart too early, // cause onBeforeChange and onAfterChange receive wrong value. // here use setState callback to hack,but not elegant this.$emit('afterChange', nextBounds); this.setState({}, () => { this.handlesRefs[nextHandle].focus(); }); this.onEnd(); } }, pushSurroundingHandles(bounds, handle) { const value = bounds[handle]; const { pushable } = this; const threshold = Number(pushable); let direction = 0; if (bounds[handle + 1] - value < threshold) { direction = +1; // push to right } if (value - bounds[handle - 1] < threshold) { direction = -1; // push to left } if (direction === 0) { return; } const nextHandle = handle + direction; const diffToNext = direction * (bounds[nextHandle] - value); if (!this.pushHandle(bounds, nextHandle, direction, threshold - diffToNext)) { // revert to original value if pushing is impossible bounds[handle] = bounds[nextHandle] - direction * threshold; } }, pushHandle(bounds, handle, direction, amount) { const originalValue = bounds[handle]; let currentValue = bounds[handle]; while (direction * (currentValue - originalValue) < amount) { if (!this.pushHandleOnePoint(bounds, handle, direction)) { // can't push handle enough to create the needed `amount` gap, so we // revert its position to the original value bounds[handle] = originalValue; return false; } currentValue = bounds[handle]; } // the handle was pushed enough to create the needed `amount` gap return true; }, pushHandleOnePoint(bounds, handle, direction) { const points = this.getPoints(); const pointIndex = points.indexOf(bounds[handle]); const nextPointIndex = pointIndex + direction; if (nextPointIndex >= points.length || nextPointIndex < 0) { // reached the minimum or maximum available point, can't push anymore return false; } const nextHandle = handle + direction; const nextValue = points[nextPointIndex]; const { pushable } = this; const threshold = Number(pushable); const diffToNext = direction * (bounds[nextHandle] - nextValue); if (!this.pushHandle(bounds, nextHandle, direction, threshold - diffToNext)) { // couldn't push next handle, so we won't push this one either return false; } // push the handle bounds[handle] = nextValue; return true; }, trimAlignValue(value) { const { sHandle, bounds } = this; return trimAlignValue({ value, handle: sHandle, bounds, props: this.$props }); }, ensureValueNotConflict(handle, val, _ref2) { let { allowCross, pushable: thershold } = _ref2; const state = this.$data || {}; const { bounds } = state; handle = handle === undefined ? state.sHandle : handle; thershold = Number(thershold); /* eslint-disable eqeqeq */ if (!allowCross && handle != null && bounds !== undefined) { if (handle > 0 && val <= bounds[handle - 1] + thershold) { return bounds[handle - 1] + thershold; } if (handle < bounds.length - 1 && val >= bounds[handle + 1] - thershold) { return bounds[handle + 1] - thershold; } } /* eslint-enable eqeqeq */ return val; }, getTrack(_ref3) { let { bounds, prefixCls, reverse, vertical, included, offsets, trackStyle } = _ref3; return bounds.slice(0, -1).map((_, index) => { const i = index + 1; const trackClassName = (0, _classNames.default)({ [`${prefixCls}-track`]: true, [`${prefixCls}-track-${i}`]: true }); return (0, _vue.createVNode)(_Track.default, { "class": trackClassName, "vertical": vertical, "reverse": reverse, "included": included, "offset": offsets[i - 1], "length": offsets[i] - offsets[i - 1], "style": trackStyle[index], "key": i }, null); }); }, renderSlider() { const { sHandle, bounds, prefixCls, vertical, included, disabled, min, max, reverse, handle, defaultHandle, trackStyle, handleStyle, tabindex, ariaLabelGroupForHandles, ariaLabelledByGroupForHandles, ariaValueTextFormatterGroupForHandles } = this; const handleGenerator = handle || defaultHandle; const offsets = bounds.map(v => this.calcOffset(v)); const handleClassName = `${prefixCls}-handle`; const handles = bounds.map((v, i) => { let mergedTabIndex = tabindex[i] || 0; if (disabled || tabindex[i] === null) { mergedTabIndex = null; } const dragging = sHandle === i; return handleGenerator({ class: (0, _classNames.default)({ [handleClassName]: true, [`${handleClassName}-${i + 1}`]: true, [`${handleClassName}-dragging`]: dragging }), prefixCls, vertical, dragging, offset: offsets[i], value: v, index: i, tabindex: mergedTabIndex, min, max, reverse, disabled, style: handleStyle[i], ref: h => this.saveHandle(i, h), onFocus: this.onFocus, onBlur: this.onBlur, ariaLabel: ariaLabelGroupForHandles[i], ariaLabelledBy: ariaLabelledByGroupForHandles[i], ariaValueTextFormatter: ariaValueTextFormatterGroupForHandles[i] }); }); return { tracks: this.getTrack({ bounds, prefixCls, reverse, vertical, included, offsets, trackStyle }), handles }; } } }); var _default = exports.default = (0, _createSlider.default)(Range);