Skip to content

Commit b3c7557

Browse files
committed
Revert "Remove deprecated FAB"
This reverts commit 35f9ee7.
1 parent e125c4d commit b3c7557

File tree

1 file changed

+231
-0
lines changed

1 file changed

+231
-0
lines changed
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
import * as React from "react";
2+
import {
3+
ActivityIndicator,
4+
View,
5+
StyleSheet,
6+
StyleProp,
7+
ViewStyle,
8+
TextStyle,
9+
Pressable,
10+
PressableProps,
11+
} from "react-native";
12+
import color from "color";
13+
import Config from "./Config";
14+
import Text from "./Text";
15+
import Elevation from "./Elevation";
16+
import { withTheme } from "../theming";
17+
18+
import type { Theme } from "../styles/DefaultTheme";
19+
import type { IconSlot } from "../interfaces/Icon";
20+
21+
/**
22+
* A floating action button represents the primary action in an application.
23+
*
24+
* <div class="screenshots">
25+
* <img src="screenshots/fab-1.png" />
26+
* <img src="screenshots/fab-2.png" />
27+
* </div>
28+
*
29+
* ## Usage
30+
* ```js
31+
* import * as React from 'react';
32+
* import { StyleSheet } from 'react-native';
33+
* import { FAB } from '@draftbit/ui';
34+
*
35+
* const MyComponent = () => (
36+
* <FAB
37+
* style={styles.fab}
38+
* type="outline"
39+
* icon="add"
40+
* onPress={() => console.log('Pressed')}
41+
* />
42+
* );
43+
*
44+
* const styles = StyleSheet.create({
45+
* fab: {
46+
* position: 'absolute',
47+
* margin: 16,
48+
* right: 0,
49+
* bottom: 0,
50+
* },
51+
* })
52+
*
53+
* export default MyComponent;
54+
* ```
55+
*/
56+
57+
type Props = {
58+
disabled?: boolean;
59+
type?: "solid" | "extended" | "outline" | "fixed" | "standard";
60+
loading?: boolean;
61+
icon?: string;
62+
color?: string;
63+
label?: string;
64+
onPress: () => void;
65+
elevation?: number;
66+
theme: Theme;
67+
style?: StyleProp<ViewStyle>;
68+
} & PressableProps &
69+
IconSlot;
70+
71+
const FAB: React.FC<React.PropsWithChildren<Props>> = ({
72+
Icon,
73+
icon,
74+
disabled = false,
75+
type = "solid",
76+
loading = false,
77+
color: colorOverride,
78+
label,
79+
onPress,
80+
elevation = 0,
81+
style,
82+
theme: { colors, disabledOpacity, roundness, typography },
83+
...rest
84+
}) => {
85+
let backgroundColor, borderColor, textColor, borderWidth;
86+
const buttonColor = colorOverride || colors.primary;
87+
88+
if (type === "standard" || type === "extended" || type === "fixed") {
89+
backgroundColor = buttonColor;
90+
91+
if (disabled) {
92+
textColor = color(colors.surface).alpha(disabledOpacity).rgb().string();
93+
} else {
94+
textColor = colors.surface;
95+
}
96+
} else {
97+
backgroundColor = "transparent";
98+
99+
if (disabled) {
100+
textColor = color(buttonColor).alpha(disabledOpacity).rgb().string();
101+
} else {
102+
textColor = buttonColor;
103+
}
104+
}
105+
106+
if (type === "outline") {
107+
if (disabled) {
108+
borderColor = color(buttonColor).alpha(disabledOpacity).rgb().string();
109+
} else {
110+
borderColor = buttonColor;
111+
}
112+
borderWidth = StyleSheet.hairlineWidth;
113+
} else {
114+
borderColor = "transparent";
115+
borderWidth = 0;
116+
}
117+
118+
const buttonStyle: StyleProp<ViewStyle> = {
119+
backgroundColor,
120+
borderColor,
121+
borderWidth,
122+
borderRadius: roundness,
123+
alignItems: "center",
124+
justifyContent: "center",
125+
};
126+
127+
const buttonStyles: StyleProp<ViewStyle>[] = [styles.button, buttonStyle];
128+
129+
const contentStyle: StyleProp<ViewStyle>[] = [styles.content];
130+
131+
const textStyle: StyleProp<TextStyle> = {
132+
textAlign: "center",
133+
color: textColor,
134+
};
135+
136+
const iconStyle: StyleProp<ViewStyle>[] = [
137+
styles.icon,
138+
{
139+
width: Config.buttonIconSize,
140+
},
141+
];
142+
143+
if (type === "standard" || type === "outline") {
144+
buttonStyle.width = Config.FABSize;
145+
buttonStyle.height = Config.FABSize;
146+
buttonStyle.borderRadius = Config.FABBorderRadius;
147+
148+
contentStyle.push({
149+
width: Config.FABSize,
150+
height: Config.FABSize,
151+
});
152+
}
153+
154+
if (type === "extended" || type === "fixed") {
155+
iconStyle.push({
156+
marginLeft: 16,
157+
marginRight: -8,
158+
});
159+
160+
textStyle.margin = 16;
161+
}
162+
163+
if (type === "fixed") {
164+
buttonStyles.push({
165+
height: Config.FABFixedHeight,
166+
alignSelf: "stretch",
167+
});
168+
}
169+
170+
return (
171+
<Elevation style={[{ elevation }, style]}>
172+
<Pressable
173+
{...rest}
174+
onPress={onPress}
175+
accessibilityState={{ disabled }}
176+
accessibilityRole="button"
177+
disabled={disabled || loading}
178+
style={buttonStyles}
179+
>
180+
<View style={styles.content}>
181+
{icon && loading !== true ? (
182+
<View style={iconStyle}>
183+
<Icon
184+
name={icon}
185+
size={Config.buttonIconSize}
186+
color={textColor}
187+
/>
188+
</View>
189+
) : null}
190+
{loading ? (
191+
<ActivityIndicator
192+
size="small"
193+
color={textColor}
194+
style={iconStyle}
195+
/>
196+
) : null}
197+
{label ? (
198+
<Text numberOfLines={1} style={[textStyle, typography.button]}>
199+
{label}
200+
</Text>
201+
) : null}
202+
</View>
203+
</Pressable>
204+
</Elevation>
205+
);
206+
};
207+
208+
const styles = StyleSheet.create({
209+
button: {
210+
borderStyle: "solid",
211+
},
212+
content: {
213+
flexDirection: "row",
214+
alignItems: "center",
215+
justifyContent: "center",
216+
},
217+
icon: {
218+
alignItems: "center",
219+
justifyContent: "center",
220+
width: Config.buttonIconSize,
221+
},
222+
fixed: {
223+
left: 0,
224+
right: 0,
225+
bottom: 0,
226+
height: 64,
227+
borderRadius: 0,
228+
},
229+
});
230+
231+
export default withTheme(FAB);

0 commit comments

Comments
 (0)