forked from callstack/react-native-paper
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIcon.tsx
124 lines (111 loc) · 2.99 KB
/
Icon.tsx
1
2
3
4
5
6
7
8
9
10
11
12
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import * as React from 'react';
import {
Image,
I18nManager,
Platform,
ImageSourcePropType,
} from 'react-native';
import { Consumer as SettingsConsumer } from '../core/settings';
import { accessibilityProps } from './MaterialCommunityIcon';
import { withTheme } from '../core/theming';
import { Theme } from '../types';
type IconSourceBase = string | ImageSourcePropType;
export type IconSource =
| IconSourceBase
| Readonly<{ source: IconSourceBase; direction: 'rtl' | 'ltr' | 'auto' }>
| ((props: IconProps & { color: string }) => React.ReactNode);
type IconProps = {
size: number;
allowFontScaling?: boolean;
};
type Props = IconProps & {
color?: string;
source: any;
/**
* @optional
*/
theme: Theme;
};
const isImageSource = (source: any) =>
// source is an object with uri
(typeof source === 'object' &&
source !== null &&
Object.prototype.hasOwnProperty.call(source, 'uri') &&
typeof source.uri === 'string') ||
// source is a module, e.g. - require('image')
typeof source === 'number' ||
// image url on web
(Platform.OS === 'web' &&
typeof source === 'string' &&
(source.startsWith('data:image') ||
/\.(bmp|jpg|jpeg|png|gif|svg)$/.test(source)));
const getIconId = (source: any) => {
if (
typeof source === 'object' &&
source !== null &&
Object.prototype.hasOwnProperty.call(source, 'uri') &&
typeof source.uri === 'string'
) {
return source.uri;
}
return source;
};
export const isValidIcon = (source: any) =>
typeof source === 'string' || isImageSource(source);
export const isEqualIcon = (a: any, b: any) =>
a === b || getIconId(a) === getIconId(b);
const Icon = ({ source, color, size, theme, ...rest }: Props) => {
const direction =
// @ts-ignore
typeof source === 'object' && source.direction && source.source
? source.direction === 'auto'
? I18nManager.isRTL
? 'rtl'
: 'ltr'
: source.direction
: null;
const s =
// @ts-ignore
typeof source === 'object' && source.direction && source.source
? source.source
: source;
const iconColor = color || theme.colors.text;
if (isImageSource(s)) {
return (
<Image
{...rest}
source={s}
style={[
{
transform: [{ scaleX: direction === 'rtl' ? -1 : 1 }],
},
// eslint-disable-next-line react-native/no-inline-styles
{
width: size,
height: size,
tintColor: color,
resizeMode: 'contain',
},
]}
{...accessibilityProps}
/>
);
} else if (typeof s === 'string') {
return (
<SettingsConsumer>
{({ icon }) => {
return icon({
name: s,
color: iconColor,
size,
direction,
});
}}
</SettingsConsumer>
);
} else if (typeof s === 'function') {
return s({ color: iconColor, size, direction });
}
return null;
};
export default withTheme(Icon);