Skip to content

Commit

Permalink
feat(Layout): Layout 组件支持 iphoneX 页面显示, 并且增加上拉刷新支持
Browse files Browse the repository at this point in the history
  • Loading branch information
shaodahong committed Oct 31, 2018
1 parent 7fd313e commit b7db916
Show file tree
Hide file tree
Showing 14 changed files with 322 additions and 36 deletions.
2 changes: 1 addition & 1 deletion docs/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>AUTO-UI</title>
<script>
Expand Down
7 changes: 2 additions & 5 deletions docs/src/md/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,7 @@ class MDIndex extends React.Component {
<div className="simulator">
<div className="simulator-header">
<p>
{window.location.origin +
baseUrl +
'/#' +
this.state.iframeUrl}
{window.location.origin + baseUrl + this.state.iframeUrl}
</p>
<i
className="simulator-header__refresh"
Expand All @@ -110,7 +107,7 @@ class MDIndex extends React.Component {
ref={ele => {
this.iframe = ele
}}
src={baseUrl + '/#' + this.state.iframeUrl}
src={baseUrl + this.state.iframeUrl}
/>
</div>
</div>
Expand Down
42 changes: 41 additions & 1 deletion docs/src/mobile/layout/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,19 @@ import { Layout, Popup, Cell } from 'auto-ui'
class DemoLayout extends React.Component {
constructor(props) {
super(props)

this.content =
'我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容'
this.state = {
default: false,
highest: false,
Loading: false,
errorInfo: false,
hideFooter: false
hideFooter: false,
reachBottom: false,
content: [
'我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容,我是内容'
]
}
}
render() {
Expand Down Expand Up @@ -63,6 +70,15 @@ class DemoLayout extends React.Component {
>
不显示底部
</Cell.Row>
<Cell.Row
onClick={() => {
this.setState({
reachBottom: true
})
}}
>
上拉刷新
</Cell.Row>
</Cell>
<Popup
onBgClick={() => {
Expand Down Expand Up @@ -155,6 +171,30 @@ class DemoLayout extends React.Component {
<Layout.Footer visible={false}>footer</Layout.Footer>
</Layout>
</Popup>
<Popup visible={this.state.reachBottom}>
<Layout>
<Layout.Header>header</Layout.Header>

<Layout.Body
onReachBottom={{
handler: () => {
return new Promise(resolve => {
setTimeout(() => {
this.setState({
content: this.state.content.concat(this.content)
})
resolve()
}, 2000)
})
}
}}
>
{this.state.content}
</Layout.Body>

<Layout.Footer>footer</Layout.Footer>
</Layout>
</Popup>
</React.Fragment>
)
}
Expand Down
1 change: 1 addition & 0 deletions docs/src/mobile/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ body,
background-color: #f3f3f3;
height: 100%;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
&-title {
font-size: 100px;
text-align: center;
Expand Down
8 changes: 5 additions & 3 deletions docs/src/routers/index.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import React from 'react'
import { HashRouter, Route, Redirect, Switch } from 'react-router-dom'
import { BrowserRouter, Route, Redirect, Switch } from 'react-router-dom'

import md from '../md'
import mobile from '../mobile'
import test from './test.js'

// 配置路由
const Routes = e => {
return (
<HashRouter>
<BrowserRouter>
<Switch>
<Route path="/docs" component={md} />
<Route path="/mobile" component={mobile} />
<Route path="/test" component={test} />
<Redirect to="/docs/introduce" />
</Switch>
</HashRouter>
</BrowserRouter>
)
}

Expand Down
71 changes: 71 additions & 0 deletions docs/src/routers/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React from 'react'
import { Layout } from 'auto-ui'

class Test extends React.Component {
constructor(props) {
super(props)
this.state = {
disable: false
}
}
render() {
return (
<Layout>
<Layout.Header>header</Layout.Header>

<Layout.Body
onReachBottom={{
handler: () => {
return new Promise(resolve => {
setTimeout(() => {
resolve()
}, 2000)
})
}
}}
>
iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
fixed 定位的元素)。iPhoneX
取消了物理按键,改成底部小黑条,这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常见的吸底导航、返回顶部等各种相对底部
</Layout.Body>

<Layout.Footer>footer</Layout.Footer>
</Layout>
)
}
}

export default Test
21 changes: 21 additions & 0 deletions packages/__libs/reg.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const Regular = {
u: navigator.userAgent,

isAndroid() {
return this.u.indexOf('Android') > -1 || this.u.indexOf('Adr') > -1
},

isiOS() {
return !!this.u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
},

isAtzuche() {
return this.u.indexOf('atzuche') > -1
},

isiPhoneX() {
return this.u.indexOf('iphonex') > -1
}
}

export default Regular
12 changes: 12 additions & 0 deletions packages/iphonex_footer/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import './style'
import React from 'react'
import cn from 'classnames'

const IphoneXHeader = props => {
const { className } = props
const composeClassName = cn('iphonex-footer', className)

return <div className={composeClassName} />
}

export default IphoneXHeader
6 changes: 6 additions & 0 deletions packages/iphonex_footer/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.iphonex-footer {
width: 100%;
height: constant(safe-area-inset-bottom);
height: env(safe-area-inset-bottom);
background-color: #fff;
}
16 changes: 16 additions & 0 deletions packages/iphonex_header/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import './style'
import React from 'react'
import cn from 'classnames'
import reg from '../__libs/reg'

const IphoneXHeader = props => {
const { className } = props
const composeClassName = cn(className, {
isAtzucheiOSNotiPhoneX: reg.isAtzuche() && reg.isiOS() && !reg.isiPhoneX(),
'iphonex-header': reg.isAtzuche() && reg.isiPhoneX()
})

return <div className={composeClassName} />
}

export default IphoneXHeader
10 changes: 10 additions & 0 deletions packages/iphonex_header/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.iphonex-header {
background-color: #fff;
width: 100%;
height: 70px;
}
.isAtzucheiOSNotiPhoneX {
background-color: #fff;
width: 100%;
height: 40px;
}
100 changes: 87 additions & 13 deletions packages/layout/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,31 @@ import './style'
import React from 'react'
import cn from 'classnames'
import Spin from '../spin'
import IPhoneXHeader from '../iphonex_header'
import IPhoneXFooter from '../iphonex_footer'

const Layout = props => {
const { className, children, ...otherProps } = props
const composeClassName = cn('x-app', className)
return (
<div {...otherProps} className={composeClassName}>
<IPhoneXHeader />
{children}
<IPhoneXFooter />
</div>
)
}

const LayoutBody = props => {
const { className, loading, errorInfo, children, ...otherProps } = props
const composeClassName = cn('x-app-body', className, {
'x-app-body--loading': loading,
'x-app-body--error': errorInfo
})

function content() {
class LayoutBody extends React.Component {
constructor(props) {
super(props)
this.timer = null
this.state = {
bottomLoading: false
}
}
content() {
const { loading, errorInfo, children } = this.props
if (loading) {
return <Spin className="x-app__loading" />
} else if (errorInfo) {
Expand All @@ -35,11 +41,79 @@ const LayoutBody = props => {
}
}

return (
<div {...otherProps} className={composeClassName}>
{content()}
</div>
)
scroll = e => {
e.preventDefault()
const { onReachBottom } = this.props
if (onReachBottom && onReachBottom.disable) {
return
}

const wrapper = e.target
const inner = e.target.querySelector('.x-app-body__inner')
if (e.target.className.indexOf('x-app-body') > -1) {
this.detectReachBottom(wrapper, inner)
}
}

// 判断是否到达底部
detectReachBottom = (wrapper, inner) => {
if (this.state.bottomLoading) {
return
}
const { onReachBottom } = this.props
this.timer && clearTimeout(this.timer)
this.timer = setTimeout(() => {
const h = inner.clientHeight
const bh = wrapper.clientHeight + wrapper.scrollTop
// 快滚动到底部时
if (h - bh < 200) {
this.setState(
{
bottomLoading: true
},
async () => {
onReachBottom && (await onReachBottom.handler())
this.setState({
bottomLoading: false
})
}
)
}
}, 300)
}

render() {
const {
loading,
errorInfo,
className,
onReachBottom,
...otherProps
} = this.props
const composeClassName = cn('x-app-body', className, {
'x-app-body--loading': loading,
'x-app-body--error': errorInfo
})
return (
<div {...otherProps} className={composeClassName} onScroll={this.scroll}>
<div className="x-app-body__inner">{this.content()}</div>
{onReachBottom && (
<div className="x-app-body__bottom">
{!this.state.bottomLoading && (
<div className="x-app-body__bottom-inner">
{onReachBottom.content}
</div>
)}
{!!this.state.bottomLoading && (
<div className="x-app-body__bottom-inner">
<Spin text="加载中..." />
</div>
)}
</div>
)}
</div>
)
}
}

const LayoutFooter = props => {
Expand Down
Loading

0 comments on commit b7db916

Please sign in to comment.