simple demo

This commit is contained in:
jim 2018-05-23 10:56:37 +08:00 committed by 陈帅
parent cbbe4035e2
commit 61a7731270
11 changed files with 488 additions and 29 deletions

View File

@ -0,0 +1,53 @@
---
order: 0
title:
zh-CN: 基本
en-US: Basic
---
## zh-CN
第一个对话框。
## en-US
Basic modal.
```jsx
import { Drawer, Button } from 'antd';
class App extends React.Component {
state = { visible: false };
showDrawer = () => {
this.setState({
visible: true,
});
};
onClose = () => {
this.setState({
visible: false,
});
};
render() {
return (
<div>
<Button type="primary" onClick={this.showDrawer}>
Open
</Button>
<Drawer
title="Basic Drawer"
width={400}
onClose={this.onClose}
visible={this.state.visible}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
</div>
);
}
}
ReactDOM.render(<App />, mountNode);
```

View File

@ -0,0 +1,32 @@
---
type: Feedback
category: Components
subtitle: Drawer
title: Drawer
---
Drawer container
## When To Use
## API
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| closable | Whether a close (x) button is visible on top right of the Drawer dialog or not | boolean | true |
| destroyOnClose | Whether to unmount child compenents on onClose | boolean | false |
| getContainer | Return the mount node for Drawer | (instance): HTMLElement | () => document.body |
| mask | Whether show mask or not. | Boolean | true |
| maskClosable | Whether to close the Drawer dialog when the mask (area outside the Drawer) is clicked | boolean | true |
| maskStyle | Style for Drawer's mask element. | object | {} |
| style | Style of floating layer, typically used at least for adjusting the position. | object | - |
| title | The Drawer dialog's title | string\|ReactNode | - |
| visible | Whether the Drawer dialog is visible or not | boolean | false |
| width | Width of the Drawer dialog | string\|number | 520 |
| wrapClassName | The class name of the container of the Drawer dialog | string | - |
| zIndex | The `z-index` of the Drawer | Number | 1000 |
| placement | The direction of the Drawer | 'left' | 'right' | 'left'
| onClose | Specify a function that will be called when a user clicks mask, close button on top right or Cancel button | function(e) | - |

View File

@ -1,28 +0,0 @@
---
category: Components
type: Other
title: Drawer
subtitle: 抽屉
---
## API
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| className | 抽屉的类属性 | string | `drawer` |
| openClassName | 打开抽屉时的类属性 | string | `drawer-open`|
| bodyStyle | Drawer 面板 样式 | object | {} |
| mask | 是否展示遮罩 | Boolean | true |
| maskClosable | 点击蒙层是否允许关闭 | boolean | true |
| maskStyle | 遮罩样式 | object | {} |
| showIcon | 是否显示抽屉的 icon | boolean | true |
| icon | 抽屉的 icon | ReactNode | node |
| visible | 抽屉是否可见 | boolean | false |
| getContainer | 指定 抽屉挂载节点 | (instance)=> HTMLElement | `body` |
| width | 抽屉的宽度 | string | `60vw` |
| placement | 抽屉的方向 | `left``right` | `left` |
| onChange | 面板状态改变事件 | (state:boolean)=>void | null |
| onIconClick | icon 点击事件 | (e:event)=>void | null
| destroyOnClose | 关闭时销毁 Drawer 里的子元素 | boolean | false |

120
components/drawer/index.tsx Normal file
View File

