1 | function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
2 |
|
3 | import color from 'color';
|
4 | import * as React from 'react';
|
5 | import { Animated, View, StyleSheet } from 'react-native';
|
6 | import ActivityIndicator from '../ActivityIndicator';
|
7 | import Surface from '../Surface';
|
8 | import CrossFadeIcon from '../CrossFadeIcon';
|
9 | import Icon from '../Icon';
|
10 | import Text from '../Typography/Text';
|
11 | import TouchableRipple from '../TouchableRipple/TouchableRipple';
|
12 | import { black, white } from '../../styles/colors';
|
13 | import { withTheme } from '../../core/theming';
|
14 | import getContrastingColor from '../../utils/getContrastingColor';
|
15 | getContrastingColor;
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 | const FAB = _ref => {
|
53 | let {
|
54 | small,
|
55 | icon,
|
56 | label,
|
57 | accessibilityLabel = label,
|
58 | accessibilityState,
|
59 | animated = true,
|
60 | color: customColor,
|
61 | disabled,
|
62 | onPress,
|
63 | onLongPress,
|
64 | theme,
|
65 | style,
|
66 | visible = true,
|
67 | uppercase = true,
|
68 | loading,
|
69 | testID,
|
70 | ...rest
|
71 | } = _ref;
|
72 | const {
|
73 | current: visibility
|
74 | } = React.useRef(new Animated.Value(visible ? 1 : 0));
|
75 | const {
|
76 | scale
|
77 | } = theme.animation;
|
78 | React.useEffect(() => {
|
79 | if (visible) {
|
80 | Animated.timing(visibility, {
|
81 | toValue: 1,
|
82 | duration: 200 * scale,
|
83 | useNativeDriver: true
|
84 | }).start();
|
85 | } else {
|
86 | Animated.timing(visibility, {
|
87 | toValue: 0,
|
88 | duration: 150 * scale,
|
89 | useNativeDriver: true
|
90 | }).start();
|
91 | }
|
92 | }, [visible, scale, visibility]);
|
93 | const IconComponent = animated ? CrossFadeIcon : Icon;
|
94 | const disabledColor = color(theme.dark ? white : black).alpha(0.12).rgb().string();
|
95 | const {
|
96 | backgroundColor = disabled ? disabledColor : theme.colors.accent
|
97 | } = StyleSheet.flatten(style) || {};
|
98 | let foregroundColor;
|
99 |
|
100 | if (typeof customColor !== 'undefined') {
|
101 | foregroundColor = customColor;
|
102 | } else if (disabled) {
|
103 | foregroundColor = color(theme.dark ? white : black).alpha(0.32).rgb().string();
|
104 | } else {
|
105 | foregroundColor = getContrastingColor(backgroundColor, white, 'rgba(0, 0, 0, .54)');
|
106 | }
|
107 |
|
108 | const rippleColor = color(foregroundColor).alpha(0.32).rgb().string();
|
109 | return React.createElement(Surface, _extends({}, rest, {
|
110 | style: [{
|
111 | backgroundColor,
|
112 | opacity: visibility,
|
113 | transform: [{
|
114 | scale: visibility
|
115 | }]
|
116 | }, styles.container, disabled && styles.disabled, style],
|
117 | pointerEvents: visible ? 'auto' : 'none'
|
118 | }), React.createElement(TouchableRipple, {
|
119 | borderless: true,
|
120 | onPress: onPress,
|
121 | onLongPress: onLongPress,
|
122 | rippleColor: rippleColor,
|
123 | disabled: disabled,
|
124 | accessibilityLabel: accessibilityLabel
|
125 | ,
|
126 | accessibilityTraits: disabled ? ['button', 'disabled'] : 'button',
|
127 | accessibilityComponentType: "button",
|
128 | accessibilityRole: "button",
|
129 | accessibilityState: { ...accessibilityState,
|
130 | disabled
|
131 | },
|
132 | style: styles.touchable,
|
133 | testID: testID
|
134 | }, React.createElement(View, {
|
135 | style: [styles.content, label ? styles.extended : small ? styles.small : styles.standard],
|
136 | pointerEvents: "none"
|
137 | }, icon && loading !== true ? React.createElement(IconComponent, {
|
138 | source: icon,
|
139 | size: 24,
|
140 | color: foregroundColor
|
141 | }) : null, loading ? React.createElement(ActivityIndicator, {
|
142 | size: 18,
|
143 | color: foregroundColor
|
144 | }) : null, label ? React.createElement(Text, {
|
145 | selectable: false,
|
146 | style: [styles.label, uppercase && styles.uppercaseLabel, {
|
147 | color: foregroundColor,
|
148 | ...theme.fonts.medium
|
149 | }]
|
150 | }, label) : null)));
|
151 | };
|
152 |
|
153 | const styles = StyleSheet.create({
|
154 | container: {
|
155 | borderRadius: 28,
|
156 | elevation: 6
|
157 | },
|
158 | touchable: {
|
159 | borderRadius: 28
|
160 | },
|
161 | standard: {
|
162 | height: 56,
|
163 | width: 56
|
164 | },
|
165 | small: {
|
166 | height: 40,
|
167 | width: 40
|
168 | },
|
169 | extended: {
|
170 | height: 48,
|
171 | paddingHorizontal: 16
|
172 | },
|
173 | content: {
|
174 | flexDirection: 'row',
|
175 | alignItems: 'center',
|
176 | justifyContent: 'center'
|
177 | },
|
178 | label: {
|
179 | marginHorizontal: 8
|
180 | },
|
181 | uppercaseLabel: {
|
182 | textTransform: 'uppercase'
|
183 | },
|
184 | disabled: {
|
185 | elevation: 0
|
186 | }
|
187 | });
|
188 | export default withTheme(FAB);
|
189 |
|
190 | const FABWithTheme = withTheme(FAB);
|
191 |
|
192 | export { FABWithTheme as FAB };
|
193 |
|
\ | No newline at end of file |