Skip to content

Commit

Permalink
feat: 优化
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Jan 30, 2019
1 parent d8c90aa commit a969231
Show file tree
Hide file tree
Showing 17 changed files with 348 additions and 71 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
dist
node_modules
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
}
1 change: 0 additions & 1 deletion config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ const config = {
if (!cssNames.has(cssNameKey)) {
cssNames.set(cssNameKey, `m-${componentName.toLowerCase() === local ? '' : (`${componentName.toLowerCase()}-`)}${local}`)
}
console.log(...arguments)
return cssNames.get(cssNameKey)
},
},
Expand Down
3 changes: 2 additions & 1 deletion src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ class App extends Taro.Component {
pages: [
// 'pages/Home/Home',
// 'pages/Sticky/Sticky',
'pages/Transition/Transition',
// 'pages/Transition/X',
'pages/Popup/Popup',
],
window: {
navigationBarTitleText: 'DEMO',
Expand Down
42 changes: 42 additions & 0 deletions src/components/Popup/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
@import '../../settings.scss';

.popup {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
.mask {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(black, 0.6);
}
.content {
position: relative;
z-index: 1;
}
&.center {
justify-content: center;
align-items: center;
}
&.top {
justify-content: center;
align-items: flex-start;
}
&.bottom {
justify-content: center;
align-items: flex-end;
}
&.left {
justify-content: flex-start;
align-items: center;
}
&.right {
justify-content: flex-end;
align-items: center;
}
}
117 changes: 117 additions & 0 deletions src/components/Popup/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import Taro from '@tarojs/taro'
import { View } from '@tarojs/components'
import { noop } from 'vtils'
import { component, RequiredProp } from '../component'
import MTransition from '../Transition'
import _ from './index.module.scss'

type Position = 'center' | 'top' | 'bottom' | 'right' | 'left'

const positionToTransitionName: { [key in Position]: MTransition['props']['name'] } = {
center: 'fade',
top: 'slideDown',
bottom: 'slideUp',
left: 'slideLeft',
right: 'slideRight',
}

/**
* 弹出层组件。
*/
class MPopup extends component({
props: {
/** 弹出层是否可见 */
visible: false as any as RequiredProp<boolean>,
/** 点击遮罩是否可关闭 */
maskClosable: true as boolean,
/** 动画时长,单位: ms */
duration: 300 as number,
/** 弹出内容位置 */
position: 'center' as Position,
/** 可见性变化事件 */
onVisibleChange: noop as any as RequiredProp<(visible: boolean) => void>,
},
state: {
/** zIndex 值 */
zIndex: 0 as number,
/** 弹出层是否显示 */
display: false as boolean,
},
}) {
/** 起始 zIndex 值 */
static startZIndex = 5000

/** 计数器 */
transitionEndCounter = 0

componentWillMount() {
this.setState({
zIndex: MPopup.startZIndex++,
display: this.props.visible,
})
}

componentWillReceiveProps(nextProps: MPopup['props']) {
if (nextProps.visible !== this.props.visible) {
this.setState({
display: true,
})
}
}

handleTouchMove = (e: Event) => {
e.stopPropagation()
}

handleMaskClick = () => {
if (this.props.maskClosable) {
this.props.onVisibleChange(false)
}
}

handleTransitionEnd = () => {
this.transitionEndCounter++
if (this.transitionEndCounter >= 2) {
this.transitionEndCounter = 0
this.setState({
display: this.props.visible,
})
}
}

render() {
const { visible, duration, position } = this.props
const { zIndex, display } = this.state
return (
<View
className={`${_.popup} ${_[position]}`}
style={{
zIndex,
...(display ? {} : { display: 'none' }),
}}
onTouchMove={this.handleTouchMove as any}>
<MTransition
name='fade'
visible={visible}
duration={duration}
onTransitionEnd={this.handleTransitionEnd}>
<View
className={_.mask}
onClick={this.handleMaskClick}
/>
</MTransition>
<View className={_.content}>
<MTransition
name={positionToTransitionName[position]}
visible={visible}
duration={duration}
onTransitionEnd={this.handleTransitionEnd}>
{this.props.children}
</MTransition>
</View>
</View>
)
}
}

export default MPopup
33 changes: 13 additions & 20 deletions src/components/Sticky/index.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,23 @@
import Taro from '@tarojs/taro'
import { View } from '@tarojs/components'
import { Disposer } from 'vtils'
import { component } from '../component'
import { CUSTOM_CLASS } from '../const'
import _ from './index.module.scss'

/**
* 吸顶组件。
*/
class MSticky extends Taro.Component<{}, {
/** 是否置顶 */
fixed: boolean,
/** 内容高度,单位:px */
contentHeight: number,
}> {
static options: wx.ComponentOptions = {
addGlobalClass: true,
}

class MSticky extends component({
state: {
/** 是否置顶 */
fixed: false as boolean,
/** 内容高度,单位:px */
contentHeight: 0 as number,
},
}) {
disposer = new Disposer()

constructor() {
super(...arguments)
this.state = {
fixed: false,
contentHeight: 0,
}
}

componentDidMount() {
wx.createSelectorQuery()
.in(this.$scope)
Expand All @@ -51,11 +43,12 @@ class MSticky extends Taro.Component<{}, {
}

render() {
const { className } = this.props
const { fixed, contentHeight } = this.state
return (
<View
className={`${_.sticky} ${fixed && _.fixed}`}
style={{ height: contentHeight ? `${contentHeight}px` : 'initial' }}>
className={`${_.sticky} ${fixed && _.fixed} ${className} ${CUSTOM_CLASS}`}
style={contentHeight ? { height: `${contentHeight}px` } : {}}>
<View className={_.content}>
{this.props.children}
</View>
Expand Down
95 changes: 48 additions & 47 deletions src/components/Transition/index.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,50 @@
import Taro from '@tarojs/taro'
import { View } from '@tarojs/components'
import { noop } from 'vtils'
import { component, RequiredProp } from '../component'
import { CUSTOM_CLASS } from '../const'
import _ from './index.module.scss'

/**
* 动画过渡组件。
*/
class MTransition extends Taro.Component<{
/** 组件是否可见 */
visible?: boolean,
/** 动画名称 */
name?: (
/** 淡入 */
'fade' |
/** 上滑淡入 */
'fadeUp' |
/** 下滑淡入 */
'fadeDown' |
/** 左滑淡入 */
'fadeLeft' |
/** 右滑淡入 */
'fadeRight' |
/** 上滑进入 */
'slideUp' |
/** 下滑进入 */
'slideDown' |
/** 左滑进入 */
'slideLeft' |
/** 右滑进入 */
'slideRight'
),
/** 动画时长,单位: ms */
duration?: number,
}, {
/** 动画类型 */
type: 'Enter' | 'Leave',
/** 是否展示组件 */
display: boolean,
}> {
static options: wx.ComponentOptions = {
addGlobalClass: true,
}

static defaultProps: MTransition['props'] = {
visible: true,
name: 'fade',
duration: 1300,
}

class MTransition extends component({
props: {
/** 组件是否可见 */
visible: true as any as RequiredProp<boolean>,
/** 动画名称 */
name: 'fade' as (
/** 淡入 */
'fade' |
/** 上滑淡入 */
'fadeUp' |
/** 下滑淡入 */
'fadeDown' |
/** 左滑淡入 */
'fadeLeft' |
/** 右滑淡入 */
'fadeRight' |
/** 上滑进入 */
'slideUp' |
/** 下滑进入 */
'slideDown' |
/** 左滑进入 */
'slideLeft' |
/** 右滑进入 */
'slideRight'
),
/** 动画时长,单位: ms */
duration: 300 as number,
/** 动画结束事件 */
onTransitionEnd: noop as () => void,
},
state: {
/** 动画类型 */
type: 'Enter' as 'Enter' | 'Leave',
/** 是否展示组件 */
display: false as boolean,
},
}) {
componentWillMount() {
if (this.props.visible) {
this.setState({
Expand All @@ -68,18 +66,21 @@ class MTransition extends Taro.Component<{
}

handleAnimationEnd = () => {
this.setState({
display: this.props.visible,
})
this.setState(
{ display: this.props.visible },
() => {
this.props.onTransitionEnd()
}
)
}

render() {
const { name, duration } = this.props
const { name, duration, className } = this.props
const { type, display } = this.state
const animation = `${_[`${name}${type}`]} ${duration}ms both`
return (
<View
className={_.transition}
className={`${_.transition} ${className} ${CUSTOM_CLASS}`}
style={{
WebkitAnimation: animation,
animation: animation,
Expand Down
Loading

0 comments on commit a969231

Please sign in to comment.