Skip to content

Commit ce7048b

Browse files
authored
Fix/floating button new branch (wix#2255)
* New floating button behaviour * Added buttonLayouts prop for the layout, added the example to the FloatingButton screen * Added bgColor logic to the secondery button, set deafult background to token * Fixed review notes * Fixed review notes
1 parent 029b9bd commit ce7048b

File tree

3 files changed

+89
-21
lines changed

3 files changed

+89
-21
lines changed

demo/src/screens/componentScreens/FloatingButtonScreen.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import React, {Component} from 'react';
22
import {View, StyleSheet, Alert, ScrollView} from 'react-native';
3-
import {Colors, Text, FloatingButton} from 'react-native-ui-lib';
3+
import {Colors, Text, FloatingButton, FloatingButtonLayouts} from 'react-native-ui-lib';
44
import {renderBooleanOption} from '../ExampleScreenPresenter';
55

66
interface State {
77
showButton: boolean;
88
showSecondary: boolean;
9+
showVertical: boolean;
910
}
1011

1112
export default class FloatingButtonScreen extends Component<{}, State> {
1213
state = {
1314
showButton: true,
14-
showSecondary: true
15+
showSecondary: true,
16+
showVertical: true
1517
};
1618

1719
notNow = () => {
@@ -25,14 +27,15 @@ export default class FloatingButtonScreen extends Component<{}, State> {
2527
};
2628

2729
render() {
28-
const {showSecondary} = this.state;
30+
const {showSecondary, showVertical} = this.state;
2931
return (
3032
<View style={styles.container}>
3133
<Text text60 center $textDefault marginB-s4>
3234
Trigger Floating Button
3335
</Text>
3436
{renderBooleanOption.call(this, 'Show Floating Button', 'showButton')}
3537
{renderBooleanOption.call(this, 'Show Secondary Button', 'showSecondary')}
38+
{renderBooleanOption.call(this, 'Button Layout Vertical', 'showVertical')}
3639

3740
<ScrollView showsVerticalScrollIndicator={false}>
3841
<View paddingT-20>
@@ -69,11 +72,11 @@ export default class FloatingButtonScreen extends Component<{}, State> {
6972
showSecondary
7073
? {
7174
label: 'Not now',
72-
onPress: this.notNow,
73-
color: Colors.$textDangerLight
75+
onPress: this.notNow
7476
}
7577
: undefined
7678
}
79+
buttonLayout={showVertical ? FloatingButtonLayouts.VERTICAL : FloatingButtonLayouts.HORIZONTAL}
7780
// bottomMargin={80}
7881
// hideBackgroundOverlay
7982
// withoutAnimation

src/components/floatingButton/index.tsx

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import View from '../view';
66
import Button, {ButtonProps} from '../button';
77
import Image from '../image';
88

9+
export enum FloatingButtonLayouts {
10+
VERTICAL = 'Vertical',
11+
HORIZONTAL = 'Horizontal'
12+
}
913
export interface FloatingButtonProps {
1014
/**
1115
* Whether the button is visible
@@ -42,6 +46,10 @@ export interface FloatingButtonProps {
4246
* <TestID>.secondaryButton - the floatingButton secondaryButton
4347
*/
4448
testID?: string;
49+
/**
50+
* Button layout direction: vertical or horizontal
51+
*/
52+
buttonLayout?: FloatingButtonLayouts;
4553
}
4654

4755
const gradientImage = () => require('./gradient.png');
@@ -54,9 +62,11 @@ const gradientImage = () => require('./gradient.png');
5462
*/
5563
class FloatingButton extends PureComponent<FloatingButtonProps> {
5664
static displayName = 'FloatingButton';
65+
static floatingButtonLayouts = FloatingButtonLayouts;
5766

5867
static defaultProps = {
59-
duration: 300
68+
duration: 300,
69+
buttonLayout: FloatingButtonLayouts.VERTICAL
6070
};
6171

6272
initialVisibility?: boolean;
@@ -86,21 +96,39 @@ class FloatingButton extends PureComponent<FloatingButtonProps> {
8696
getAnimatedStyle = () => {
8797
return {
8898
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+
]
93107
};
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;
94118
}
95119

96120
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;
99126

100127
return (
101128
<Button
102129
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}]}
104132
testID={`${testID}.button`}
105133
{...button}
106134
/>
@@ -123,7 +151,23 @@ class FloatingButton extends PureComponent<FloatingButtonProps> {
123151
};
124152

125153
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+
}
127171

128172
return (
129173
<Button
@@ -138,9 +182,9 @@ class FloatingButton extends PureComponent<FloatingButtonProps> {
138182
}
139183

140184
render() {
141-
const {withoutAnimation, secondaryButton, visible, testID} = this.props;
185+
const {withoutAnimation, visible, testID} = this.props;
142186
// 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);
144188

145189
// NOTE: On first load, don't show if it should not be visible
146190
if (this.firstLoad === true && !this.initialVisibility) {
@@ -152,14 +196,17 @@ class FloatingButton extends PureComponent<FloatingButtonProps> {
152196

153197
return (
154198
<View
199+
row={!!this.isSecondaryHorizontal}
200+
center={!!this.isSecondaryHorizontal}
155201
pointerEvents="box-none"
156202
animated
157203
style={[styles.container, this.getAnimatedStyle()]}
158204
testID={testID}
159205
>
160206
{this.renderOverlay()}
207+
{this.isSecondaryHorizontal && this.renderSecondaryButton()}
161208
{this.renderButton()}
162-
{secondaryButton && this.renderSecondaryButton()}
209+
{this.isSecondaryVertical && this.renderSecondaryButton()}
163210
</View>
164211
);
165212
}
@@ -183,7 +230,12 @@ const styles = StyleSheet.create({
183230
shadowOpacity: 0.35,
184231
shadowRadius: 12,
185232
elevation: 2
233+
},
234+
secondaryMargin: {
235+
marginTop: Spacings.s4,
236+
marginBottom: Spacings.s7,
237+
marginLeft: 20
186238
}
187239
});
188240

189-
export default asBaseComponent<FloatingButtonProps>(FloatingButton);
241+
export default asBaseComponent<FloatingButtonProps, typeof FloatingButton>(FloatingButton);

src/index.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export {default as Drawer, DrawerProps, DrawerItemProps} from './components/draw
7070
export {default as ExpandableSection, ExpandableSectionProps} from './components/expandableSection';
7171
export {default as Fader, FaderProps, FaderPosition} from './components/fader';
7272
export {default as FeatureHighlight, FeatureHighlightProps} from './components/featureHighlight';
73-
export {default as FloatingButton, FloatingButtonProps} from './components/floatingButton';
73+
export {default as FloatingButton, FloatingButtonProps, FloatingButtonLayouts} from './components/floatingButton';
7474
export {default as GradientSlider, GradientSliderProps} from './components/slider/GradientSlider';
7575
export {default as GridListItem, GridListItemProps} from './components/gridListItem';
7676
export {default as GridList, GridListProps} from './components/gridList';
@@ -136,9 +136,22 @@ export {default as StackAggregator, StackAggregatorProps} from './components/sta
136136
export {default as StateScreen, StateScreenProps} from './components/stateScreen';
137137
export {default as Stepper, StepperProps} from './components/stepper';
138138
export {default as Switch, SwitchProps} from './components/switch';
139-
export {default as TabController, TabControllerProps, TabControllerItemProps, TabControllerImperativeMethods} from './components/tabController';
139+
export {
140+
default as TabController,
141+
TabControllerProps,
142+
TabControllerItemProps,
143+
TabControllerImperativeMethods
144+
} from './components/tabController';
140145
export {default as TabBar, TabBarProps} from './components/tabBar'; //TODO: remove on V7
141-
export {default as Timeline, TimelineProps, TimelinePointProps, TimelineLineProps, TimelineStateTypes, TimelinePointTypes, TimelineLineTypes} from './components/timeline';
146+
export {
147+
default as Timeline,
148+
TimelineProps,
149+
TimelinePointProps,
150+
TimelineLineProps,
151+
TimelineStateTypes,
152+
TimelinePointTypes,
153+
TimelineLineTypes
154+
} from './components/timeline';
142155
export {default as Text, TextProps} from './components/text';
143156
// @ts-expect-error
144157
export {default as TextArea} from './components/textArea';

0 commit comments

Comments
 (0)