UNPKG

antd-mini

Version:

antd-mini 是支付宝小程序 UI 组件库,遵循 Ant Design 规范。

163 lines (156 loc) 4.49 kB
import createValue from '../mixins/value'; import { getInstanceBoundingClientRect } from '../_util/jsapi/get-instance-bounding-client-rect'; import { Component, getValueFromProps, triggerEvent } from '../_util/simply'; import { TabsDefaultProps } from './props'; Component({ props: TabsDefaultProps, data: { scrollLeft: 0, scrollTop: 0, leftFade: false, rightFade: false, }, scrollLeft: 0, scrollTop: 0, methods: { getInstance() { if (this.$id) { return my; } return this; }, get$Id() { return this.$id ? `-${this.$id}` : ''; }, async getBoundingClientRect(query: string) { return await getInstanceBoundingClientRect(this.getInstance(), query); }, async updateFade() { this.setData({ leftFade: !!this.scrollLeft, }); const items = getValueFromProps(this, 'items'); const [view, item] = await Promise.all([ this.getBoundingClientRect(`#ant-tabs-bar-scroll-view${this.get$Id()}`), this.getBoundingClientRect( `#ant-tabs-bar-item${this.get$Id()}-${items.length - 1}` ), ]); if (!item || !view) { return; } this.setData({ rightFade: item.left + item.width / 2 > view.width, }); }, async updateScroll() { const current = this.getValue(); const [view, item] = await Promise.all([ this.getBoundingClientRect(`#ant-tabs-bar-scroll-view${this.get$Id()}`), this.getBoundingClientRect( `#ant-tabs-bar-item${this.get$Id()}-${current}` ), ]); if (!view || !item) { return; } const [direction, scrollMode] = getValueFromProps(this, [ 'direction', 'scrollMode', ]); if (direction === 'vertical') { let scrollTop = this.scrollTop || 0; let needScroll = false; if (scrollMode === 'center') { needScroll = true; scrollTop += item.top - view.top - Math.max((view.height - item.height) / 2, 0); } else { const distance = item.top - view.top; if (distance < 0) { scrollTop += distance; needScroll = true; } else if (distance + item.height > view.height) { scrollTop += Math.min( distance + item.height - view.height, distance ); needScroll = true; } } if (needScroll) { if (scrollTop === this.data.scrollTop) { scrollTop += Math.random(); } this.setData({ scrollTop, }); } return; } let scrollLeft = this.scrollLeft || 0; let needScroll = false; if (scrollMode === 'center') { needScroll = true; scrollLeft += item.left - view.left - Math.max((view.width - item.width) / 2, 0); } else { const distance = item.left - view.left; if (distance < 0) { scrollLeft += distance; needScroll = true; } else if (distance + item.width > view.width) { scrollLeft += Math.min(distance + item.width - view.width, distance); needScroll = true; } } if (needScroll) { if (scrollLeft === this.data.scrollLeft) { scrollLeft += Math.random(); } this.setData({ scrollLeft, }); this.updateFade(); } }, async onScroll(e) { const direction = getValueFromProps(this, 'direction'); if (direction === 'vertical') { this.scrollTop = e.detail.scrollTop; return; } this.scrollLeft = e.detail.scrollLeft; this.updateFade(); }, onChange(e) { const index = parseInt(e.currentTarget.dataset.index, 10); const items = getValueFromProps(this, 'items'); if (items[index].disabled) { return; } if (this.getValue() === index) { return; } if (!this.isControlled()) { this.update(index); } triggerEvent(this, 'change', index, e); }, }, mixins: [ createValue({ valueKey: 'current', defaultValueKey: 'defaultCurrent', }), ], didMount() { this.updateScroll(); }, didUpdate(prevProps, prevData) { const items = getValueFromProps(this, 'items'); if (prevProps.items !== items || !this.isEqualValue(prevData)) { this.updateScroll(); } }, });