| | |
| | | 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 props from './props'; |
| | | import config from '../common/config'; |
| | | import touch from '../mixins/touch'; |
| | | import { getRect, uniqueFactory } from '../common/utils'; |
| | | const { prefix } = config; |
| | | const name = `${prefix}-tabs`; |
| | | const getUniqueID = uniqueFactory('tabs'); |
| | | let Tabs = class Tabs extends SuperComponent { |
| | | constructor() { |
| | | super(...arguments); |
| | | this.behaviors = [touch]; |
| | | this.externalClasses = [ |
| | | `${prefix}-class`, |
| | | `${prefix}-class-item`, |
| | | `${prefix}-class-active`, |
| | | `${prefix}-class-track`, |
| | | `${prefix}-class-content`, |
| | | ]; |
| | | this.relations = { |
| | | '../tab-panel/tab-panel': { |
| | | type: 'descendant', |
| | | linked(target) { |
| | | this.children.push(target); |
| | | this.initChildId(); |
| | | 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.initChildId(); |
| | | }, |
| | | }, |
| | | }; |
| | | this.properties = props; |
| | | this.controlledProps = [ |
| | | { |
| | | key: 'value', |
| | | event: 'change', |
| | | }, |
| | | ]; |
| | | this.observers = { |
| | | value(name) { |
| | | if (name !== this.getCurrentName()) { |
| | | this.setCurrentIndexByName(name); |
| | | } |
| | | }, |
| | | }; |
| | | this.data = { |
| | | prefix, |
| | | classPrefix: name, |
| | | tabs: [], |
| | | currentIndex: -1, |
| | | trackStyle: '', |
| | | offset: 0, |
| | | tabID: '', |
| | | placement: 'top', |
| | | }; |
| | | this.lifetimes = { |
| | | created() { |
| | | this.children = this.children || []; |
| | | }, |
| | | attached() { |
| | | wx.nextTick(() => { |
| | | this.setTrack(); |
| | | }); |
| | | getRect(this, `.${name}`).then((rect) => { |
| | | this.containerWidth = rect.width; |
| | | }); |
| | | this.setData({ |
| | | tabID: getUniqueID(), |
| | | }); |
| | | }, |
| | | }; |
| | | this.methods = { |
| | | onScroll(e) { |
| | | const { scrollLeft } = e.detail; |
| | | this.setData({ |
| | | offset: scrollLeft, |
| | | }); |
| | | }, |
| | | updateTabs(cb) { |
| | | const { children } = this; |
| | | const tabs = children.map((child) => child.data); |
| | | tabs.forEach((item) => { |
| | | if (typeof item.icon === 'string') { |
| | | item.icon = { name: item.icon }; |
| | | } |
| | | }); |
| | | this.setData({ tabs }, 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) { |
| | | return offset + targetLeft - (1 / 2) * containerWidth + targetWidth / 2; |
| | | }, |
| | | getTrackSize() { |
| | | return new Promise((resolve, reject) => { |
| | | if (this.trackWidth) { |
| | | resolve(this.trackWidth); |
| | | return; |
| | | } |
| | | getRect(this, `.${prefix}-tabs__track`) |
| | | .then((res) => { |
| | | if (res) { |
| | | this.trackWidth = res.width; |
| | | resolve(this.trackWidth); |
| | | } |
| | | }) |
| | | .catch(reject); |
| | | }); |
| | | }, |
| | | setTrack() { |
| | | return __awaiter(this, void 0, void 0, function* () { |
| | | if (!this.properties.showBottomLine) |
| | | return; |
| | | const { children } = this; |
| | | if (!children) |
| | | return; |
| | | const { currentIndex } = this.data; |
| | | if (currentIndex <= -1) |
| | | return; |
| | | try { |
| | | const res = yield getRect(this, `.${prefix}-tabs__item`, true); |
| | | const rect = res[currentIndex]; |
| | | if (!rect) |
| | | return; |
| | | let count = 0; |
| | | let distance = 0; |
| | | let totalSize = 0; |
| | | res.forEach((item) => { |
| | | if (count < currentIndex) { |
| | | distance += item.width; |
| | | count += 1; |
| | | } |
| | | totalSize += item.width; |
| | | }); |
| | | if (this.containerWidth) { |
| | | const offset = this.calcScrollOffset(this.containerWidth, rect.left, rect.width, this.data.offset); |
| | | const maxOffset = totalSize - this.containerWidth; |
| | | this.setData({ |
| | | offset: Math.min(Math.max(offset, 0), maxOffset), |
| | | }); |
| | | } |
| | | if (this.data.theme === 'line') { |
| | | const trackLineWidth = yield this.getTrackSize(); |
| | | distance += (rect.width - trackLineWidth) / 2; |
| | | } |
| | | this.setData({ |
| | | trackStyle: `-webkit-transform: translateX(${distance}px); |
| | | transform: translateX(${distance}px); |
| | | `, |
| | | }); |
| | | } |
| | | 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; |
| | | }, |
| | | }; |
| | | } |
| | | initChildId() { |
| | | this.children.forEach((item, index) => { |
| | | item.setId(`${this.data.tabID}_panel_${index}`); |
| | | }); |
| | | } |
| | | }; |
| | | Tabs = __decorate([ |
| | | wxComponent() |
| | | ], Tabs); |
| | | export default Tabs; |
| | | import{__awaiter,__decorate}from"tslib";import{SuperComponent,wxComponent}from"../common/src/index";import props from"./props";import config from"../common/config";import touch from"../mixins/touch";import{getRect,uniqueFactory}from"../common/utils";import{getObserver}from"../common/wechat";const{prefix:prefix}=config,name=`${prefix}-tabs`,getUniqueID=uniqueFactory("tabs");let Tabs=class extends SuperComponent{constructor(){super(...arguments),this.options={pureDataPattern:/^currentLabels$/},this.behaviors=[touch],this.externalClasses=[`${prefix}-class`,`${prefix}-class-item`,`${prefix}-class-active`,`${prefix}-class-track`,`${prefix}-class-content`],this.relations={"../tab-panel/tab-panel":{type:"descendant",linked(t){this.children.push(t),this.initChildId(),t.index=this.children.length-1,this.updateTabs()},unlinked(t){this.children=this.children.filter(e=>e.index!==t.index),this.updateTabs(()=>this.setTrack()),this.initChildId()}}},this.properties=props,this.controlledProps=[{key:"value",event:"change"}],this.observers={value(t){t!==this.getCurrentName()&&this.setCurrentIndexByName(t)}},this.data={prefix:prefix,classPrefix:name,tabs:[],currentLabels:[],currentIndex:-1,trackOption:{lineWidth:0,distance:0,isInit:!0},offset:0,scrollLeft:0,tabID:"",placement:"top"},this.lifetimes={created(){this.children=this.children||[]},attached(){wx.nextTick(()=>{this.setTrack()}),getRect(this,`.${name}`).then(t=>{this.containerWidth=t.width}),this.setData({tabID:getUniqueID()})}},this.methods={onScroll(t){const{scrollLeft:e}=t.detail;this.setData({scrollLeft:e})},updateTabs(t){const{children:e}=this,i=e.map(t=>t.data);i.forEach(t=>{"string"==typeof t.icon&&(t.icon={name:t.icon})}),this.setData({tabs:i},t),this.setCurrentIndexByName(this.properties.value)},setCurrentIndexByName(t){const{children:e}=this,i=e.findIndex(e=>e.getComputedName()===`${t}`);i>-1&&this.setCurrentIndex(i)},setCurrentIndex(t){if(t<=-1||t>=this.children.length)return;const e=[];this.children.forEach((i,s)=>{const r=t===s;r===i.data.active&&i.initialized||i.render(r,this),e.push(i.data.label)});const{currentIndex:i,currentLabels:s}=this.data;i===t&&s.join("")===e.join("")||this.setData({currentIndex:t,currentLabels:e},()=>{this.setTrack()})},getCurrentName(){if(this.children){const t=this.children[this.data.currentIndex];if(t)return t.getComputedName()}},calcScrollOffset:(t,e,i,s)=>s+e-.5*t+i/2,getTabHeight(){return getRect(this,`.${name}`)},getTrackSize(){const{bottomLineMode:t}=this.properties,e={fixed:`.${prefix}-tabs__track`,auto:`.${prefix}-tabs__item--active .${prefix}-tabs__item-inner`,full:`.${prefix}-tabs__item--active`};return new Promise((i,s)=>{this.trackWidth?i(this.trackWidth):getRect(this,e[t]||e.fixed).then(t=>{t&&i(t.width)}).catch(s)})},setTrack(){return __awaiter(this,void 0,void 0,function*(){const{children:t}=this;if(!t)return;const{currentIndex:e}=this.data;if(!(e<=-1))try{const t=yield getRect(this,`.${prefix}-tabs__item`,!0),i=t[e];if(!i)return;let s=0,r=0,n=0;if(t.forEach(t=>{s<e&&(r+=t.width,s+=1),n+=t.width}),this.containerWidth){const t=this.calcScrollOffset(this.containerWidth,i.left,i.width,this.data.scrollLeft),e=n-this.containerWidth;this.setData({offset:Math.min(Math.max(t,0),e)})}else this._hasObserved||(this._hasObserved=!0,getObserver(this,`.${name}`).then(()=>this.setTrack()));const a=yield this.getTrackSize();"line"===this.data.theme&&(r+=(i.width-a)/2);const h=void 0===this.previousIndex;(h||this.previousIndex!==e)&&(this.previousIndex=e,this.setData({trackOption:{lineWidth:a,distance:r,isInit:h}}))}catch(t){this.triggerEvent("error",t)}})},onTabTap(t){const{index:e}=t.currentTarget.dataset;this.changeIndex(e)},onTouchStart(t){this.properties.swipeable&&this.touchStart(t)},onTouchMove(t){this.properties.swipeable&&this.touchMove(t)},onTouchEnd(){if(!this.properties.swipeable)return;const{direction:t,deltaX:e,offsetX:i}=this;if("horizontal"===t&&i>=50){const t=this.getAvailableTabIndex(e);-1!==t&&this.changeIndex(t)}},onTouchScroll(t){this._trigger("scroll",t.detail)},changeIndex(t){const e=this.data.tabs[t],{value:i,label:s}=e;(null==e?void 0:e.disabled)||t===this.data.currentIndex||this._trigger("change",{value:i,label:s}),this._trigger("click",{value:i,label:s})},getAvailableTabIndex(t){const e=t>0?-1:1,{currentIndex:i,tabs:s}=this.data,r=s.length;for(let t=e;i+e>=0&&i+e<r;t+=e){const e=i+t;if(!(e>=0&&e<r&&s[e]))return i;if(!s[e].disabled)return e}return-1}}}initChildId(){this.children.forEach((t,e)=>{t.setId(`${this.data.tabID}_panel_${e}`)})}};Tabs=__decorate([wxComponent()],Tabs);export default Tabs; |