UNPKG

mp-colorui

Version:

MP ColorUI 是一款基于 Taro 框架并且联合 Color-UI CSS 库开发的多端 UI 组件库(支持小程序端和H5端)

155 lines 6.17 kB
import Nerv from "nervjs"; import { ScrollView, Text, View } from "@tarojs/components"; import Taro, { createSelectorQuery as _createSelectorQuery } from "@tarojs/taro-h5"; import { BG_COLOR_LIST, TEXT_COLOR_LIST } from "../../lib/model"; import "./index.scss"; import { classNames, getRectNumber, isAliPay, screenPercent } from "../../lib/index"; let move = 0; let scrollLeftContent = 0; let duration = 0.3; let distance = 0; export default class ClTabs extends Taro.Component { constructor() { super(...arguments); this.state = { activeTab: 0, scrollLeft: 0, contentScrollLeft: 0 }; } componentDidMount() { this.props.tabs.length && this.onClickTab(this.props.active || 0); } componentWillReceiveProps(nextProps, nextContext) { const nextActive = nextProps.active; const thisActive = this.props.active; if (nextActive !== thisActive) { this.onClickTab(nextActive || 0); } } onClickTab(index) { const id = this.props.tabs[index].id; const id0 = this.props.tabs[0].id; const query = _createSelectorQuery(); const view = query.select(`#${id}`); const view0 = query.select(`#${id0}`); let left = 0; const promise = new Promise(resolve => { new Promise(resolve1 => { view0.boundingClientRect().exec(res => { const data = res[0]; left = data.left; resolve1(); }); }).then(() => { view.boundingClientRect().exec(res => { const data = res[getRectNumber()]; if (isAliPay) { left = data.width * index; } else { left = Math.abs(left - data.left); } resolve(left); }); }); }); promise.then(() => { this.setState({ activeTab: index, scrollLeft: (index - 1) * 60, contentScrollLeft: left + Math.random() / 10 }); }); this.props.onClick && this.props.onClick(index); } renderDefaultComponent(paramters) { const { bgColorClassName, activeColor, tabs, activeTab, scrollLeft } = paramters; return <ScrollView scrollX className={`${bgColorClassName} nav`} scrollWithAnimation scrollLeft={scrollLeft}> {tabs.map((item, index) => <View key={index} className={`cu-item ${activeTab === index ? `${activeColor} cur` : ""}`} onClick={this.onClickTab.bind(this, index)}> {item.icon ? <Text className={`cuIcon-${item.icon} margin-right-xs`} /> : ""} <Text>{item.text}</Text> </View>)} </ScrollView>; } renderVerbComponent(paramters) { const { bgColorClassName, activeColor, tabs, activeTab } = paramters; return <ScrollView scrollX className={`${bgColorClassName} nav`}> <View className="flex text-center"> {tabs.map((item, index) => <View key={index} className={`cu-item flex-sub ${activeTab === index ? `${activeColor} cur` : ""}`} onClick={this.onClickTab.bind(this, index)}> {item.icon ? <Text className={`cuIcon-${item.icon} margin-right-xs`} /> : ""} <Text>{item.text}</Text> </View>)} </View> </ScrollView>; } renderCenterComponent(paramters) { const { bgColorClassName, activeColor, tabs, activeTab } = paramters; return <ScrollView scrollX className={`${bgColorClassName} nav text-center`}> {tabs.map((item, index) => <View key={index} className={`cu-item ${activeTab === index ? `${activeColor} cur` : ""}`} onClick={this.onClickTab.bind(this, index)}> {item.icon ? <Text className={`cuIcon-${item.icon} margin-right-xs`} /> : ""} <Text>{item.text}</Text> </View>)} </ScrollView>; } render() { const { contentScrollLeft } = this.state; const bgColorClassName = this.props.bgColor ? BG_COLOR_LIST[this.props.bgColor] : ""; const activeColor = this.props.activeColor ? TEXT_COLOR_LIST[this.props.activeColor] : ""; // 空组件镇压邪魔 const centerComponent = <View />; const renderComponent = () => { const { type, tabs } = this.props; const { activeTab, scrollLeft } = this.state; const defaultParameter = { bgColorClassName, activeColor, tabs, activeTab, scrollLeft }; if (type === "default") return this.renderDefaultComponent(defaultParameter);else if (type === "verb") return this.renderVerbComponent(defaultParameter);else if (type === "center") return this.renderCenterComponent(defaultParameter);else return <View />; }; return <View className={classNames(this.props.className)} style={Object.assign({ overflow: "hidden" }, this.props.style)}> {renderComponent()} <ScrollView scrollY> <View className="scrollx" style={{ width: "auto", transform: `translateX(-${Taro.pxTransform(contentScrollLeft / screenPercent)})`, transitionDuration: `${duration}s` }} onTouchStart={e => { if (!this.props.touchMove) return; scrollLeftContent = 0; duration = 0; move = e.touches[0].pageX; }} onTouchMove={e => { if (!this.props.touchMove) return; if (scrollLeftContent === 0) scrollLeftContent = e.touches[0].pageX; distance = e.touches[0].pageX - scrollLeftContent; this.setState({ contentScrollLeft: contentScrollLeft - distance }); scrollLeftContent = e.touches[0].pageX; }} onTouchEnd={e => { if (!this.props.touchMove) return; duration = 0.3; move = e.changedTouches[0].pageX - move; const maxIndex = this.props.tabs.length - 1; if (move < -50) this.onClickTab(this.state.activeTab + 1 > maxIndex ? maxIndex : this.state.activeTab + 1);else if (move > 50) this.onClickTab(this.state.activeTab - 1);else this.onClickTab(this.state.activeTab); }}> {this.props.children} </View> </ScrollView> </View>; } } ClTabs.options = { addGlobalClass: true }; ClTabs.defaultProps = { type: "default", bgColor: undefined, activeColor: "black", active: 0, tabs: [], touchMove: false };