@ -0,0 +1,120 @@
import * as React from 'react';
import RcDrawer from 'rc-drawer-menu';
import { isNull } from 'util';
type EventType =
| React.MouseEvent<HTMLDivElement>
| React.MouseEvent<HTMLButtonElement>;
export interface IDrawerProps {
closable?: boolean;
// @todo 下一步增加
destroyOnClose?: boolean;
getContainer?: HTMLElement;
maskClosable?: boolean;
mask?: boolean;
maskStyle?: React.CSSProperties;
style?: React.CSSProperties;
title?: React.ReactNode;
visible?: boolean;
width?: number | string;
wrapClassName?: string;
// @todo 下一步增加
zIndex?: number;
prefixCls?: string;
placement?: 'left' | 'right' ;
onClose?: (e: EventType) => void;
}
export interface IDrawerState {
visible?: boolean;
}
export default class Drawer extends React.Component<
IDrawerProps,
IDrawerState
> {
static defaultProps = {
prefixCls: 'ant-drawer',
width: 325,
closable: true,
};
static getDerivedStateFromProps(
nextProps: IDrawerProps,
prevState: IDrawerState,
) {
const nextState: IDrawerState = {};
if (!isNull(nextProps.visible) && nextProps.visible !== prevState.visible) {
nextState.visible = nextProps.visible;
}
return nextState;
}
constructor(props: IDrawerProps) {
super(props);
this.state = {
visible: false,
};
}
close = (e: EventType) => {
if (!isNull(this.props.visible)) {
if (this.props.onClose) {
this.props.onClose(e);
}
return;
}
this.setState({
visible: false,
});
}
onMaskClick = (e: EventType) => {
if (!this.props.maskClosable) {
return;
}
this.close(e);
}
renderBody = () => {
const { prefixCls, title, closable } = this.props;
let header;
if (title) {
header = (
<div className={`${prefixCls}-header`}>
<div className={`${prefixCls}-title`}>{title}</div>
</div>
);
}
let closer;
if (closable) {
closer = (
<button
onClick={this.close}
aria-label="Close"
className={`${prefixCls}-close`}
>
<span className={`${prefixCls}-close-x`} />
</button>
);
}
const containerStyle = { width: this.props.width };
return (
<div style={containerStyle} >
{header}
{closer}
<div className={`${prefixCls}-body`} style={this.props.style}>{this.props.children}</div>;
</div >
);
}
render() {
return (
<RcDrawer
{...this.props}
handleChild={false}
open={this.state.visible}
onMaskClick={this.close}
showMask={this.props.mask}
placement={this.props.placement}
>
{this.renderBody()}
</RcDrawer>
);
}
}

View File

@ -0,0 +1,32 @@
---
type: Feedback
category: Components
subtitle: 抽屉
title: Drawer
---
抽屉容器
## 何时使用
## API
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| closable | 是否显示右上角的关闭按钮 | boolean | true |
| destroyOnClose | 关闭时销毁 Drawer 里的子元素 | boolean | false |
| getContainer | 指定 Drawer 挂载的 HTML 节点 | (instance): HTMLElement | () => document.body |
| maskClosable | 点击蒙层是否允许关闭 | boolean | true |
| mask | 是否展示遮罩 | Boolean | true |
| maskStyle | 遮罩样式 | object | {} |
| style | 可用于设置 Drawer 的样式,调整浮层位置等 | object | - |
| title | 标题 | string\|ReactNode | 无 |
| visible | Drawer 是否可见 | boolean | 无 |
| width | 宽度 | string\|number | 325 |
| wrapClassName | 对话框外层容器的类名 | string | - |
| zIndex | 设置 Drawer 的 `z-index` | Number | 1000 |
| placement | 抽屉的方向 | 'left' | 'right' | 'left'
| onClose | 点击遮罩层或右上角叉或取消按钮的回调 | function(e) | 无 |

View File

