UNPKG

7.62 kBJavaScriptView Raw
1function _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
3import * as React from 'react';
4import { Animated, Platform, StyleSheet, TouchableWithoutFeedback, View } from 'react-native';
5import color from 'color';
6import Icon from './Icon';
7import MaterialCommunityIcon from './MaterialCommunityIcon';
8import Surface from './Surface';
9import Text from './Typography/Text';
10import TouchableRipple from './TouchableRipple/TouchableRipple';
11import { withTheme } from '../core/theming';
12import { black, white } from '../styles/colors';
13
14/**
15 * Chips can be used to display entities in small blocks.
16 *
17 * <div class="screenshots">
18 * <figure>
19 * <img class="medium" src="screenshots/chip-1.png" />
20 * <figcaption>Flat chip</figcaption>
21 * </figure>
22 * <figure>
23 * <img class="medium" src="screenshots/chip-2.png" />
24 * <figcaption>Outlined chip</figcaption>
25 * </figure>
26 * </div>
27 *
28 * ## Usage
29 * ```js
30 * import * as React from 'react';
31 * import { Chip } from 'react-native-paper';
32 *
33 * const MyComponent = () => (
34 * <Chip icon="information" onPress={() => console.log('Pressed')}>Example Chip</Chip>
35 * );
36 *
37 * export default MyComponent;
38 * ```
39 */
40const 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 /*#__PURE__*/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), /*#__PURE__*/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 // @ts-expect-error We keep old a11y props for backwards compat with old RN versions
137 ,
138 accessibilityTraits: accessibilityTraits,
139 accessibilityComponentType: "button",
140 accessibilityRole: "button",
141 accessibilityState: accessibilityState,
142 testID: testID
143 }, /*#__PURE__*/React.createElement(View, {
144 style: [styles.content, {
145 paddingRight: onClose ? 32 : 4
146 }]
147 }, avatar && !icon ? /*#__PURE__*/React.createElement(View, {
148 style: [styles.avatarWrapper, disabled && {
149 opacity: 0.26
150 }]
151 }, /*#__PURE__*/React.isValidElement(avatar) ? /*#__PURE__*/React.cloneElement(avatar, {
152 style: [styles.avatar, avatar.props.style]
153 }) : avatar) : null, icon || selected ? /*#__PURE__*/React.createElement(View, {
154 style: [styles.icon, avatar ? [styles.avatar, styles.avatarSelected] : null]
155 }, icon ? /*#__PURE__*/React.createElement(Icon, {
156 source: icon,
157 color: avatar ? white : iconColor,
158 size: 18
159 }) : /*#__PURE__*/React.createElement(MaterialCommunityIcon, {
160 name: "check",
161 color: avatar ? white : iconColor,
162 size: 18,
163 direction: "ltr"
164 })) : null, /*#__PURE__*/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 ? /*#__PURE__*/React.createElement(View, {
174 style: styles.closeButtonStyle
175 }, /*#__PURE__*/React.createElement(TouchableWithoutFeedback, {
176 onPress: onClose // @ts-expect-error We keep old a11y props for backwards compat with old RN versions
177 ,
178 accessibilityTraits: "button",
179 accessibilityComponentType: "button",
180 accessibilityRole: "button",
181 accessibilityLabel: closeIconAccessibilityLabel
182 }, /*#__PURE__*/React.createElement(View, {
183 style: [styles.icon, styles.closeIcon]
184 }, closeIcon ? /*#__PURE__*/React.createElement(Icon, {
185 source: closeIcon,
186 color: iconColor,
187 size: 16
188 }) : /*#__PURE__*/React.createElement(MaterialCommunityIcon, {
189 name: "close-circle",
190 size: 16,
191 color: iconColor,
192 direction: "ltr"
193 })))) : null);
194};
195
196const 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});
250export default withTheme(Chip);
251//# sourceMappingURL=Chip.js.map
\No newline at end of file