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

Commit

Permalink
feat: add FloatLayout
Browse files Browse the repository at this point in the history
  • Loading branch information
pengshanglong committed May 13, 2020
1 parent 9a826bb commit 9b85868
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 3 deletions.
174 changes: 174 additions & 0 deletions src/components/float-layout/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import classNames from 'classnames'
import { handleTouchScroll } from '../../utils/common'

export default {
name: 'FloatLayout',
props: {
title: {
type: String,
default: '',
},
isOpened: {
type: Boolean,
default: false,
},
scrollY: {
type: Boolean,
default: true,
},
scrollX: {
type: Boolean,
default: false,
},
scrollWithAnimation: {
type: Boolean,
default: false,
},
onClose: {
type: Function,
default: () => () => {},
},
onScroll: {
type: Function,
default: () => () => {},
},
onScrollToLower: {
type: Function,
default: () => () => {},
},
onScrollToUpper: {
type: Function,
default: () => () => {},
},
scrollTop: {
type: Number,
default: 0,
},
scrollLeft: {
type: Number,
default: 0,
},
upperThreshold: {
type: Number,
default: 0,
},
lowerThreshold: {
type: Number,
default: 0,
},
className: {
type: [String, Array],
default: '',
},
},
data() {
const { isOpened } = this
return {
state: {
_isOpened: isOpened,
},
}
},
watch: {
isOpened(val, oldVal) {
if (val !== oldVal) {
handleTouchScroll(val)
}
if (val !== this.state._isOpened) {
this.setState({
_isOpened: val,
})
}
},
},
methods: {
setState(newState, fn) {
const ks = Object.keys(newState)
if (Array.isArray(ks)) {
ks.forEach((k) => {
if (k in this.state) {
this.state[k] = newState[k]
}
})
}
this.$nextTick(() => {
typeof fn === 'function' && fn.call(this)
})
},
handleClose() {
if (typeof this.onClose === 'function') {
this.onClose()
}
},
close() {
this.setState(
{
_isOpened: false,
},
this.handleClose
)
},
/**
*
* @param {event} e
*/
handleTouchMove(e) {
e.stopPropagation()
},
},
render() {
const { _isOpened } = this.state
const {
title,

scrollY,
scrollX,
scrollTop,
scrollLeft,
upperThreshold,
lowerThreshold,
scrollWithAnimation,
} = this

const rootClass = classNames(
'at-float-layout',
{
'at-float-layout--active': _isOpened,
},
this.className
)

return (
<view class={rootClass} onTouchMove={this.handleTouchMove}>
<view onTap={this.close} class="at-float-layout__overlay" />
<view class="at-float-layout__container layout">
{title ? (
<view class="layout-header">
<view class="layout-header__title">{title}</view>
<view class="layout-header__btn-close" onTap={this.close} />
</view>
) : null}
<view class="layout-body">
<scroll-view
scrollY={scrollY}
scrollX={scrollX}
scrollTop={scrollTop}
scrollLeft={scrollLeft}
upperThreshold={upperThreshold}
lowerThreshold={lowerThreshold}
scrollWithAnimation={scrollWithAnimation}
// @ts-ignore // TODO: Fix typings
onScroll={this.onScroll}
// @ts-ignore // TODO: Fix typings
onScrollToLower={this.onScrollToLower}
// @ts-ignore // TODO: Fix typings
onScrollToUpper={this.onScrollToUpper}
class="layout-body__content">
{this.$slots.default}
</scroll-view>
</view>
</view>
</view>
)
},
}
3 changes: 2 additions & 1 deletion src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ import Grid from './grid/index'
import List from './list/index'
import ListItem from './list/item/index'
import Card from './card/index'
import FloatLayout from './float-layout/index'

export { Grid, List, ListItem, Card }
export { Grid, List, ListItem, Card, FloatLayout }
9 changes: 8 additions & 1 deletion src/pages/index/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
<view
class="index"
>
<FloatLayout
title="这是个标题"
>
这是内容区 随你怎么写这是内容区 随你怎么写这是内容区 随你怎么写这是内容区
随你怎么写这是内容区 随你怎么写这是内容区 随你怎么写
</FloatLayout>
<Card
note="小Tips"
extra="额外信息"
Expand Down Expand Up @@ -211,7 +217,7 @@ import ModalAction from '../../components/modal/action/index.jsx'
import Toast from '../../components/toast/index.jsx'
import SwipeAction from '../../components/swipe-action/index.jsx'
import Message from '../../components/message/index.jsx'
import { Grid, List, ListItem, Card } from '../../components/index'
import { Grid, List, ListItem, Card, FloatLayout } from '../../components/index'
export default {
name: 'Index',
Expand Down Expand Up @@ -242,6 +248,7 @@ export default {
List,
ListItem,
Card,
FloatLayout,
},
data() {
return {
Expand Down
32 changes: 31 additions & 1 deletion src/utils/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,34 @@ function isTest(): boolean {
return process.env.NODE_ENV === 'test'
}

export { getEnvs, delayGetScrollOffset, delayGetClientRect, delayQuerySelector, uuid, isTest }
let scrollTop = 0

function handleTouchScroll(flag: any): void {
if (ENV !== Taro.ENV_TYPE.WEB) {
return
}
if (flag) {
scrollTop = document.documentElement.scrollTop

// 使body脱离文档流
document.body.classList.add('at-frozen')

// 把脱离文档流的body拉上去!否则页面会回到顶部!
document.body.style.top = `${-scrollTop}px`
} else {
document.body.style.top = null
document.body.classList.remove('at-frozen')

document.documentElement.scrollTop = scrollTop
}
}

export {
getEnvs,
delayGetScrollOffset,
delayGetClientRect,
delayQuerySelector,
uuid,
isTest,
handleTouchScroll,
}

0 comments on commit 9b85868

Please sign in to comment.