@ -0,0 +1,237 @@
@dawer-prefix-cls: ~"@{ant-prefix}-drawer";
.@{dawer-prefix-cls} {
position: fixed;
top: 0;
width: 100%;
height: 100%;
pointer-events: none;
&-content-wrapper {
position: absolute;
z-index: @zindex-modal-mask + 1;
}
&-left,
&-right {
.@{dawer-prefix-cls}-content-wrapper,
.@{dawer-prefix-cls}-content {
height: 100%;
}
}
&-left {
.@{dawer-prefix-cls} {
&-handle {
right: -40px;
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);
border-radius: 0 4px 4px 0;
}
}
&.@{dawer-prefix-cls}-open {
.@{dawer-prefix-cls} {
&-wrapper {
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);
}
}
}
}
&-right {
.@{dawer-prefix-cls} {
&-content-wrapper {
right: 0;
}
&-handle {
left: -40px;
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);
border-radius: 4px 0 0 4px;
}
}
&.@{dawer-prefix-cls}-open {
& .@{dawer-prefix-cls} {
&-wrapper {
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);
}
}
}
}
&-top,
&-bottom {
.@{dawer-prefix-cls}-content-wrapper,
.@{dawer-prefix-cls}-content {
width: 100%;
}
.@{dawer-prefix-cls} {
&-handle {
left: 50%;
margin-left: -20px;
}
}
}
&-top {
.@{dawer-prefix-cls} {
&-handle {
top: auto;
bottom: -40px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
border-radius: 0 0 4px 4px;
}
}
&.@{dawer-prefix-cls}-open {
.@{dawer-prefix-cls} {
&-wrapper {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
}
}
}
&-bottom {
.@{dawer-prefix-cls} {
&-content-wrapper {
bottom: 0;
}
&-handle {
top: -40px;
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.15);
border-radius: 4px 4px 0 0;
}
}
&.@{dawer-prefix-cls}-open {
.@{dawer-prefix-cls} {
&-wrapper {
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.15);
}
}
}
}
&.@{dawer-prefix-cls}-open {
> * {
pointer-events: auto;
}
.@{dawer-prefix-cls} {
&-mask {
opacity: 0.3;
display: block;
}
&-handle {
&-icon {
background: transparent;
&:before {
transform: translateY(5px) rotate(45deg);
}
&:after {
transform: translateY(-5px) rotate(-45deg);
}
}
}
}
}
&-title {
margin: 0;
font-size: @font-size-lg;
line-height: 22px;
font-weight: 500;
color: @heading-color;
}
&-content {
position: relative;
background-color: @component-background;
border: 0;
background-clip: padding-box;
box-shadow: @shadow-2;
}
&-close {
cursor: pointer;
border: 0;
background: transparent;
position: absolute;
right: 0;
top: 0;
z-index: 10;
font-weight: 700;
line-height: 1;
text-decoration: none;
transition: color 0.3s;
color: @text-color-secondary;
outline: 0;
padding: 0;
&-x {
display: block;
font-style: normal;
text-align: center;
text-transform: none;
text-rendering: auto;
width: 56px;
height: 56px;
line-height: 56px;
font-size: @font-size-lg;
&:before {
content: "\e633";
display: block;
font-family: "anticon" !important;
}
}
&:focus,
&:hover {
color: #444;
text-decoration: none;
}
}
&-header {
padding: 16px 24px;
border-radius: @border-radius-base @border-radius-base 0 0;
background: @component-background;
color: @text-color;
border-bottom: @border-width-base @border-style-base @border-color-split;
}
&-body {
padding: 24px;
font-size: @font-size-base;
line-height: @line-height-base;
word-wrap: break-word;
}
&.zoom-enter,
&.zoom-appear {
animation-duration: @animation-duration-slow;
transform: none; // reset scale avoid mousePosition bug
opacity: 0;
}
&-mask {
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0;
display: none;
background-color: #373737;
background-color: @modal-mask-bg; // lesshint duplicateProperty: false
height: 100%;
z-index: @zindex-modal-mask;
filter: ~"alpha(opacity=50)";
}
&-open {
overflow: hidden;
}
}
@media (max-width: @screen-md) {
.@{dawer-prefix-cls} {
width: auto !important;
margin: 10px;
}
.vertical-center-modal {
.@{dawer-prefix-cls} {
flex: 1;
}
}
}

View File

@ -0,0 +1,4 @@
@import "../../style/themes/default";
@import "../../style/mixins/index";
@import "./drawer";

View File

@ -0,0 +1,5 @@
import '../../style/index.less';
import './index.less';
// style dependencies
import '../../button/style';

View File

@ -51,6 +51,8 @@ export { default as Divider } from './divider';
export { default as Dropdown } from './dropdown';
export { default as Drawer } from './drawer';
export { default as Form } from './form';
export { default as Icon } from './icon';

View File

@ -143,7 +143,7 @@
"preact": "^8.2.5",
"preact-compat": "^3.17.0",
"querystring": "^0.2.0",
"rc-drawer-menu": "^0.5.3",
"rc-drawer-menu": "^1.0.2",
"rc-queue-anim": "^1.4.1",
"rc-scroll-anim": "^2.2.1",
"rc-tween-one": "^2.0.1",

View File

@ -40,6 +40,8 @@ declare module 'rc-progress';
declare module 'rc-menu';
declare module 'rc-drawer-menu';
declare module 'rc-tabs*';
declare module 'rc-tree';