UNPKG

4.41 kBJSXView Raw
1/**
2 * Dialog component.
3 * @constructor ApDialog
4 */
5
6'use strict'
7
8
9import React, {PropTypes as types} from 'react'
10import classnames from 'classnames'
11
12import {ApTouchable} from 'apeman-react-touchable'
13import {ApIcon} from 'apeman-react-icon'
14import {ApSpinner} from 'apeman-react-spinner'
15import ApDialogHeader from './ap_dialog_header'
16import ApDialogBody from './ap_dialog_body'
17
18
19const DEFAULT_CLOSE_ICON = 'fa fa-close'
20
21/** @lends ApDialog */
22let ApDialog = React.createClass({
23
24 // --------------------
25 // Specs
26 // --------------------
27
28 propTypes: {
29 present: types.bool.isRequired,
30 onClose: types.func,
31 spinning: types.bool,
32 spinner: types.string,
33 title: types.string,
34 closeIcon: types.string
35 },
36
37 mixins: [],
38
39 statics: {
40 DEFAULT_CLOSE_ICON
41 },
42
43 getInitialState () {
44 return {}
45 },
46
47 getDefaultProps () {
48 return {
49 present: false,
50 onClose: null,
51 spinning: false,
52 spinner: ApSpinner.DEFAULT_THEME,
53 title: null,
54 closeIcon: DEFAULT_CLOSE_ICON
55 }
56 },
57
58 render () {
59 const s = this,
60 {props} = s;
61 if (!props.present) {
62 return null;
63 }
64 return (
65 <div className={ classnames('ap-dialog', props.className, {
66 'ap-dialog-present':props.present
67 }) }
68 style={ Object.assign({}, props.style) }>
69 <ApSpinner theme={ props.spinner }
70 className="ap-dialog-spinner"
71 enabled={ props.spinning }/>
72 <div className="ap-dialog-inner">
73 { s._renderBack() }
74 <div className="ap-dialog-content">
75 <ApDialogHeader>
76 { s._renderTitle() }
77 { s._renderCloseButton() }
78 </ApDialogHeader>
79 <ApDialogBody>
80 { props.children }
81 </ApDialogBody>
82 </div>
83 </div>
84 </div>
85 )
86 },
87
88
89 // --------------------
90 // Lifecycle
91 // --------------------
92
93 componentWillMount() {
94 const s = this
95
96 },
97
98 componentDidMount() {
99 const s = this,
100 {props} = s;
101 s.toggleDocumentScroll(props.present)
102 },
103
104 componentWillReceiveProps(nextProps) {
105 const s = this
106
107 s.toggleDocumentScroll(nextProps.present)
108 },
109
110 shouldComponentUpdate(nextProps, nextState) {
111 const s = this
112 return true
113 },
114
115 componentWillUpdate(nextProps, nextState) {
116 const s = this
117 },
118
119 componentDidUpdate(prevProps, prevState) {
120 const s = this
121 },
122
123 componentWillUnmount() {
124 const s = this
125 s.toggleDocumentScroll(false)
126 },
127
128 // ------------------
129 // Helper
130 // ------------------
131
132 handleClose(e) {
133 const s = this,
134 {props} = s;
135 if (props.onClose) {
136 props.onClose(e)
137 }
138 },
139
140 toggleDocumentScroll(enabled) {
141 let s = false
142
143 let body = document.body;
144 if (enabled) {
145 body.classList.add('ap-dialog-fix')
146 } else {
147 body.classList.remove('ap-dialog-fix')
148 }
149
150 },
151
152 // ------------------
153 // Private
154 // ------------------
155
156 _renderBack() {
157 const s = this,
158 {props} = s;
159 return (
160 <div className="ap-dialog-back">
161 <ApTouchable onTap={ s.handleClose }>
162 <div className="ap-dialog-back-inner"></div>
163 </ApTouchable>
164 </div>
165 )
166 },
167
168 _renderCloseButton() {
169 const s = this,
170 {props} = s;
171 return (
172 <a className="ap-dialog-close-button">
173 <ApTouchable onTap={ s.handleClose }>
174 <span>
175 <ApIcon className={ classnames('ap-dialog-close-button-icon', props.closeIcon) }/>
176 </span>
177 </ApTouchable>
178 </a>
179 )
180 },
181
182 _renderTitle() {
183 const s = this,
184 {props} = s;
185 return (
186 <h3 className="ap-dialog-title">{ props.title }</h3>
187 )
188 }
189})
190
191module.exports = ApDialog;
\No newline at end of file