116 |
117 | | Prop name |
118 | Description |
119 | Type |
120 | Default |
121 |
122 |
123 | | title |
124 | |
125 | PropTypes.string or PropTypes.element |
126 | |
127 |
128 |
129 | | message |
130 | |
131 | PropTypes.string or PropTypes.element |
132 | |
133 |
134 |
135 | | options |
136 | |
137 | PropTypes.arrayOf([PropTypes.string, PropTypes.element]) |
138 | |
139 |
140 |
141 | | tintColor |
142 | |
143 | PropTypes.string |
144 | |
145 |
146 |
147 | | cancelButtonIndex |
148 | |
149 | PropTypes.number |
150 | |
151 |
152 |
153 | | destructiveButtonIndex |
154 | |
155 | PropTypes.number |
156 | |
157 |
158 |
159 | | onPress |
160 | |
161 | PropTypes.func |
162 | (index) => {} |
163 |
164 |
165 | | styles |
166 | only for ActionSheetCustom |
167 | |
168 | {} |
169 |
170 |
171 |
--------------------------------------------------------------------------------
/lib/ActionSheetCustom.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Text, View, Dimensions, Modal, TouchableHighlight, Animated, ScrollView, Easing } from 'react-native'
3 | import * as utils from './utils'
4 | import styles2 from './styles'
5 |
6 | const WARN_COLOR = '#FF3B30'
7 | const MAX_HEIGHT = Dimensions.get('window').height * 0.7
8 |
9 | class ActionSheet extends React.Component {
10 | static defaultProps = {
11 | tintColor: '#007AFF',
12 | buttonUnderlayColor: '#F4F4F4',
13 | onPress: () => {},
14 | styles: {}
15 | }
16 |
17 | constructor (props) {
18 | super(props)
19 | this.scrollEnabled = false
20 | this.translateY = this._calculateHeight(props)
21 | this.state = {
22 | visible: false,
23 | sheetAnim: new Animated.Value(this.translateY)
24 | }
25 | }
26 |
27 | componentWillReceiveProps (nextProps) {
28 | this.translateY = this._calculateHeight(nextProps)
29 | }
30 |
31 | get styles () {
32 | const { styles } = this.props
33 | const obj = {}
34 | Object.keys(styles2).forEach((key) => {
35 | const arr = [styles2[key]]
36 | if (styles[key]) {
37 | arr.push(styles[key])
38 | }
39 | obj[key] = arr
40 | })
41 | return obj
42 | }
43 |
44 | show = () => {
45 | this.setState({visible: true}, () => {
46 | this._showSheet()
47 | })
48 | }
49 |
50 | hide = (index) => {
51 | this._hideSheet(() => {
52 | this.setState({visible: false}, () => {
53 | this.props.onPress(index)
54 | })
55 | })
56 | }
57 |
58 | _cancel = () => {
59 | const { cancelButtonIndex } = this.props
60 | // 保持和 ActionSheetIOS 一致,
61 | // 未设置 cancelButtonIndex 时,点击背景不隐藏 ActionSheet
62 | if (utils.isset(cancelButtonIndex)) {
63 | this.hide(cancelButtonIndex)
64 | }
65 | }
66 |
67 | _showSheet = () => {
68 | Animated.timing(this.state.sheetAnim, {
69 | toValue: 0,
70 | duration: 250,
71 | easing: Easing.out(Easing.ease)
72 | }).start()
73 | }
74 |
75 | _hideSheet (callback) {
76 | Animated.timing(this.state.sheetAnim, {
77 | toValue: this.translateY,
78 | duration: 200
79 | }).start(callback)
80 | }
81 |
82 | /**
83 | * elements: titleBox, messageBox, buttonBox, cancelButtonBox
84 | * box size: height, marginTop, marginBottom
85 | */
86 | _calculateHeight (props) {
87 | const styles = this.styles
88 |
89 | const getHeight = (name) => {
90 | const style = styles[name][styles[name].length - 1]
91 | let h = 0
92 | ;['height', 'marginTop', 'marginBottom'].forEach((attrName) => {
93 | if (typeof style[attrName] !== 'undefined') {
94 | h += style[attrName]
95 | }
96 | })
97 | return h
98 | }
99 |
100 | let height = 0
101 | if (props.title) height += getHeight('titleBox')
102 | if (props.message) height += getHeight('messageBox')
103 | if (utils.isset(props.cancelButtonIndex)) {
104 | height += getHeight('cancelButtonBox')
105 | height += (props.options.length - 1) * getHeight('buttonBox')
106 | } else {
107 | height += props.options.length * getHeight('buttonBox')
108 | }
109 |
110 | if (height > MAX_HEIGHT) {
111 | this.scrollEnabled = true
112 | height = MAX_HEIGHT
113 | } else {
114 | this.scrollEnabled = false
115 | }
116 |
117 | return height
118 | }
119 |
120 | _renderTitle () {
121 | const { title } = this.props
122 | const styles = this.styles
123 | if (!title) return null
124 | return (
125 |