Skip to content
This repository has been archived by the owner on Oct 27, 2021. It is now read-only.

Commit

Permalink
feat(drawer): 新增 AtDrawer 组件
Browse files Browse the repository at this point in the history
  • Loading branch information
pengshanglong committed Jun 4, 2020
1 parent 96d06db commit 0f6db73
Show file tree
Hide file tree
Showing 4 changed files with 506 additions and 0 deletions.
156 changes: 156 additions & 0 deletions src/components/drawer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import { View } from '@tarojs/components'
import classNames from 'classnames'
import Vue from 'vue'
import Component from 'vue-class-component'
import mixins from '../mixins'
import AtList from '../list/index'
import AtListItem from '../list/item/index'

const setState = mixins.methods.setState

const AtDrawerProps = Vue.extend({
name: 'AtDrawer',
mixins: [mixins],
props: {
show: {
type: Boolean,
default: false,
},
mask: {
type: Boolean,
default: true,
},
right: {
type: Boolean,
default: false,
},
width: {
type: [Number, String],
default: '',
},
items: {
type: Array,
default: function () {
return []
},
},
className: {
type: [Object, String],
default: function () {
return {}
},
},
onClose: {
type: Function,
default: function () {
return () => {}
},
},
onItemClick: {
type: Function,
default: function () {
return () => {}
},
},
},
})

@Component
export default class AtDrawer extends AtDrawerProps {
state
constructor() {
super()
this.state = {
animShow: false,
_show: this.show,
}
}

setState = setState

mount(): void {
const { _show } = this.state
if (_show) this.animShow()
}

handleItemClick(index: number): void {
this.onItemClick && this.onItemClick(index)
this.animHide()
}

onHide(): void {
this.setState({ _show: false }, () => {
this.onClose && this.onClose()
})
}

animHide(): void {
this.setState({
animShow: false,
})
setTimeout(() => {
this.onHide()
}, 300)
}

animShow(): void {
this.setState({ _show: true })
setTimeout(() => {
this.setState({
animShow: true,
})
}, 200)
}

onMaskClick(): void {
this.animHide()
}

render(h) {
const { mask, width, right, items } = this
const { animShow, _show } = this.state
const rootClassName = ['at-drawer']

const maskStyle = {
display: mask ? 'block' : 'none',
opacity: animShow ? 1 : 0,
}
const listStyle = {
width,
transition: animShow
? 'all 225ms cubic-bezier(0, 0, 0.2, 1)'
: 'all 195ms cubic-bezier(0.4, 0, 0.6, 1)',
}

const classObject = {
'at-drawer--show': animShow,
'at-drawer--right': right,
'at-drawer--left': !right,
}

return _show ? (
<View class={classNames(rootClassName, classObject, this.className)}>
<View class="at-drawer__mask" style={maskStyle} onTap={this.onMaskClick.bind(this)}></View>

<View class="at-drawer__content" style={listStyle}>
{!!items && items.length ? (
<AtList>
{items.map((name, index) => (
<AtListItem
key={`${name}-${index}`}
data-index={index}
props={{ onClick: this.handleItemClick.bind(this, index) }}
title={name}
arrow="right"></AtListItem>
))}
</AtList>
) : (
this.$slots.default
)}
</View>
</View>
) : (
<View></View>
)
}
}
155 changes: 155 additions & 0 deletions tests/components/drawer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import classNames from 'classnames'
import Vue from 'vue'
import Component from 'vue-class-component'
import mixins from '../mixins'
import AtList from '../list/index'
import AtListItem from '../list/item/index'

const setState = mixins.methods.setState

const AtDrawerProps = Vue.extend({
name: 'AtDrawer',
mixins: [mixins],
props: {
show: {
type: Boolean,
default: false,
},
mask: {
type: Boolean,
default: true,
},
right: {
type: Boolean,
default: false,
},
width: {
type: [Number, String],
default: '',
},
items: {
type: Array,
default: function () {
return []
},
},
className: {
type: [Object, String],
default: function () {
return {}
},
},
onClose: {
type: Function,
default: function () {
return () => {}
},
},
onItemClick: {
type: Function,
default: function () {
return () => {}
},
},
},
})

@Component
export default class AtDrawer extends AtDrawerProps {
state
constructor() {
super()
this.state = {
animShow: false,
_show: this.show,
}
}

setState = setState

mount(): void {
const { _show } = this.state
if (_show) this.animShow()
}

handleItemClick(index: number): void {
this.onItemClick && this.onItemClick(index)
this.animHide()
}

onHide(): void {
this.setState({ _show: false }, () => {
this.onClose && this.onClose()
})
}

animHide(): void {
this.setState({
animShow: false,
})
setTimeout(() => {
this.onHide()
}, 300)
}

animShow(): void {
this.setState({ _show: true })
setTimeout(() => {
this.setState({
animShow: true,
})
}, 200)
}

onMaskClick(): void {
this.animHide()
}

render(h) {
const { mask, width, right, items } = this
const { animShow, _show } = this.state
const rootClassName = ['at-drawer']

const maskStyle = {
display: mask ? 'block' : 'none',
opacity: animShow ? 1 : 0,
}
const listStyle = {
width,
transition: animShow
? 'all 225ms cubic-bezier(0, 0, 0.2, 1)'
: 'all 195ms cubic-bezier(0.4, 0, 0.6, 1)',
}

const classObject = {
'at-drawer--show': animShow,
'at-drawer--right': right,
'at-drawer--left': !right,
}

return _show ? (
<view class={classNames(rootClassName, classObject, this.className)}>
<view class="at-drawer__mask" style={maskStyle} onTap={this.onMaskClick.bind(this)}></view>

<view class="at-drawer__content" style={listStyle}>
{!!items && items.length ? (
<AtList>
{items.map((name, index) => (
<AtListItem
key={`${name}-${index}`}
data-index={index}
props={{ onClick: this.handleItemClick.bind(this, index) }}
title={name}
arrow="right"></AtListItem>
))}
</AtList>
) : (
this.$slots.default
)}
</view>
</view>
) : (
<view></view>
)
}
}
Loading

0 comments on commit 0f6db73

Please sign in to comment.