/
icon.tsx
143 lines (133 loc) · 3.31 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import React from "react";
import {
backgroundColorStyleFunction,
BackgroundColorProps,
colorStyleFunction,
ColorProps,
layoutStyleFunction,
LayoutProps,
spacingStyleFunction,
SpacingProps,
opacityStyleFunction,
OpacityProps,
visibleStyleFunction,
VisibleProps,
} from "../../../theme/src/style-functions";
import {
AtomComponentProps,
StyleFunctionContainer,
} from "../../../theme/src/types";
import {
AntDesign,
Entypo,
EvilIcons,
Feather,
FontAwesome,
FontAwesome5,
Fontisto,
Foundation,
Ionicons,
MaterialCommunityIcons,
MaterialIcons,
Octicons,
SimpleLineIcons,
Zocial,
} from "@expo/vector-icons";
import responsiveSize from "../../../utils/responsive-size";
import { View } from "react-native";
import { pearl } from "../../../pearl";
const iconStyleFunctions = [
colorStyleFunction,
backgroundColorStyleFunction,
spacingStyleFunction,
layoutStyleFunction,
opacityStyleFunction,
visibleStyleFunction,
] as StyleFunctionContainer[];
type IconStyleProps = ColorProps &
BackgroundColorProps &
SpacingProps &
LayoutProps &
OpacityProps &
VisibleProps;
// BaseIconProps defines the basic properties for the Icon component
export type BaseIconProps = React.ComponentProps<typeof View> & {
/** Icon family that contains the icon you want to use */
iconFamily:
| "AntDesign"
| "Entypo"
| "EvilIcons"
| "Feather"
| "FontAwesome"
| "FontAwesome5"
| "Fontisto"
| "Foundation"
| "Ionicons"
| "MaterialCommunityIcons"
| "MaterialIcons"
| "Octicons"
| "SimpleLineIcons"
| "Zocial";
/** Name of the icon as given in it's respective icon family */
iconName: string;
/** The accessibility label of the icon */
accessibilityLabel?: string;
/** Size of the icon in pixels to override the component style size */
rawSize?: number;
};
// Mapping of icon families to their respective components
const iconFamilyMapping = {
AntDesign,
Entypo,
EvilIcons,
Feather,
FontAwesome,
FontAwesome5,
Fontisto,
Foundation,
Ionicons,
MaterialCommunityIcons,
MaterialIcons,
Octicons,
SimpleLineIcons,
Zocial,
};
// CustomIcon is a wrapper around the icon components that allows for additional customization
const CustomIcon = React.memo(
React.forwardRef(
(
{
iconFamily,
iconName,
accessibilityLabel = undefined,
rawSize = undefined,
...props
}: AtomComponentProps<"Icon", BaseIconProps, IconStyleProps>,
ref: any
) => {
// Select the appropriate icon component based on the iconFamily prop
const IconToUse = iconFamilyMapping[iconFamily];
return (
<IconToUse
accessible={true}
accessibilityLabel={
accessibilityLabel ? accessibilityLabel : `${iconName} Icon`
}
name={iconName}
{...props}
ref={ref}
size={responsiveSize(rawSize)}
/>
);
}
)
);
/** The `Icon` component can used to add Expo Icons to your app and customize them using style props. */
const Icon = pearl<BaseIconProps, "atom", Record<string, any>, IconStyleProps>(
CustomIcon,
{ componentName: "Icon", type: "atom", animatable: true },
iconStyleFunctions
);
export type IconProps = React.ComponentProps<typeof Icon>;
Icon.displayName = "Icon";
export default Icon;