1 | var __rest = (this && this.__rest) || function (s, e) {
|
2 | var t = {};
|
3 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
4 | t[p] = s[p];
|
5 | if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
6 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
7 | if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
8 | t[p[i]] = s[p[i]];
|
9 | }
|
10 | return t;
|
11 | };
|
12 | import React, { useCallback, useEffect } from 'react';
|
13 | import { View, Text, TouchableNativeFeedback, TouchableOpacity, ActivityIndicator, Platform, StyleSheet, } from 'react-native';
|
14 | import Color from 'color';
|
15 | import { withTheme } from '../config';
|
16 | import { renderNode, color } from '../helpers';
|
17 | import Icon from '../icons/Icon';
|
18 | const defaultLoadingProps = (type, theme) => {
|
19 | var _a;
|
20 | return ({
|
21 | color: type === 'solid' ? 'white' : (_a = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _a === void 0 ? void 0 : _a.primary,
|
22 | size: 'small',
|
23 | });
|
24 | };
|
25 | const Button = (props) => {
|
26 | var _a, _b, _c, _d, _e, _f, _g;
|
27 | useEffect(() => {
|
28 | if (props.linearGradientProps && !props.ViewComponent) {
|
29 | console.error("You need to pass a ViewComponent to use linearGradientProps !\nExample: ViewComponent={require('react-native-linear-gradient')}");
|
30 | }
|
31 | });
|
32 | const { TouchableComponent, containerStyle, onPress = () => console.log('Please attach a method to this component'), buttonStyle, type = 'solid', loading = false, loadingStyle, loadingProps: passedLoadingProps, title = '', titleProps, titleStyle: passedTitleStyle, icon, iconContainerStyle, iconRight = false, disabled = false, disabledStyle, disabledTitleStyle, raised = false, linearGradientProps, ViewComponent = View, theme, iconPosition = 'left' } = props, attributes = __rest(props, ["TouchableComponent", "containerStyle", "onPress", "buttonStyle", "type", "loading", "loadingStyle", "loadingProps", "title", "titleProps", "titleStyle", "icon", "iconContainerStyle", "iconRight", "disabled", "disabledStyle", "disabledTitleStyle", "raised", "linearGradientProps", "ViewComponent", "theme", "iconPosition"]);
|
33 | const handleOnPress = useCallback((evt) => {
|
34 | if (!loading) {
|
35 | onPress(evt);
|
36 | }
|
37 | }, [loading, onPress]);
|
38 |
|
39 | const TouchableComponentInternal = TouchableComponent ||
|
40 | Platform.select({
|
41 | android: linearGradientProps ? TouchableOpacity : TouchableNativeFeedback,
|
42 | default: TouchableOpacity,
|
43 | });
|
44 | const titleStyle = StyleSheet.flatten([
|
45 | {
|
46 | color: type === 'solid' ? 'white' : (_a = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _a === void 0 ? void 0 : _a.primary,
|
47 | },
|
48 | styles.title,
|
49 | passedTitleStyle,
|
50 | disabled && {
|
51 | color: color((_b = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _b === void 0 ? void 0 : _b.disabled).darken(0.3).string(),
|
52 | },
|
53 | disabled && disabledTitleStyle,
|
54 | ]);
|
55 | const background = Platform.OS === 'android' && Platform.Version >= 21
|
56 | ? TouchableNativeFeedback.Ripple(Color((_c = titleStyle === null || titleStyle === void 0 ? void 0 : titleStyle.color) === null || _c === void 0 ? void 0 : _c.toString()).alpha(0.32).rgb().string(), true)
|
57 | : undefined;
|
58 | const loadingProps = Object.assign(Object.assign({}, defaultLoadingProps(type, theme)), passedLoadingProps);
|
59 | const accessibilityState = {
|
60 | disabled: !!disabled,
|
61 | busy: !!loading,
|
62 | };
|
63 | const positionStyle = {
|
64 | top: 'column',
|
65 | bottom: 'column-reverse',
|
66 | left: 'row',
|
67 | right: 'row-reverse',
|
68 | };
|
69 | return (<View style={[
|
70 | styles.container,
|
71 | {
|
72 | borderRadius: 3 || styles.container.borderRadius,
|
73 | },
|
74 | containerStyle,
|
75 | raised && !disabled && type !== 'clear' && styles.raised,
|
76 | ]}>
|
77 | <TouchableComponentInternal onPress={handleOnPress} delayPressIn={0} activeOpacity={0.3} accessibilityRole="button" accessibilityState={accessibilityState} disabled={disabled} background={background} {...attributes}>
|
78 | <ViewComponent {...linearGradientProps} style={StyleSheet.flatten([
|
79 | styles.button,
|
80 | styles.buttonOrientation,
|
81 | {
|
82 | flexDirection: positionStyle[iconRight ? 'right' : iconPosition] || 'row',
|
83 | },
|
84 | {
|
85 | backgroundColor: type === 'solid' ? (_d = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _d === void 0 ? void 0 : _d.primary : 'transparent',
|
86 | borderColor: (_e = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _e === void 0 ? void 0 : _e.primary,
|
87 | borderWidth: type === 'outline' ? StyleSheet.hairlineWidth : 0,
|
88 | },
|
89 | buttonStyle,
|
90 | disabled &&
|
91 | type === 'solid' && {
|
92 | backgroundColor: (_f = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _f === void 0 ? void 0 : _f.disabled,
|
93 | },
|
94 | disabled &&
|
95 | type === 'outline' && {
|
96 | borderColor: color((_g = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _g === void 0 ? void 0 : _g.disabled)
|
97 | .darken(0.3)
|
98 | .string(),
|
99 | },
|
100 | disabled && disabledStyle,
|
101 | ])}>
|
102 | {loading && (<ActivityIndicator style={StyleSheet.flatten([styles.loading, loadingStyle])} color={loadingProps.color} size={loadingProps.size} {...loadingProps}/>)}
|
103 | {!loading &&
|
104 | icon &&
|
105 | renderNode(Icon, icon, {
|
106 | containerStyle: StyleSheet.flatten([
|
107 | styles.iconContainer,
|
108 | iconContainerStyle,
|
109 | ]),
|
110 | })}
|
111 |
|
112 | {!loading &&
|
113 | !!title &&
|
114 | renderNode(Text, title, Object.assign({ style: titleStyle }, titleProps))}
|
115 | </ViewComponent>
|
116 | </TouchableComponentInternal>
|
117 | </View>);
|
118 | };
|
119 | const styles = StyleSheet.create({
|
120 | button: {
|
121 | flexDirection: 'row',
|
122 | justifyContent: 'center',
|
123 | alignItems: 'center',
|
124 | borderRadius: 3,
|
125 | padding: 8,
|
126 | },
|
127 | buttonOrientation: {
|
128 | justifyContent: 'center',
|
129 | alignItems: 'center',
|
130 | borderRadius: 3,
|
131 | padding: 8,
|
132 | },
|
133 | container: {
|
134 | overflow: 'hidden',
|
135 | borderRadius: 3,
|
136 | },
|
137 | title: Object.assign({ fontSize: 16, textAlign: 'center', paddingVertical: 1 }, Platform.select({
|
138 | android: {
|
139 | fontFamily: 'sans-serif-medium',
|
140 | },
|
141 | default: {
|
142 | fontSize: 18,
|
143 | },
|
144 | })),
|
145 | iconContainer: {
|
146 | marginHorizontal: 5,
|
147 | },
|
148 | raised: Object.assign({ backgroundColor: '#fff', overflow: 'visible' }, Platform.select({
|
149 | android: {
|
150 | elevation: 4,
|
151 | },
|
152 | default: {
|
153 | shadowColor: 'rgba(0,0,0, .4)',
|
154 | shadowOffset: { height: 1, width: 1 },
|
155 | shadowOpacity: 1,
|
156 | shadowRadius: 1,
|
157 | },
|
158 | })),
|
159 | loading: {
|
160 | marginVertical: 2,
|
161 | },
|
162 | });
|
163 | export { Button };
|
164 | export default withTheme(Button, 'Button');
|
165 |
|
\ | No newline at end of file |