-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d75ed28
commit f139bb6
Showing
14 changed files
with
1,424 additions
and
32 deletions.
There are no files selected for viewing
636 changes: 636 additions & 0 deletions
636
components/drawer/__tests__/__snapshots__/index.test.js.snap
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import React from 'react'; | ||
import { render, shallow, mount } from 'enzyme'; | ||
import assert from 'power-assert'; | ||
import toJson from 'enzyme-to-json'; | ||
import Drawer from '../index'; | ||
|
||
describe('<Drawer/>', () => { | ||
it('should render a <Drawer/> components', () => { | ||
const wrapper = render( | ||
<div> | ||
<Drawer title="基本使用" visible> | ||
<span>基本使用</span> | ||
</Drawer> | ||
<Drawer title="基本使用" visible width={500}> | ||
<span>无 footer</span> | ||
</Drawer> | ||
<Drawer title="基本使用" visible width={500} zIndex={9999}> | ||
<span>无 footer</span> | ||
</Drawer> | ||
</div> | ||
); | ||
expect(toJson(wrapper)).toMatchSnapshot(); | ||
}); | ||
|
||
it('should can not clicked with set maskClosable false', () => { | ||
const onCancelClick = jest.fn(); | ||
const wrapper = mount( | ||
<Drawer visible={true} onCancel={onCancelClick}> | ||
<span>关闭回调</span> | ||
</Drawer> | ||
); | ||
wrapper.find('.cuke-drawer').simulate('click'); | ||
assert(wrapper.props().visible === true); | ||
expect(onCancelClick).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should render custom direction', () => { | ||
const wrapper = mount( | ||
<div> | ||
<Drawer visible placement="left"> | ||
<span>关闭回调</span> | ||
</Drawer> | ||
<Drawer visible placement="top"> | ||
<span>关闭回调</span> | ||
</Drawer> | ||
<Drawer visible placement="right"> | ||
<span>关闭回调</span> | ||
</Drawer> | ||
<Drawer visible placement="bottom"> | ||
<span>关闭回调</span> | ||
</Drawer> | ||
</div> | ||
); | ||
expect(toJson(wrapper)).toMatchSnapshot(); | ||
}); | ||
|
||
it('should can trigger onClose event', () => { | ||
const onCancelClick = jest.fn(); | ||
const wrapper = shallow( | ||
<Drawer title="关闭回调" visible onClose={onCancelClick}> | ||
<span>关闭回调</span> | ||
</Drawer> | ||
); | ||
wrapper.find('.cuke-drawer').simulate('click'); | ||
expect(onCancelClick).not.toHaveBeenCalled(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import React, { PureComponent, Fragment } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { createPortal } from 'react-dom'; //传送门 将节点挂载在root 节点之外 | ||
import cls from 'classnames'; | ||
import { CloseIcon } from '../icon'; | ||
|
||
const placements = ['right', 'top', 'bottom', 'left']; | ||
export default class Drawer extends PureComponent { | ||
state = { | ||
init: false | ||
}; | ||
static defaultProps = { | ||
prefixCls: 'cuke-drawer', | ||
visible: false, | ||
getTargetAtNode: () => document.body, | ||
title: '', | ||
onClose: () => {}, | ||
maskClosable: true, | ||
closable: true, | ||
showMask: true, | ||
width: 300, | ||
zIndex: 999, | ||
placement: placements[0] | ||
}; | ||
static propTypes = { | ||
title: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), | ||
content: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), | ||
confirmLoading: PropTypes.bool, | ||
visible: PropTypes.bool, | ||
closable: PropTypes.bool, | ||
maskClosable: PropTypes.bool, | ||
showMask: PropTypes.bool, | ||
zIndex: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), | ||
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), | ||
placement: PropTypes.oneOf(placements), | ||
getTargetAtNode: PropTypes.func, | ||
onClose: PropTypes.func | ||
}; | ||
constructor(props) { | ||
super(props); | ||
} | ||
disableScroll = () => { | ||
document.body.style.overflow = 'hidden'; | ||
//滚动条的宽度 防止鬼畜 | ||
document.body.style.paddingRight = '15px'; | ||
}; | ||
enableScroll = () => { | ||
document.body.style.overflow = ''; | ||
document.body.style.paddingRight = 0; | ||
}; | ||
componentWillReceiveProps({ visible }) { | ||
if (visible === true) { | ||
this.disableScroll(); | ||
this.setState({ | ||
init: true | ||
}); | ||
} else { | ||
this.enableScroll(); | ||
} | ||
} | ||
render() { | ||
const { | ||
prefixCls, | ||
children, | ||
title, | ||
visible, | ||
onClose, | ||
className, | ||
getTargetAtNode, | ||
closable, | ||
maskClosable, | ||
showMask, | ||
width, | ||
zIndex, | ||
placement, | ||
style, | ||
...attr | ||
} = this.props; | ||
|
||
const { init } = this.state; | ||
|
||
const initModalAnimate = init | ||
? { [`${prefixCls}-open`]: visible, [`${prefixCls}-close`]: !visible } | ||
: { [`${prefixCls}-open`]: visible }; | ||
|
||
const initMaskAnimate = init | ||
? { | ||
[`${prefixCls}-mask-show`]: visible, | ||
[`${prefixCls}-mask-hide`]: !visible | ||
} | ||
: { [`${prefixCls}-mask-show`]: visible }; | ||
|
||
const maskClickHandle = maskClosable ? { onClick: onClose } : {}; | ||
|
||
return createPortal( | ||
<Fragment> | ||
{showMask ? ( | ||
<div | ||
className={cls(`${prefixCls}-mask`, initMaskAnimate)} | ||
{...maskClickHandle} | ||
/> | ||
) : ( | ||
undefined | ||
)} | ||
<div role="dialog" tabIndex="-1" className={cls(`${prefixCls}-wrap`)}> | ||
<div | ||
className={cls( | ||
prefixCls, | ||
className, | ||
initModalAnimate, | ||
`${prefixCls}-${placement}` | ||
)} | ||
ref={node => (this.modal = node)} | ||
style={{ | ||
...style, | ||
width, | ||
zIndex | ||
}} | ||
{...attr} | ||
> | ||
<section className={`${prefixCls}-header`}> | ||
<h2 className={`${prefixCls}-title`}>{title}</h2> | ||
{closable ? ( | ||
<CloseIcon className={`${prefixCls}-close`} onClick={onClose} /> | ||
) : ( | ||
undefined | ||
)} | ||
</section> | ||
<section className={`${prefixCls}-content`}>{children}</section> | ||
</div> | ||
</div> | ||
</Fragment>, | ||
getTargetAtNode() | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
@import "../styles/vars.less"; | ||
@import "../styles/animate.less"; | ||
@import "../styles/mixins.less"; | ||
|
||
@prefixCls : cuke-drawer; | ||
|
||
.@{prefixCls}{ | ||
pointer-events: auto; | ||
background-color: @modal-bg-color; | ||
z-index:@modal-z-index; | ||
transform-origin: bottom center; | ||
outline: none; | ||
position: relative; | ||
padding:0; | ||
width: @cuke-drawer-width; | ||
height: 100%; | ||
list-style:none; | ||
transform: scale(0); | ||
|
||
&.@{prefixCls}-open{ | ||
pointer-events: auto; | ||
} | ||
&.@{prefixCls}-close{ | ||
pointer-events: none; | ||
} | ||
|
||
&-left { | ||
top:0; | ||
left:0; | ||
&.@{prefixCls}-open{ | ||
animation: cuke-drawer-slide-in-left @cuke-drawer-animate-type forwards; | ||
} | ||
&.@{prefixCls}-close{ | ||
animation: cuke-drawer-slide-out-left @cuke-drawer-animate-type forwards; | ||
} | ||
} | ||
|
||
&-right { | ||
top:0; | ||
right:-100%; | ||
&.@{prefixCls}-open{ | ||
animation: cuke-drawer-slide-in-right @cuke-drawer-animate-type forwards; | ||
} | ||
&.@{prefixCls}-close{ | ||
animation: cuke-drawer-slide-out-right @cuke-drawer-animate-type forwards; | ||
} | ||
} | ||
|
||
&-top { | ||
top:0; | ||
left:0; | ||
width:100% !important; | ||
height: @cuke-drawer-height; | ||
&.@{prefixCls}-open{ | ||
animation: cuke-drawer-slide-in-top @cuke-drawer-animate-type forwards; | ||
} | ||
&.@{prefixCls}-close{ | ||
animation: cuke-drawer-slide-out-top @cuke-drawer-animate-type forwards; | ||
} | ||
} | ||
|
||
&-bottom { | ||
bottom:0; | ||
left:0; | ||
width:100% !important; | ||
height: @cuke-drawer-height; | ||
&.@{prefixCls}-open{ | ||
animation: cuke-drawer-slide-in-bottom @cuke-drawer-animate-type forwards; | ||
} | ||
&.@{prefixCls}-close{ | ||
animation: cuke-drawer-slide-out-bottom @cuke-drawer-animate-type forwards; | ||
} | ||
} | ||
|
||
&-header{ | ||
padding: @modal-header-padding; | ||
border-bottom:1px solid @border-color; | ||
line-height: 40px; | ||
text-align: center; | ||
position: relative; | ||
.@{prefixCls}-title{ | ||
font-size: @modal-title-font-size; | ||
color:@font-color; | ||
margin:0; | ||
font-weight:500; | ||
} | ||
.@{prefixCls}-close{ | ||
position: absolute; | ||
right: 20px; | ||
top:13px; | ||
cursor: pointer; | ||
color: @modal-close-font-color; | ||
font-size: @modal-close-font-size; | ||
&,i{ | ||
transition:all .3s @animate-type; | ||
} | ||
&:hover{ | ||
transform: rotate(90deg); | ||
&,i{ | ||
color:@primary-color; | ||
} | ||
} | ||
} | ||
} | ||
&-content{ | ||
padding: @modal-padding; | ||
background-clip: padding-box; | ||
height: auto; | ||
overflow-y: auto; | ||
margin: 0 auto; | ||
line-height: 1.5; | ||
word-wrap: break-word; | ||
max-height: 100vh; | ||
} | ||
} | ||
|
||
.@{prefixCls}-wrap { | ||
position: fixed; | ||
overflow: auto; | ||
left:0; | ||
right:0; | ||
bottom:0; | ||
top:0; | ||
z-index: @modal-z-index; | ||
outline: 0; | ||
pointer-events: none; | ||
-webkit-overflow-scrolling: touch; | ||
} | ||
|
||
.@{prefixCls}-mask{ | ||
position: fixed; | ||
background-color: @modal-mask-color; | ||
left:0; | ||
top:0; | ||
bottom:0; | ||
top:0; | ||
width:100%; | ||
height:100%; | ||
z-index: @modal-z-index; | ||
pointer-events: none; | ||
transform: scale(0); | ||
&-show{ | ||
pointer-events: auto; | ||
animation: cuke-mask-fade-in @default-transition forwards; | ||
} | ||
&-hide { | ||
pointer-events: none; | ||
animation: cuke-mask-fade-out @default-transition forwards; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.