-
Notifications
You must be signed in to change notification settings - Fork 753
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(component): 完成 SwipeAction 组件编写
- Loading branch information
Showing
8 changed files
with
389 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import Taro from '@tarojs/taro' | ||
import { View, Text } from '@tarojs/components' | ||
|
||
import PropTypes from 'prop-types' | ||
import classNames from 'classnames' | ||
import _isFunction from 'lodash/isFunction' | ||
|
||
import AtComponent from '../../common/component' | ||
import AtSwipeActionOptions from './options/index' | ||
|
||
import './index.scss' | ||
|
||
export default class AtSwipeAction extends AtComponent { | ||
constructor () { | ||
super(...arguments) | ||
|
||
this.startX = null | ||
this.maxOffsetSize = 0 | ||
this.isTouching = false | ||
this.endValue = 0 | ||
|
||
this.state = { | ||
offsetSize: 0 | ||
} | ||
} | ||
|
||
handleTouchStart = e => { | ||
const { clientX } = e.touches[0] | ||
|
||
if (this.props.disabled) return | ||
|
||
this.startX = clientX | ||
this.isTouching = true | ||
} | ||
|
||
handleTouchEnd = () => { | ||
this.isTouching = false | ||
|
||
const { offsetSize } = this.state | ||
|
||
this.endValue = offsetSize | ||
|
||
const breakpoint = this.maxOffsetSize / 2 | ||
const absOffsetSize = Math.abs(offsetSize) | ||
|
||
if (absOffsetSize > breakpoint) { | ||
this.endValue = -this.maxOffsetSize | ||
return this.setState({ | ||
offsetSize: -this.maxOffsetSize | ||
}) | ||
} | ||
|
||
this.endValue = 0 | ||
|
||
this.setState({ | ||
offsetSize: 0 | ||
}) | ||
} | ||
|
||
handleTouchMove = e => { | ||
const { clientX } = e.touches[0] | ||
if (this.isTouching) { | ||
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 | ||
}) | ||
} | ||
} | ||
|
||
handleDomInfo = ({ width }) => { | ||
this.maxOffsetSize = width | ||
} | ||
|
||
handleClick = (item, index, ...arg) => { | ||
const { onClick, autoClose } = this.props | ||
if (_isFunction(onClick)) { | ||
onClick(item, index, ...arg) | ||
} | ||
if (autoClose) { | ||
this.setState({ | ||
offsetSize: 0 | ||
}) | ||
} | ||
} | ||
|
||
render () { | ||
const { offsetSize } = this.state | ||
const { options } = this.props | ||
const rootClass = classNames('at-swipe-action', this.props.className) | ||
|
||
return ( | ||
<View | ||
className={rootClass} | ||
onTouchMove={this.handleTouchMove} | ||
onTouchEnd={this.handleTouchEnd} | ||
onTouchStart={this.handleTouchStart} | ||
> | ||
<View | ||
className='at-swipe-action__content' | ||
style={{ | ||
transform: `translate3d(${offsetSize}px,0,0)` | ||
}} | ||
> | ||
{this.props.children} | ||
</View> | ||
|
||
{Array.isArray(options) && options.length > 0 ? ( | ||
<AtSwipeActionOptions onQueryedDom={this.handleDomInfo}> | ||
{options.map((item, key) => ( | ||
<View | ||
key={key} | ||
style={item.style} | ||
onClick={this.handleClick.bind(this, item, key)} | ||
className={classNames( | ||
'at-swipe-action__option', | ||
item.className | ||
)} | ||
> | ||
<Text className='option__text'>{item.text}</Text> | ||
</View> | ||
))} | ||
</AtSwipeActionOptions> | ||
) : null} | ||
</View> | ||
) | ||
} | ||
} | ||
|
||
AtSwipeAction.defaultProps = {} | ||
|
||
AtSwipeAction.propTypes = { | ||
disabled: PropTypes.bool, | ||
autoClose: PropTypes.bool, | ||
options: PropTypes.arrayOf( | ||
PropTypes.shape({ | ||
text: PropTypes.string, | ||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), | ||
className: PropTypes.oneOfType([ | ||
PropTypes.object, | ||
PropTypes.string, | ||
PropTypes.array | ||
]) | ||
}) | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
@import "../../style/mixins/index.scss"; | ||
@import "../../style/theme/default.scss"; | ||
|
||
.at-swipe-action { | ||
position: relative; | ||
overflow: hidden; | ||
|
||
&__content { | ||
background-color: white; | ||
position: relative; | ||
z-index: 2; | ||
font-size: $font-size-lg; | ||
transition: transform 200ms $timing-func; | ||
} | ||
|
||
&__option { | ||
@include active; | ||
@include align-items(center); | ||
|
||
height: 100%; | ||
background-color: $color-grey-2; | ||
display: inline-flex; | ||
color: $color-white; | ||
font-size: $font-size-base; | ||
padding: 0 $spacing-h-xl; | ||
text-align: center; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import Taro from '@tarojs/taro' | ||
import { View } from '@tarojs/components' | ||
|
||
// import PropTypes from 'prop-types' | ||
import classNames from 'classnames' | ||
|
||
import AtComponent from '../../../common/component' | ||
|
||
import './index.scss' | ||
|
||
const REM_LAYOUT_DELAY = 500 | ||
|
||
export default class AtSwiperActionOptions extends AtComponent { | ||
delay = () => | ||
new Promise(resolve => { | ||
if (Taro.getEnv() === Taro.ENV_TYPE.WEB) { | ||
return setTimeout(() => { | ||
resolve() | ||
}, REM_LAYOUT_DELAY) | ||
} | ||
if (Taro.getEnv() === Taro.ENV_TYPE.WEAPP) { | ||
return resolve() | ||
} | ||
}) | ||
|
||
componentDidMount () { | ||
const selector = Taro.createSelectorQuery().in(this.$scope) | ||
|
||
this.delay().then(() => { | ||
selector | ||
.select('.at-swipe-action__options') | ||
.fields({ | ||
size: true | ||
}) | ||
.exec(res => { | ||
console.log(res[0]) | ||
this.props.onQueryedDom(res[0]) | ||
}) | ||
}) | ||
} | ||
|
||
render () { | ||
const rootClass = classNames( | ||
'at-swipe-action__options', | ||
this.props.className | ||
) | ||
|
||
return <View className={rootClass}>{this.props.children}</View> | ||
} | ||
} | ||
|
||
AtSwiperActionOptions.defaultProps = {} | ||
|
||
AtSwiperActionOptions.propTypes = {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
@import '../../../style/mixins/libs/flex.scss'; | ||
|
||
.at-swipe-action__options { | ||
@include align-items(center); | ||
|
||
display: inline-flex; | ||
position: absolute; | ||
top: 0; | ||
right: 0; | ||
z-index: 1; | ||
height: 100%; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/* eslint taro/custom-component-children: 0 */ | ||
|
||
import Taro from '@tarojs/taro' | ||
import { View } from '@tarojs/components' | ||
|
||
import AtList from '../../../components/list/index' | ||
import AtListItem from '../../../components/list/item/index' | ||
import AtSwipeAction from '../../../components/swipe-action/index' | ||
|
||
import DocsHeader from '../../components/doc-header' | ||
|
||
import './index.scss' | ||
|
||
const OPTIONS = [ | ||
{ | ||
text: '取消', | ||
style: { | ||
backgroundColor: '#6190E8' | ||
} | ||
}, | ||
{ | ||
text: '确认', | ||
style: { | ||
backgroundColor: '#FF4949' | ||
} | ||
} | ||
] | ||
|
||
export default class SwipeActionPage extends Taro.Component { | ||
config = { | ||
navigationBarTitleText: 'Taro UI' | ||
} | ||
|
||
handleClick = (item, key, e) => { | ||
console.log('触发了点击', item, key, e) | ||
} | ||
|
||
render () { | ||
return ( | ||
<View className='page swipe-action-page'> | ||
{/* S Header */} | ||
<DocsHeader title='SwipeAction 滑动按钮' /> | ||
{/* E Header */} | ||
|
||
{/* S Body */} | ||
<View className='doc-body'> | ||
{/* 无 Title */} | ||
<View className='panel'> | ||
<View className='panel__title'>普通使用</View> | ||
<View className='panel__content'> | ||
<View className='example-item'> | ||
<AtSwipeAction options={OPTIONS}> | ||
<View className='normal'>AtSwipeAction 一般使用场景</View> | ||
</AtSwipeAction> | ||
</View> | ||
</View> | ||
</View> | ||
|
||
<View className='panel'> | ||
<View className='panel__title'>禁止滑动</View> | ||
<View className='panel__content'> | ||
<View className='example-item'> | ||
<AtSwipeAction disabled options={OPTIONS}> | ||
<View className='normal'>禁止滑动展示</View> | ||
</AtSwipeAction> | ||
</View> | ||
</View> | ||
</View> | ||
|
||
<View className='panel'> | ||
<View className='panel__title'>自动关闭</View> | ||
<View className='panel__content'> | ||
<View className='example-item'> | ||
<AtSwipeAction autoClose options={OPTIONS}> | ||
<View className='normal'>自动关闭展示</View> | ||
</AtSwipeAction> | ||
</View> | ||
</View> | ||
</View> | ||
|
||
<View className='panel'> | ||
<View className='panel__title'>传递点击事件</View> | ||
<View className='panel__content'> | ||
<View className='example-item'> | ||
<AtSwipeAction onClick={this.handleClick} options={OPTIONS}> | ||
<View className='normal'>点击事件展示</View> | ||
</AtSwipeAction> | ||
</View> | ||
</View> | ||
</View> | ||
|
||
<View className='panel'> | ||
<View className='panel__title'>与List组件使用</View> | ||
<View className='panel__content'> | ||
<View className='example-item'> | ||
<AtList> | ||
<AtSwipeAction options={OPTIONS}> | ||
<AtListItem title='Item1' /> | ||
</AtSwipeAction> | ||
<AtSwipeAction options={OPTIONS}> | ||
<AtListItem title='Item2' /> | ||
</AtSwipeAction> | ||
<AtSwipeAction | ||
options={[ | ||
{ | ||
text: '警告', | ||
style: { | ||
backgroundColor: '#FFC82C' | ||
} | ||
} | ||
]} | ||
> | ||
<AtListItem title='Item3' /> | ||
</AtSwipeAction> | ||
</AtList> | ||
</View> | ||
</View> | ||
</View> | ||
</View> | ||
</View> | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.swipe-action-page { | ||
.normal { | ||
line-height: 50px; | ||
} | ||
} |
Oops, something went wrong.