use context to implement multiple drawers

This commit is contained in:
陈帅 2018-07-02 21:49:06 +08:00
parent 441b90e488
commit dba4b8c3c9
7 changed files with 87 additions and 47 deletions

View File

@ -5,19 +5,20 @@ exports[`Drawer closable is false 1`] = `
class=""
>
<div
class="ant-drawer ant-drawer-left ant-drawer-open"
class="ant-drawer ant-drawer-right ant-drawer-open"
>
<div
class="ant-drawer-mask"
/>
<div
class="ant-drawer-content-wrapper"
style=""
>
<div
class="ant-drawer-content"
>
<div
style="width: 256px;"
style="overflow: auto; height: 100%; width: 256px;"
>
<div
class="ant-drawer-body"
@ -36,13 +37,14 @@ exports[`Drawer destroyOnClose is true 1`] = `
class=""
>
<div
class="ant-drawer ant-drawer-left"
class="ant-drawer ant-drawer-right"
>
<div
class="ant-drawer-mask"
/>
<div
class="ant-drawer-content-wrapper"
style="transform: translateX(100%);"
>
<div
class="ant-drawer-content"
@ -57,19 +59,20 @@ exports[`Drawer have a title 1`] = `
class=""
>
<div
class="ant-drawer ant-drawer-left ant-drawer-open"
class="ant-drawer ant-drawer-right ant-drawer-open"
>
<div
class="ant-drawer-mask"
/>
<div
class="ant-drawer-content-wrapper"
style=""
>
<div
class="ant-drawer-content"
>
<div
style="width: 256px;"
style="overflow: auto; height: 100%; width: 256px;"
>
<div
class="ant-drawer-header"
@ -105,19 +108,20 @@ exports[`Drawer render correctly 1`] = `
class=""
>
<div
class="ant-drawer ant-drawer-left ant-drawer-open"
class="ant-drawer ant-drawer-right ant-drawer-open"
>
<div
class="ant-drawer-mask"
/>
<div
class="ant-drawer-content-wrapper"
style=""
>
<div
class="ant-drawer-content"
>
<div
style="width: 400px;"
style="overflow: auto; height: 100%; width: 400px;"
>
<button
aria-label="Close"

View File

