var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { SuperComponent, wxComponent } from '../common/src/index'; import config from '../common/config'; import { trimSingleValue, trimValue } from './tool'; import props from './props'; import { getRect } from '../common/utils'; import Bus from '../common/bus'; const { prefix } = config; const name = `${prefix}-slider`; let Slider = class Slider extends SuperComponent { constructor() { super(...arguments); this.externalClasses = [ `${prefix}-class`, `${prefix}-class-bar`, `${prefix}-class-bar-active`, `${prefix}-class-bar-disabled`, `${prefix}-class-cursor`, ]; this.properties = props; this.controlledProps = [ { key: 'value', event: 'change', }, ]; this.data = { sliderStyles: '', classPrefix: name, initialLeft: null, initialRight: null, activeLeft: 0, activeRight: 0, maxRange: 0, lineLeft: 0, lineRight: 0, dotTopValue: [0, 0], _value: 0, blockSize: 20, isScale: false, scaleArray: [], scaleTextArray: [], prefix, isVisibleToScreenReader: false, }; this.observers = { value(newValue) { this.handlePropsChange(newValue); }, _value(newValue) { this.bus.on('initial', () => this.renderLine(newValue)); this.toggleA11yTips(); }, marks(val) { this.bus.on('initial', () => this.handleMark(val)); }, }; this.lifetimes = { created() { this.bus = new Bus(); }, attached() { const { value } = this.properties; if (!value) this.handlePropsChange(0); this.init(); this.injectPageScroll(); }, }; } injectPageScroll() { const { range, vertical } = this.properties; if (!range || !vertical) return; const pages = getCurrentPages() || []; let curPage = null; if (pages && pages.length - 1 >= 0) { curPage = pages[pages.length - 1]; } if (!curPage) return; const originPageScroll = curPage === null || curPage === void 0 ? void 0 : curPage.onPageScroll; curPage.onPageScroll = (rest) => { originPageScroll === null || originPageScroll === void 0 ? void 0 : originPageScroll.call(this, rest); this.observerScrollTop(rest); }; } observerScrollTop(rest) { const { scrollTop } = rest || {}; this.pageScrollTop = scrollTop; } toggleA11yTips() { this.setData({ isVisibleToScreenReader: true, }); setTimeout(() => { this.setData({ isVisibleToScreenReader: false, }); }, 2000); } renderLine(val) { const { min, max, range } = this.properties; const { maxRange } = this.data; if (range) { const left = (maxRange * (val[0] - Number(min))) / (Number(max) - Number(min)); const right = (maxRange * (Number(max) - val[1])) / (Number(max) - Number(min)); this.setLineStyle(left, right); } else { this.setSingleBarWidth(val); } } triggerValue(value) { if (this.preval === value) return; this.preval = value; this._trigger('change', { value: trimValue(value, this.properties), }); } handlePropsChange(newValue) { const value = trimValue(newValue, this.properties); const setValueAndTrigger = () => { this.setData({ _value: value, }); }; if (this.data.maxRange === 0) { this.init().then(setValueAndTrigger); return; } setValueAndTrigger(); } handleMark(marks) { const calcPos = (arr) => { const { max, theme } = this.properties; const { blockSize, maxRange } = this.data; const margin = theme === 'capsule' ? blockSize / 2 : 0; return arr.map((item) => ({ val: item, left: Math.round((item / Number(max)) * maxRange) + margin, })); }; if ((marks === null || marks === void 0 ? void 0 : marks.length) && Array.isArray(marks)) { this.setData({ isScale: true, scaleArray: calcPos(marks), scaleTextArray: [], }); } if (Object.prototype.toString.call(marks) === '[object Object]') { const scaleArray = Object.keys(marks).map((item) => Number(item)); const scaleTextArray = scaleArray.map((item) => marks[item]); this.setData({ isScale: scaleArray.length > 0, scaleArray: calcPos(scaleArray), scaleTextArray, }); } } setSingleBarWidth(value) { const { max, min, theme } = this.properties; const { maxRange, blockSize } = this.data; const halfBlock = theme === 'capsule' ? Number(blockSize) / 2 : 0; const percentage = (Number(value) - Number(min)) / (Number(max) - Number(min)); const width = percentage * maxRange + halfBlock; this.setData({ lineBarWidth: `${width}px`, }); } init() { return __awaiter(this, void 0, void 0, function* () { const line = yield getRect(this, '#sliderLine'); const { blockSize } = this.data; const { theme, vertical } = this.properties; const halfBlock = Number(blockSize) / 2; const { top, bottom, right, left } = line; let maxRange = vertical ? bottom - top : right - left; let initialLeft = vertical ? top : left; let initialRight = vertical ? bottom : right; if (initialLeft === 0 && initialRight === 0) return; if (theme === 'capsule') { maxRange = maxRange - Number(blockSize) - 6; initialLeft -= halfBlock; initialRight -= halfBlock; } this.setData({ maxRange, initialLeft, initialRight, }); this.bus.emit('initial'); }); } stepValue(value) { const { step, min, max } = this.properties; const decimal = String(step).indexOf('.') > -1 ? String(step).length - String(step).indexOf('.') - 1 : 0; const closestStep = trimSingleValue(Number((Math.round(value / Number(step)) * Number(step)).toFixed(decimal)), Number(min), Number(max)); return closestStep; } onSingleLineTap(e) { const { disabled } = this.properties; if (disabled) return; const value = this.getSingleChangeValue(e); this.triggerValue(value); } getSingleChangeValue(e) { const { min, max } = this.properties; const { initialLeft, maxRange } = this.data; const [touch] = e.changedTouches; const pagePosition = this.getPagePosition(touch); const currentLeft = pagePosition - initialLeft; let value = 0; if (currentLeft <= 0) { value = Number(min); } else if (currentLeft >= maxRange) { value = Number(max); } else { value = (currentLeft / maxRange) * (Number(max) - Number(min)) + Number(min); } return this.stepValue(value); } convertPosToValue(posValue, dir) { const { maxRange } = this.data; const { max, min } = this.properties; return dir === 0 ? (posValue / maxRange) * (Number(max) - Number(min)) + Number(min) : Number(max) - (posValue / maxRange) * (Number(max) - Number(min)); } onLineTap(e) { const { disabled, theme, vertical } = this.properties; const { initialLeft, initialRight, maxRange, blockSize } = this.data; if (disabled) return; const [touch] = e.changedTouches; const pagePosition = this.getPagePosition(touch); const halfBlock = theme === 'capsule' ? Number(blockSize) / 2 : 0; const currentLeft = pagePosition - initialLeft; if (currentLeft < 0 || currentLeft > maxRange + Number(blockSize)) return; Promise.all([getRect(this, '#leftDot'), getRect(this, '#rightDot')]).then(([leftDot, rightDot]) => { const pageScrollTop = this.pageScrollTop || 0; const leftDotPosition = vertical ? leftDot.top + pageScrollTop : leftDot.left; const distanceLeft = Math.abs(pagePosition - leftDotPosition - halfBlock); const rightDotPosition = vertical ? rightDot.top + pageScrollTop : rightDot.left; const distanceRight = Math.abs(rightDotPosition - pagePosition + halfBlock); const isMoveLeft = distanceLeft < distanceRight; if (isMoveLeft) { const left = pagePosition - initialLeft; const leftValue = this.convertPosToValue(left, 0); this.triggerValue([this.stepValue(leftValue), this.data._value[1]]); } else { const right = -(pagePosition - initialRight); const rightValue = this.convertPosToValue(right, 1); this.triggerValue([this.data._value[0], this.stepValue(rightValue)]); } }); } onTouchStart(e) { this.triggerEvent('dragstart', { e }); } onTouchMoveLeft(e) { const { disabled } = this.properties; const { initialLeft, _value } = this.data; if (disabled) return; const [touch] = e.changedTouches; const pagePosition = this.getPagePosition(touch); const currentLeft = pagePosition - initialLeft; const newData = [..._value]; const leftValue = this.convertPosToValue(currentLeft, 0); newData[0] = this.stepValue(leftValue); this.triggerValue(newData); } onTouchMoveRight(e) { const { disabled } = this.properties; const { initialRight, _value } = this.data; if (disabled) return; const [touch] = e.changedTouches; const pagePosition = this.getPagePosition(touch); const currentRight = -(pagePosition - initialRight); const newData = [..._value]; const rightValue = this.convertPosToValue(currentRight, 1); newData[1] = this.stepValue(rightValue); this.triggerValue(newData); } setLineStyle(left, right) { const { theme } = this.properties; const { blockSize, maxRange } = this.data; const halfBlock = theme === 'capsule' ? Number(blockSize) / 2 : 0; const [a, b] = this.data._value; const cut = (v) => parseInt(v, 10); this.setData({ dotTopValue: [a, b], }); if (left + right <= maxRange) { this.setData({ lineLeft: cut(left + halfBlock), lineRight: cut(right + halfBlock), }); } else { this.setData({ lineLeft: cut(maxRange + halfBlock - right), lineRight: cut(maxRange - left + halfBlock * 1.5), }); } } onTouchEnd(e) { this.triggerEvent('dragend', { e }); } getPagePosition(touch) { const { pageX, pageY } = touch; const { vertical } = this.properties; return vertical ? pageY : pageX; } }; Slider = __decorate([ wxComponent() ], Slider); export default Slider;