From 03455874fbf9f97864560b6ff48f6089f3f7ef57 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Thu, 17 Dec 2020 16:57:15 +0800 Subject: [PATCH] =?UTF-8?q?fix(SwipeAction):=20=E4=BF=AE=E5=A4=8D=20SwipeA?= =?UTF-8?q?ction=20=E6=BB=91=E5=8A=A8=E5=8D=A1=E9=A1=BF=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-ui/config/rollup.config.js | 11 - packages/taro-ui/package.json | 1 - .../src/components/swipe-action/index.tsx | 272 +++++++----------- .../components/swipe-action/options/index.tsx | 23 +- .../src/style/components/swipe-action.scss | 10 + packages/taro-ui/types/swipe-action.d.ts | 6 +- 6 files changed, 119 insertions(+), 204 deletions(-) diff --git a/packages/taro-ui/config/rollup.config.js b/packages/taro-ui/config/rollup.config.js index a1ba6b589..237f2940a 100644 --- a/packages/taro-ui/config/rollup.config.js +++ b/packages/taro-ui/config/rollup.config.js @@ -29,17 +29,6 @@ export default { file: resolveFile(Package.module), format: 'es', sourcemap: true - }, - { - file: resolveFile(Package.browser), - format: 'umd', - name: 'taro-ui', - sourcemap: true, - globals: { - react: 'React', - '@tarojs/components': 'components', - '@tarojs/taro': 'Taro' - } } ], external: externalPackages, diff --git a/packages/taro-ui/package.json b/packages/taro-ui/package.json index f61c20b43..4467fdb9b 100644 --- a/packages/taro-ui/package.json +++ b/packages/taro-ui/package.json @@ -2,7 +2,6 @@ "name": "taro-ui", "version": "3.0.0-alpha.3", "description": "UI KIT for Taro", - "browser": "dist/index.umd.js", "module": "dist/index.esm.js", "main": "dist/index.js", "source": "src/index.ts", diff --git a/packages/taro-ui/src/components/swipe-action/index.tsx b/packages/taro-ui/src/components/swipe-action/index.tsx index d68c13a48..afd928deb 100644 --- a/packages/taro-ui/src/components/swipe-action/index.tsx +++ b/packages/taro-ui/src/components/swipe-action/index.tsx @@ -1,20 +1,14 @@ import classNames from 'classnames' -import _inRange from 'lodash/inRange' -import _isEmpty from 'lodash/isEmpty' import PropTypes, { InferProps } from 'prop-types' import React from 'react' -import { Text, View } from '@tarojs/components' -import { CommonEvent, ITouchEvent } from '@tarojs/components/types/common' +import { Text, View, MovableArea, MovableView } from '@tarojs/components' +import { CommonEvent } from '@tarojs/components/types/common' import { AtSwipeActionProps, AtSwipeActionState, SwipeActionOption } from '../../../types/swipe-action' -import { - delayGetClientRect, - delayGetScrollOffset, - uuid -} from '../../common/utils' +import { uuid } from '../../common/utils' import AtSwipeActionOptions from './options/index' export default class AtSwipeAction extends React.Component< @@ -24,48 +18,22 @@ export default class AtSwipeAction extends React.Component< public static defaultProps: AtSwipeActionProps public static propTypes: InferProps - private endValue: number - private startX: number - private startY: number private maxOffsetSize: number - private domInfo: any - private isMoving: boolean - private isTouching: boolean + private moveX: number + private eleWidth: number public constructor(props: AtSwipeActionProps) { super(props) - const { isOpened } = props - this.endValue = 0 - this.startX = 0 - this.startY = 0 - this.maxOffsetSize = 0 - this.domInfo = { - top: 0, - bottom: 0, - left: 0, - right: 0 - } - this.isMoving = false - this.isTouching = false + const { isOpened, maxDistance, areaWidth } = props + this.maxOffsetSize = maxDistance this.state = { componentId: uuid(), offsetSize: 0, - _isOpened: !!isOpened + _isOpened: !!isOpened, + needAnimation: false } - } - - private getDomInfo(): Promise { - return Promise.all([ - delayGetClientRect({ - delayTime: 0, - selectorStr: `#swipeAction-${this.state.componentId}` - }), - delayGetScrollOffset({ delayTime: 0 }) - ]).then(([rect, scrollOffset]) => { - rect[0].top += scrollOffset[0].scrollTop - rect[0].bottom += scrollOffset[0].scrollTop - this.domInfo = rect[0] - }) + this.moveX = 0 + this.eleWidth = areaWidth } public UNSAFE_componentWillReceiveProps(nextProps: AtSwipeActionProps): void { @@ -78,118 +46,40 @@ export default class AtSwipeAction extends React.Component< } private _reset(isOpened: boolean): void { - this.isMoving = false - this.isTouching = false - if (isOpened) { - this.endValue = -this.maxOffsetSize this.setState({ _isOpened: true, - offsetSize: -this.maxOffsetSize + offsetSize: 0 }) } else { - this.endValue = 0 - this.setState({ - offsetSize: 0, - _isOpened: false - }) + this.setState( + { + offsetSize: this.moveX + }, + () => { + this.setState({ + offsetSize: this.maxOffsetSize, + _isOpened: false + }) + } + ) } } - private computeTransform = (value: number): string | null => - // if (Taro.getEnv() === Taro.ENV_TYPE.ALIPAY) { - // return !_isNil(value) ? `translate3d(${value}px,0,0)` : null - // } - value ? `translate3d(${value}px,0,0)` : null - private handleOpened = (event: CommonEvent): void => { const { onOpened } = this.props - if (typeof onOpened === 'function' && this.state._isOpened) { + if (typeof onOpened === 'function') { onOpened(event) } } private handleClosed = (event: CommonEvent): void => { const { onClosed } = this.props - if (typeof onClosed === 'function' && !this.state._isOpened) { + if (typeof onClosed === 'function') { onClosed(event) } } - private handleTouchStart = (e: ITouchEvent): void => { - const { clientX, clientY } = e.touches[0] - - if (this.props.disabled) return - - this.getDomInfo() - - this.startX = clientX - this.startY = clientY - this.isTouching = true - } - - private handleTouchMove = (e: ITouchEvent): void => { - if (_isEmpty(this.domInfo)) { - return - } - - const { startX, startY } = this - const { top, bottom, left, right } = this.domInfo - const { clientX, clientY, pageX, pageY } = e.touches[0] - - const x = Math.abs(clientX - startX) - const y = Math.abs(clientY - startY) - - const inDom = _inRange(pageX, left, right) && _inRange(pageY, top, bottom) - - if (!this.isMoving && inDom) { - this.isMoving = - y === 0 || - x / y >= Number.parseFloat(Math.tan((45 * Math.PI) / 180).toFixed(2)) - } - - if (this.isTouching && this.isMoving) { - e.preventDefault() - - const offsetSize = clientX - this.startX - const isRight = offsetSize > 0 - - if (this.state.offsetSize === 0 && isRight) return - - const value = this.endValue + offsetSize - this.setState({ - offsetSize: value >= 0 ? 0 : value - }) - } - } - - private handleTouchEnd = (event: ITouchEvent): void => { - this.isTouching = false - - const { offsetSize } = this.state - - this.endValue = offsetSize - - const breakpoint = this.maxOffsetSize / 2 - const absOffsetSize = Math.abs(offsetSize) - - if (absOffsetSize > breakpoint) { - this._reset(true) - this.handleOpened(event) - return - } - - this._reset(false) // TODO: Check behavior - this.handleClosed(event) - } - - private handleDomInfo = ({ width }: { width: number }): void => { - const { _isOpened } = this.state - - this.maxOffsetSize = width - this._reset(_isOpened) - } - private handleClick = ( item: SwipeActionOption, index: number, @@ -206,51 +96,93 @@ export default class AtSwipeAction extends React.Component< } } + onTouchEnd = e => { + if (this.moveX === 0) { + this._reset(true) + this.handleOpened(e) + return + } + if (this.moveX === this.maxOffsetSize) { + this._reset(false) + this.handleClosed(e) + return + } + if (this.state._isOpened && this.moveX > 0) { + this._reset(false) + this.handleClosed(e) + return + } + if (this.maxOffsetSize - this.moveX < this.maxOffsetSize * 0.4) { + this._reset(false) + this.handleClosed(e) + } else { + this._reset(true) + this.handleOpened(e) + } + } + + onChange = e => { + this.moveX = e.detail.x + } + public render(): JSX.Element { - const { offsetSize, componentId } = this.state + const { componentId, offsetSize } = this.state const { options } = this.props const rootClass = classNames('at-swipe-action', this.props.className) - const transform = this.computeTransform(offsetSize) - const transformStyle: React.CSSProperties = transform ? { transform } : {} return ( - - {this.props.children} - - - {Array.isArray(options) && options.length > 0 ? ( - - {options.map((item, key) => ( - this.handleClick(item, key, e)} - className={classNames( - 'at-swipe-action__option', - item.className - )} + {this.props.children} + {Array.isArray(options) && options.length > 0 ? ( + - {item.text} - - ))} - - ) : null} + {options.map((item, key) => ( + this.handleClick(item, key, e)} + className={classNames( + 'at-swipe-action__option', + item.className + )} + > + {item.text} + + ))} + + ) : null} + + ) } @@ -260,7 +192,9 @@ AtSwipeAction.defaultProps = { options: [], isOpened: false, disabled: false, - autoClose: false + autoClose: false, + maxDistance: 0, + areaWidth: 0 } AtSwipeAction.propTypes = { diff --git a/packages/taro-ui/src/components/swipe-action/options/index.tsx b/packages/taro-ui/src/components/swipe-action/options/index.tsx index 9930dafd7..9c93391cf 100644 --- a/packages/taro-ui/src/components/swipe-action/options/index.tsx +++ b/packages/taro-ui/src/components/swipe-action/options/index.tsx @@ -2,32 +2,10 @@ import classNames from 'classnames' import React from 'react' import { View } from '@tarojs/components' import { AtSwipeActionOptionsProps } from '../../../../types/swipe-action' -import { delayQuerySelector } from '../../../common/utils' export default class AtSwipeActionOptions extends React.Component< AtSwipeActionOptionsProps > { - private trrigerOptionsDomUpadte(): void { - delayQuerySelector( - `#swipeActionOptions-${this.props.componentId}`, - 100 - ).then(res => { - this.props.onQueryedDom(res[0]) - }) - } - - public componentDidMount(): void { - this.trrigerOptionsDomUpadte() - } - - public UNSAFE_componentWillReceiveProps( - nextProps: AtSwipeActionOptionsProps - ): void { - if (nextProps.options !== this.props.options) { - this.trrigerOptionsDomUpadte() - } - } - public render(): JSX.Element { const rootClass = classNames( 'at-swipe-action__options', @@ -38,6 +16,7 @@ export default class AtSwipeActionOptions extends React.Component< {this.props.children} diff --git a/packages/taro-ui/src/style/components/swipe-action.scss b/packages/taro-ui/src/style/components/swipe-action.scss index 827ba2485..5cd095c0c 100644 --- a/packages/taro-ui/src/style/components/swipe-action.scss +++ b/packages/taro-ui/src/style/components/swipe-action.scss @@ -4,12 +4,19 @@ .at-swipe-action { position: relative; overflow: hidden; + width: 100%; + + &__area { + height: auto; + } /* elements */ &__content { position: relative; font-size: $font-size-lg; background-color: $at-swipe-action-bg-color; + display: flex; + height: 100%; z-index: 2; &.animtion { @@ -26,6 +33,8 @@ height: 100%; color: $at-swipe-action-color; font-size: $at-swipe-action-font-size; + width: 120px; + text-align: center; background-color: $at-swipe-action-option-bg-color; } @@ -39,5 +48,6 @@ right: 0; height: 100%; z-index: 1; + opacity: 0; } } diff --git a/packages/taro-ui/types/swipe-action.d.ts b/packages/taro-ui/types/swipe-action.d.ts index d8a3f2150..5fc7bf449 100644 --- a/packages/taro-ui/types/swipe-action.d.ts +++ b/packages/taro-ui/types/swipe-action.d.ts @@ -53,18 +53,22 @@ export interface AtSwipeActionProps extends AtComponent { * 完全关闭时触发 */ onClosed?: CommonEventFunction + + maxDistance: number + + areaWidth: number } export interface AtSwipeActionState { componentId: string offsetSize: number _isOpened: boolean + needAnimation: boolean } export interface AtSwipeActionOptionsProps extends AtComponent { componentId: string options: SwipeActionOption[] - onQueryedDom: (res: any) => void } declare const AtSwipeAction: ComponentClass