@@ -6,6 +6,10 @@ import View from '../view';
6
6
import Button , { ButtonProps } from '../button' ;
7
7
import Image from '../image' ;
8
8
9
+ export enum FloatingButtonLayouts {
10
+ VERTICAL = 'Vertical' ,
11
+ HORIZONTAL = 'Horizontal'
12
+ }
9
13
export interface FloatingButtonProps {
10
14
/**
11
15
* Whether the button is visible
@@ -42,6 +46,10 @@ export interface FloatingButtonProps {
42
46
* <TestID>.secondaryButton - the floatingButton secondaryButton
43
47
*/
44
48
testID ?: string ;
49
+ /**
50
+ * Button layout direction: vertical or horizontal
51
+ */
52
+ buttonLayout ?: FloatingButtonLayouts ;
45
53
}
46
54
47
55
const gradientImage = ( ) => require ( './gradient.png' ) ;
@@ -54,9 +62,11 @@ const gradientImage = () => require('./gradient.png');
54
62
*/
55
63
class FloatingButton extends PureComponent < FloatingButtonProps > {
56
64
static displayName = 'FloatingButton' ;
65
+ static floatingButtonLayouts = FloatingButtonLayouts ;
57
66
58
67
static defaultProps = {
59
- duration : 300
68
+ duration : 300 ,
69
+ buttonLayout : FloatingButtonLayouts . VERTICAL
60
70
} ;
61
71
62
72
initialVisibility ?: boolean ;
@@ -86,21 +96,39 @@ class FloatingButton extends PureComponent<FloatingButtonProps> {
86
96
getAnimatedStyle = ( ) => {
87
97
return {
88
98
opacity : this . visibleAnimated ,
89
- transform : [ { translateY : this . visibleAnimated . interpolate ( {
90
- inputRange : [ 0 , 1 ] ,
91
- outputRange : [ Constants . screenHeight / 2 , 0 ]
92
- } ) } ]
99
+ transform : [
100
+ {
101
+ translateY : this . visibleAnimated . interpolate ( {
102
+ inputRange : [ 0 , 1 ] ,
103
+ outputRange : [ Constants . screenHeight / 2 , 0 ]
104
+ } )
105
+ }
106
+ ]
93
107
} ;
108
+ } ;
109
+
110
+ get isSecondaryHorizontal ( ) {
111
+ const { secondaryButton, buttonLayout} = this . props ;
112
+ return secondaryButton && buttonLayout === FloatingButtonLayouts . HORIZONTAL ;
113
+ }
114
+
115
+ get isSecondaryVertical ( ) {
116
+ const { secondaryButton, buttonLayout} = this . props ;
117
+ return secondaryButton && buttonLayout === FloatingButtonLayouts . VERTICAL ;
94
118
}
95
119
96
120
renderButton ( ) {
97
- const { bottomMargin, button, secondaryButton, testID} = this . props ;
98
- const bottom = secondaryButton ? Spacings . s4 : bottomMargin || Spacings . s8 ;
121
+ const { bottomMargin, button, testID} = this . props ;
122
+
123
+ const bottom = this . isSecondaryVertical ? Spacings . s4 : bottomMargin || Spacings . s8 ;
124
+ const left = this . isSecondaryHorizontal ? Spacings . s4 : undefined ;
125
+ const right = this . isSecondaryHorizontal ? 20 : undefined ;
99
126
100
127
return (
101
128
< Button
102
129
size = { Button . sizes . large }
103
- style = { [ styles . shadow , { marginTop : 16 , marginBottom : bottom } ] }
130
+ flex = { ! ! this . isSecondaryHorizontal }
131
+ style = { [ styles . shadow , { marginTop : 16 , marginBottom : bottom , marginLeft : left , marginRight : right } ] }
104
132
testID = { `${ testID } .button` }
105
133
{ ...button }
106
134
/>
@@ -123,7 +151,23 @@ class FloatingButton extends PureComponent<FloatingButtonProps> {
123
151
} ;
124
152
125
153
renderSecondaryButton ( ) {
126
- const { secondaryButton, bottomMargin, testID} = this . props ;
154
+ const { secondaryButton, bottomMargin, testID, buttonLayout} = this . props ;
155
+
156
+ const bgColor = secondaryButton ?. backgroundColor || Colors . $backgroundDefault ;
157
+
158
+ if ( buttonLayout === FloatingButtonLayouts . HORIZONTAL ) {
159
+ return (
160
+ < Button
161
+ outline
162
+ flex
163
+ size = { Button . sizes . large }
164
+ testID = { `${ testID } .secondaryButton` }
165
+ { ...secondaryButton }
166
+ style = { [ styles . shadow , styles . secondaryMargin , { backgroundColor : bgColor } ] }
167
+ enableShadow = { false }
168
+ />
169
+ ) ;
170
+ }
127
171
128
172
return (
129
173
< Button
@@ -138,9 +182,9 @@ class FloatingButton extends PureComponent<FloatingButtonProps> {
138
182
}
139
183
140
184
render ( ) {
141
- const { withoutAnimation, secondaryButton , visible, testID} = this . props ;
185
+ const { withoutAnimation, visible, testID} = this . props ;
142
186
// NOTE: keep this.firstLoad as true as long as the visibility changed to true
143
- this . firstLoad && ! visible ? this . firstLoad = true : this . firstLoad = false ;
187
+ this . firstLoad && ! visible ? ( this . firstLoad = true ) : ( this . firstLoad = false ) ;
144
188
145
189
// NOTE: On first load, don't show if it should not be visible
146
190
if ( this . firstLoad === true && ! this . initialVisibility ) {
@@ -152,14 +196,17 @@ class FloatingButton extends PureComponent<FloatingButtonProps> {
152
196
153
197
return (
154
198
< View
199
+ row = { ! ! this . isSecondaryHorizontal }
200
+ center = { ! ! this . isSecondaryHorizontal }
155
201
pointerEvents = "box-none"
156
202
animated
157
203
style = { [ styles . container , this . getAnimatedStyle ( ) ] }
158
204
testID = { testID }
159
205
>
160
206
{ this . renderOverlay ( ) }
207
+ { this . isSecondaryHorizontal && this . renderSecondaryButton ( ) }
161
208
{ this . renderButton ( ) }
162
- { secondaryButton && this . renderSecondaryButton ( ) }
209
+ { this . isSecondaryVertical && this . renderSecondaryButton ( ) }
163
210
</ View >
164
211
) ;
165
212
}
@@ -183,7 +230,12 @@ const styles = StyleSheet.create({
183
230
shadowOpacity : 0.35 ,
184
231
shadowRadius : 12 ,
185
232
elevation : 2
233
+ } ,
234
+ secondaryMargin : {
235
+ marginTop : Spacings . s4 ,
236
+ marginBottom : Spacings . s7 ,
237
+ marginLeft : 20
186
238
}
187
239
} ) ;
188
240
189
- export default asBaseComponent < FloatingButtonProps > ( FloatingButton ) ;
241
+ export default asBaseComponent < FloatingButtonProps , typeof FloatingButton > ( FloatingButton ) ;
0 commit comments