UNPKG

3.37 kBJSXView Raw
1/**
2 * Dropdown component
3 * @class ApDropdown
4 */
5
6'use strict'
7
8import React, {PropTypes as types} from 'react'
9import ReactDOM from 'react-dom'
10import classnames from 'classnames'
11import {ApSpinner} from 'apeman-react-spinner'
12
13import {ApLayoutMixin, ApPureMixin, ApOutsideMixin} from 'apeman-react-mixins'
14import {ApButton} from 'apeman-react-button'
15
16/** @lends ApDropdown */
17const ApDropdown = React.createClass({
18
19 // --------------------
20 // Specs
21 // --------------------
22
23 propTypes: {
24 /** Icon class name for open state */
25 openIcon: types.string,
26 /** Icon class name for closed state */
27 closedIcon: types.string,
28 /** Show spinner */
29 spinning: types.bool,
30 /** Spinner theme */
31 spinner: types.string,
32 /** Open or not */
33 open: types.bool.isRequired,
34 /** Handler for tap event */
35 onTap: types.func.isRequired
36 },
37
38 mixins: [
39 ApLayoutMixin,
40 ApOutsideMixin
41 ],
42
43 statics: {},
44
45 getInitialState () {
46 return {
47 open: false
48 }
49 },
50
51 getDefaultProps () {
52 return {
53 openIcon: 'ion ion-chevron-up',
54 closedIcon: 'ion ion-chevron-down',
55 spinning: false,
56 spinner: ApSpinner.DEFAULT_THEME
57 }
58 },
59
60 render () {
61 const s = this
62 let { state, props, layouts } = s
63
64 return (
65 <div className={ classnames('ap-dropdown', {
66 'ap-dropdown-open': props.open,
67 'ap-dropdown-closed': !props.open
68 }, props.className) }
69 style={ Object.assign({}, props.style) }>
70 { s._renderSpinner() }
71 <div className="ap-dropdown-button-wrap">
72 <ApButton className="ap-dropdown-button" onTap={ s.handleButtonTap }>
73 { props.title }
74 <i className={ classnames('ap-dropdown-icon', props.open ? props.openIcon : props.closedIcon) }/>
75 </ApButton>
76 </div>
77 <div className="ap-dropdown-content" style={ layouts.content }>
78 <div className="ap-dropdown-content-inner"
79 ref={ (inner) => s.registerContentInner(inner) }>
80 { props.children }
81 </div>
82 </div>
83 </div>
84 )
85 },
86
87 // --------------------
88 // Lifecycle
89 // --------------------
90
91 componentWillMount () {
92 const s = this
93 },
94
95 componentDidMount () {
96 const s = this
97 s.layout()
98 },
99
100 // ------------------
101 // For ApLayoutMixin
102 // ------------------
103
104 getInitialLayouts () {
105 return {
106 content: null
107 }
108 },
109
110 calcLayouts () {
111 const s = this
112 let { contentInner } = s
113 let contentRect = contentInner.getBoundingClientRect()
114 return {
115 content: {
116 height: contentRect.height
117 }
118 }
119 },
120
121 // ------------------
122 // Custom
123 // ------------------
124
125 contentInner: null,
126
127 registerContentInner (contentInner) {
128 const s = this
129 s.contentInner = contentInner
130 },
131
132 handleButtonTap (e) {
133 const s = this
134 let { props } = s
135 props.onTap(e)
136 },
137
138 // ------------------
139 // Private
140 // ------------------
141 _renderSpinner () {
142 const s = this
143 let { props } = s
144 if (!props.spinning) {
145 return null
146 }
147 return (
148 <div className="ap-dropdown-spinner-cover">
149 <ApSpinner theme={ props.spinner }
150 className="ap-dropdown-spinner"
151 enabled={ true }/>
152 </div>
153 )
154 }
155})
156
157export default ApDropdown