@ -14,19 +14,20 @@ exports[`Drawer render correctly 1`] = `
class=""
>
<div
class="ant-drawer ant-drawer-left ant-drawer-open"
class="ant-drawer ant-drawer-right ant-drawer-open"
>
<div
class="ant-drawer-mask"
/>
<div
class="ant-drawer-content-wrapper"
style=""
>
<div
class="ant-drawer-content"
>
<div
style="width: 256px;"
style="overflow: auto; height: 100%; width: 256px;"
>
<button
aria-label="Close"

View File

@ -21,7 +21,7 @@ const vegetables = ['asparagus', 'bamboo', 'potato', 'carrot', 'cilantro', 'pota
const TagList = ({ value, show }) => {
return (
<div>
{value.map(item => <Tag>{item}</Tag>)}
{value.map(item => <Tag key={item}>{item}</Tag>)}
<Tag onClick={() => show()}>+</Tag>
</div>
);
@ -61,8 +61,8 @@ class DrawerForm extends React.Component {
width={520}
closable={false}
onClose={this.onClose}
wrapperClassName="cookbook"
visible={this.state.visible}
push={this.state.childrenDrawer}
>
<Form hideRequiredMark>
<Form.Item label="Name">
@ -81,11 +81,8 @@ class DrawerForm extends React.Component {
title="Food"
width={320}
closable={false}
wrapperClassName="cookbook_children"
onClose={this.onChildrenDrawerClose}
visible={this.state.childrenDrawer}
levelMove={250}
level=".cookbook"
>
<List
size="small"
@ -133,12 +130,4 @@ ReactDOM.render(<App />, mountNode);
#_hj_feedback_container{
display:none
}
.cookbook,.cookbook_children{
position: fixed;
top: 0;
width: 100%;
height: 100%;
z-index: 9999;
pointer-events: none;
}
</style>

View File

@ -1,6 +1,9 @@
import * as React from 'react';
import RcDrawer from 'rc-drawer';
import PropTypes from 'prop-types';
import createReactContext, { Context } from 'create-react-context';
const DrawerContext: Context<Drawer | null> = createReactContext(null);
type EventType =
| React.MouseEvent<HTMLDivElement>
@ -22,22 +25,25 @@ export interface DrawerProps {
wrapClassName?: string;
zIndex?: number;
prefixCls?: string;
push?: boolean;
placement?: 'left' | 'right';
onClose?: (e: EventType) => void;
}
export interface IDrawerState {
visible?: boolean;
push?: boolean;
}
export default class Drawer extends React.Component<
DrawerProps,
IDrawerState
> {
export default class Drawer extends React.Component<DrawerProps, IDrawerState> {
static propTypes = {
closable: PropTypes.bool,
destroyOnClose: PropTypes.bool,
getContainer: PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.func, PropTypes.bool]),
getContainer: PropTypes.oneOfType([
PropTypes.string,
PropTypes.object,
PropTypes.func,
PropTypes.bool,
]),
maskClosable: PropTypes.bool,
mask: PropTypes.bool,
maskStyle: PropTypes.object,
@ -61,6 +67,20 @@ export default class Drawer extends React.Component<
level: null,
};
readonly state = {
push: false,
};
praentDrawer: Drawer;
public componentDidUpdate(preProps: DrawerProps) {
if (preProps.visible !== this.props.visible && this.praentDrawer) {
if (this.props.visible) {
this.praentDrawer.push();
} else {
this.praentDrawer.pull();
}
}
}
close = (e: EventType) => {
if (this.props.visible !== undefined) {
if (this.props.onClose) {
@ -69,16 +89,24 @@ export default class Drawer extends React.Component<
return;
}
}
onMaskClick = (e: EventType) => {
if (!this.props.maskClosable) {
return;
}
this.close(e);
}
push = () => {
this.setState({
push: true,
});
}
pull = () => {
this.setState({
push: false,
});
}
renderBody = () => {
const { destroyOnClose , visible, width, placement } = this.props;
const { destroyOnClose, visible, width, placement } = this.props;
if (destroyOnClose && !visible) {
return null;
}
@ -121,24 +149,37 @@ export default class Drawer extends React.Component<
</div>
);
}
render() {
let { width, zIndex, style, ...rest } = this.props;
renderProvider = (value: Drawer) => {
let { width, zIndex, style, placement, ...rest } = this.props;
if (typeof width === 'number') {
width = `${width}px`;
}
const RcDrawerStyle = this.state.push
? {
zIndex,
transform: `translateX(${placement === 'left' ? 180 : -180}px)`,
}
: { zIndex };
this.praentDrawer = value;
return (
<RcDrawer
{...rest}
handler={false}
open={this.props.visible}
onMaskClick={this.onMaskClick}
showMask={this.props.mask}
placement={this.props.placement}
style={{ zIndex }}
>
{this.renderBody()}
</RcDrawer>
<DrawerContext.Provider value={this}>
<RcDrawer
{...rest}
handler={false}
open={this.props.visible}
onMaskClick={this.onMaskClick}
showMask={this.props.mask}
placement={placement}
style={RcDrawerStyle}
>
{this.renderBody()}
</RcDrawer>
</DrawerContext.Provider>
);
}
render() {
return (
<DrawerContext.Consumer>{this.renderProvider}</DrawerContext.Consumer>
);
}
}

View File

@ -8,7 +8,8 @@
width: 100%;
height: 100%;
pointer-events: none;
z-index: 99;
z-index: 99999;
transition: transform .3s @ease-in-out-circ;
>* {
transition: transform .3s @ease-in-out-circ;
}

View File

@ -43,6 +43,7 @@
"babel-runtime": "6.x",
"classnames": "~2.2.0",
"create-react-class": "^15.6.0",
"create-react-context": "^0.2.2",
"css-animation": "^1.2.5",
"dom-closest": "^0.2.0",
"enquire.js": "^2.1.1",
@ -131,7 +132,7 @@
"glob": "^7.1.1",
"immutability-helper": "^2.5.0",
"intersection-observer": "^0.5.0",
"jest": "^23.0.0",
"jest": "^23.2.0",
"jsdom": "~11.10.0",
"jsonml.js": "^0.1.0",
"lint-staged": "^7.0.0",

View File

@ -0,0 +1,3 @@
import createReactContext from 'create-react-context/lib/implementation';
export default createReactContext;