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 * as React from 'react';
|
4 | import { Animated, Platform, StyleSheet, TouchableWithoutFeedback, View } from 'react-native';
|
5 | import color from 'color';
|
6 | import Icon from './Icon';
|
7 | import MaterialCommunityIcon from './MaterialCommunityIcon';
|
8 | import Surface from './Surface';
|
9 | import Text from './Typography/Text';
|
10 | import TouchableRipple from './TouchableRipple/TouchableRipple';
|
11 | import { withTheme } from '../core/theming';
|
12 | import { black, white } from '../styles/colors';
|
13 |
|
14 |
|
15 |
|
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 | const Chip = _ref => {
|
41 | let {
|
42 | mode = 'flat',
|
43 | children,
|
44 | icon,
|
45 | avatar,
|
46 | selected = false,
|
47 | disabled = false,
|
48 | accessibilityLabel,
|
49 | closeIconAccessibilityLabel = 'Close',
|
50 | onPress,
|
51 | onLongPress,
|
52 | onClose,
|
53 | closeIcon,
|
54 | textStyle,
|
55 | style,
|
56 | theme,
|
57 | testID,
|
58 | selectedColor,
|
59 | ellipsizeMode,
|
60 | ...rest
|
61 | } = _ref;
|
62 | const {
|
63 | current: elevation
|
64 | } = React.useRef(new Animated.Value(0));
|
65 |
|
66 | const handlePressIn = () => {
|
67 | const {
|
68 | scale
|
69 | } = theme.animation;
|
70 | Animated.timing(elevation, {
|
71 | toValue: 4,
|
72 | duration: 200 * scale,
|
73 | useNativeDriver: true
|
74 | }).start();
|
75 | };
|
76 |
|
77 | const handlePressOut = () => {
|
78 | const {
|
79 | scale
|
80 | } = theme.animation;
|
81 | Animated.timing(elevation, {
|
82 | toValue: 0,
|
83 | duration: 150 * scale,
|
84 | useNativeDriver: true
|
85 | }).start();
|
86 | };
|
87 |
|
88 | const {
|
89 | dark,
|
90 | colors
|
91 | } = theme;
|
92 | const defaultBackgroundColor = mode === 'outlined' ? colors.surface : dark ? '#383838' : '#ebebeb';
|
93 | const {
|
94 | backgroundColor = defaultBackgroundColor,
|
95 | borderRadius = 16
|
96 | } = StyleSheet.flatten(style) || {};
|
97 | const borderColor = mode === 'outlined' ? color(selectedColor !== undefined ? selectedColor : color(dark ? white : black)).alpha(0.29).rgb().string() : backgroundColor;
|
98 | const textColor = disabled ? colors.disabled : color(selectedColor !== undefined ? selectedColor : colors.text).alpha(0.87).rgb().string();
|
99 | const iconColor = disabled ? colors.disabled : color(selectedColor !== undefined ? selectedColor : colors.text).alpha(0.54).rgb().string();
|
100 | const backgroundColorString = typeof backgroundColor === 'string' ? backgroundColor : defaultBackgroundColor;
|
101 | const selectedBackgroundColor = (dark ? color(backgroundColorString).lighten(mode === 'outlined' ? 0.2 : 0.4) : color(backgroundColorString).darken(mode === 'outlined' ? 0.08 : 0.2)).rgb().string();
|
102 | const underlayColor = selectedColor ? color(selectedColor).fade(0.5).rgb().string() : selectedBackgroundColor;
|
103 | const accessibilityTraits = ['button'];
|
104 | const accessibilityState = {
|
105 | selected,
|
106 | disabled
|
107 | };
|
108 |
|
109 | if (selected) {
|
110 | accessibilityTraits.push('selected');
|
111 | }
|
112 |
|
113 | if (disabled) {
|
114 | accessibilityTraits.push('disabled');
|
115 | }
|
116 |
|
117 | return React.createElement(Surface, _extends({
|
118 | style: [styles.container, {
|
119 | elevation: Platform.OS === 'android' ? elevation : 0,
|
120 | backgroundColor: selected ? selectedBackgroundColor : backgroundColor,
|
121 | borderColor,
|
122 | borderRadius
|
123 | }, style]
|
124 | }, rest), React.createElement(TouchableRipple, {
|
125 | borderless: true,
|
126 | delayPressIn: 0,
|
127 | style: [{
|
128 | borderRadius
|
129 | }, styles.touchable],
|
130 | onPress: onPress,
|
131 | onLongPress: onLongPress,
|
132 | onPressIn: handlePressIn,
|
133 | onPressOut: handlePressOut,
|
134 | underlayColor: underlayColor,
|
135 | disabled: disabled,
|
136 | accessibilityLabel: accessibilityLabel
|
137 | ,
|
138 | accessibilityTraits: accessibilityTraits,
|
139 | accessibilityComponentType: "button",
|
140 | accessibilityRole: "button",
|
141 | accessibilityState: accessibilityState,
|
142 | testID: testID
|
143 | }, React.createElement(View, {
|
144 | style: [styles.content, {
|
145 | paddingRight: onClose ? 32 : 4
|
146 | }]
|
147 | }, avatar && !icon ? React.createElement(View, {
|
148 | style: [styles.avatarWrapper, disabled && {
|
149 | opacity: 0.26
|
150 | }]
|
151 | }, React.isValidElement(avatar) ? React.cloneElement(avatar, {
|
152 | style: [styles.avatar, avatar.props.style]
|
153 | }) : avatar) : null, icon || selected ? React.createElement(View, {
|
154 | style: [styles.icon, avatar ? [styles.avatar, styles.avatarSelected] : null]
|
155 | }, icon ? React.createElement(Icon, {
|
156 | source: icon,
|
157 | color: avatar ? white : iconColor,
|
158 | size: 18
|
159 | }) : React.createElement(MaterialCommunityIcon, {
|
160 | name: "check",
|
161 | color: avatar ? white : iconColor,
|
162 | size: 18,
|
163 | direction: "ltr"
|
164 | })) : null, React.createElement(Text, {
|
165 | selectable: false,
|
166 | numberOfLines: 1,
|
167 | style: [styles.text, { ...theme.fonts.regular,
|
168 | color: textColor,
|
169 | marginRight: onClose ? 0 : 8,
|
170 | marginLeft: avatar || icon || selected ? 4 : 8
|
171 | }, textStyle],
|
172 | ellipsizeMode: ellipsizeMode
|
173 | }, children))), onClose ? React.createElement(View, {
|
174 | style: styles.closeButtonStyle
|
175 | }, React.createElement(TouchableWithoutFeedback, {
|
176 | onPress: onClose
|
177 | ,
|
178 | accessibilityTraits: "button",
|
179 | accessibilityComponentType: "button",
|
180 | accessibilityRole: "button",
|
181 | accessibilityLabel: closeIconAccessibilityLabel
|
182 | }, React.createElement(View, {
|
183 | style: [styles.icon, styles.closeIcon]
|
184 | }, closeIcon ? React.createElement(Icon, {
|
185 | source: closeIcon,
|
186 | color: iconColor,
|
187 | size: 16
|
188 | }) : React.createElement(MaterialCommunityIcon, {
|
189 | name: "close-circle",
|
190 | size: 16,
|
191 | color: iconColor,
|
192 | direction: "ltr"
|
193 | })))) : null);
|
194 | };
|
195 |
|
196 | const styles = StyleSheet.create({
|
197 | container: {
|
198 | borderWidth: StyleSheet.hairlineWidth,
|
199 | borderStyle: 'solid',
|
200 | flexDirection: Platform.select({
|
201 | default: 'column',
|
202 | web: 'row'
|
203 | })
|
204 | },
|
205 | content: {
|
206 | flexDirection: 'row',
|
207 | alignItems: 'center',
|
208 | paddingLeft: 4,
|
209 | position: 'relative',
|
210 | flexGrow: 1
|
211 | },
|
212 | icon: {
|
213 | padding: 4,
|
214 | alignSelf: 'center'
|
215 | },
|
216 | closeIcon: {
|
217 | marginRight: 4
|
218 | },
|
219 | text: {
|
220 | minHeight: 24,
|
221 | lineHeight: 24,
|
222 | textAlignVertical: 'center',
|
223 | marginVertical: 4
|
224 | },
|
225 | avatar: {
|
226 | width: 24,
|
227 | height: 24,
|
228 | borderRadius: 12
|
229 | },
|
230 | avatarWrapper: {
|
231 | marginRight: 4
|
232 | },
|
233 | avatarSelected: {
|
234 | position: 'absolute',
|
235 | top: 4,
|
236 | left: 4,
|
237 | backgroundColor: 'rgba(0, 0, 0, .29)'
|
238 | },
|
239 | closeButtonStyle: {
|
240 | position: 'absolute',
|
241 | right: 0,
|
242 | height: '100%',
|
243 | justifyContent: 'center',
|
244 | alignItems: 'center'
|
245 | },
|
246 | touchable: {
|
247 | flexGrow: 1
|
248 | }
|
249 | });
|
250 | export default withTheme(Chip);
|
251 |
|
\ | No newline at end of file |