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; }; import dom from '../behaviors/dom'; import touch from '../behaviors/touch'; import { SuperComponent, wxComponent } from '../common/src/index'; import props from './props'; import config from '../common/config'; const { prefix } = config; const name = `${prefix}-tabs`; var Position; (function (Position) { Position["top"] = "top"; Position["right"] = "right"; Position["bottom"] = "bottom"; Position["left"] = "left"; })(Position || (Position = {})); const trackLineWidth = 30; let Tabs = class Tabs extends SuperComponent { constructor() { super(...arguments); this.behaviors = [dom, touch]; this.externalClasses = [`${prefix}-class`, `${prefix}-class-item`, `${prefix}-class-active`, `${prefix}-class-track`]; this.relations = { './tab-panel': { type: 'descendant', linked(target) { this.children.push(target); target.index = this.children.length - 1; this.updateTabs(); }, unlinked(target) { this.children = this.children.filter((item) => item.index !== target.index); this.updateTabs(() => this.setTrack()); }, }, }; this.properties = props; this.controlledProps = [ { key: 'value', event: 'change', }, ]; this.observers = { value(name) { if (name !== this.getCurrentName()) { this.setCurrentIndexByName(name); } }, animation(v) { this.setData({ animate: v }); }, placement() { this.adjustPlacement(); }, }; this.data = { prefix, classPrefix: name, tabs: [], currentIndex: -1, trackStyle: '', isScrollX: true, isScrollY: false, direction: 'X', animate: { duration: 0 }, offset: 0, }; this.methods = { adjustPlacement() { const { placement } = this.properties; let isScrollX = false; let isScrollY = false; if (placement === Position.top || placement === Position.bottom) { isScrollX = true; } else { isScrollY = true; } this.setData({ isScrollX, isScrollY, direction: isScrollX ? 'X' : 'Y', }); }, }; } created() { this.children = this.children || []; } attached() { wx.nextTick(() => { this.setTrack(); }); this.adjustPlacement(); this.gettingBoundingClientRect(`.${name}`, true).then((res) => { this.containerWidth = res[0].width; }); } updateTabs(cb) { const { children } = this; this.setData({ tabs: children.map((child) => child.data), }, cb); this.setCurrentIndexByName(this.properties.value); } setCurrentIndexByName(name) { const { children } = this; const index = children.findIndex((child) => child.getComputedName() === `${name}`); if (index > -1) { this.setCurrentIndex(index); } } setCurrentIndex(index) { if (index <= -1 || index >= this.children.length) return; this.children.forEach((child, idx) => { const isActive = index === idx; if (isActive !== child.data.active) { child.render(isActive, this); } }); if (this.data.currentIndex === index) return; this.setData({ currentIndex: index, }); this.setTrack(); } getCurrentName() { if (this.children) { const activeTab = this.children[this.data.currentIndex]; if (activeTab) { return activeTab.getComputedName(); } } } calcScrollOffset(containerWidth, targetLeft, targetWidth, offset, currentIndex) { return currentIndex * targetWidth - (1 / 2) * containerWidth + targetWidth / 2; } setTrack() { if (!this.properties.showBottomLine) return; const { children } = this; if (!children) return; const { currentIndex, isScrollX, direction } = this.data; if (currentIndex <= -1) return; this.gettingBoundingClientRect(`.${prefix}-tabs__item`, true) .then((res) => { const rect = res[currentIndex]; if (!rect) return; let count = 0; let distance = 0; for (const item of res) { if (count < currentIndex) { distance += isScrollX ? item.width : item.height; count += 1; } } if (this.containerWidth) { const offset = this.calcScrollOffset(this.containerWidth, rect.left, rect.width, this.data.offset, currentIndex); this.setData({ offset, }); } if (isScrollX) { distance += (rect.width - trackLineWidth) / 2; } let trackStyle = `-webkit-transform: translate${direction}(${distance}px); transform: translate${direction}(${distance}px); `; trackStyle += isScrollX ? `width: ${trackLineWidth}px;` : `height: ${rect.height}px;`; this.setData({ trackStyle, }); }) .catch((err) => { this.triggerEvent('error', err); }); } onTabTap(event) { const { index } = event.currentTarget.dataset; this.changeIndex(index); } onTouchStart(event) { if (!this.properties.swipeable) return; this.touchStart(event); } onTouchMove(event) { if (!this.properties.swipeable) return; this.touchMove(event); } onTouchEnd() { if (!this.properties.swipeable) return; const { direction, deltaX, offsetX } = this; const minSwipeDistance = 50; if (direction === 'horizontal' && offsetX >= minSwipeDistance) { const index = this.getAvailableTabIndex(deltaX); if (index !== -1) { this.changeIndex(index); } } } onTouchScroll(event) { this._trigger('scroll', event.detail); } changeIndex(index) { const currentTab = this.data.tabs[index]; const { value, label } = currentTab; if (!(currentTab === null || currentTab === void 0 ? void 0 : currentTab.disabled) && index !== this.data.currentIndex) { this._trigger('change', { value, label }); } this._trigger('click', { value, label }); } getAvailableTabIndex(deltaX) { const step = deltaX > 0 ? -1 : 1; const { currentIndex, tabs } = this.data; const len = tabs.length; for (let i = step; currentIndex + step >= 0 && currentIndex + step < len; i += step) { const newIndex = currentIndex + i; if (newIndex >= 0 && newIndex < len && tabs[newIndex] && !tabs[newIndex].disabled) { return newIndex; } } return -1; } }; Tabs = __decorate([ wxComponent() ], Tabs); export default Tabs;