Skip to content

Commit cba1f78

Browse files
committed
refactor: organize code in component
1 parent 4818b3f commit cba1f78

File tree

1 file changed

+65
-65
lines changed

1 file changed

+65
-65
lines changed

src/components/MaterialCommunityIcon.tsx

Lines changed: 65 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,20 @@ type AccessibilityProps =
2323
importantForAccessibility?: 'auto' | 'yes' | 'no' | 'no-hide-descendants';
2424
};
2525

26+
export const accessibilityProps: AccessibilityProps =
27+
Platform.OS === 'web'
28+
? {
29+
role: 'img',
30+
focusable: false,
31+
}
32+
: {
33+
accessibilityElementsHidden: true,
34+
importantForAccessibility: 'no-hide-descendants',
35+
};
36+
37+
/**
38+
* Loads the appropriate icon module based on available dependencies
39+
*/
2640
const loadIconModule = () => {
2741
try {
2842
return require('@expo/vector-icons/MaterialCommunityIcons').default;
@@ -41,7 +55,7 @@ const loadIconModule = () => {
4155
}
4256
};
4357

44-
let MaterialCommunityIcons: React.ComponentType<
58+
type IconModuleType = React.ComponentType<
4559
React.ComponentProps<
4660
| typeof import('@react-native-vector-icons/material-design-icons').default
4761
| typeof import('react-native-vector-icons/MaterialCommunityIcons').default
@@ -51,79 +65,65 @@ let MaterialCommunityIcons: React.ComponentType<
5165
}
5266
>;
5367

54-
MaterialCommunityIcons = loadIconModule();
55-
56-
if (!MaterialCommunityIcons) {
57-
let isErrorLogged = false;
58-
59-
// Fallback component for icons
60-
MaterialCommunityIcons = ({ name, color, size, ...rest }) => {
61-
/* eslint-disable no-console */
62-
if (!isErrorLogged) {
63-
console.warn(
64-
`Tried to use the icon '${name}' in a component from 'react-native-paper', but none of the required icon libraries are installed.`,
65-
`To fix this, please install one of the following:\n` +
66-
`- @expo/vector-icons\n` +
67-
`- @react-native-vector-icons/material-design-icons\n` +
68-
`- react-native-vector-icons\n\n` +
69-
`You can also use another method to specify icon: https://callstack.github.io/react-native-paper/docs/guides/icons`
70-
);
68+
const IconModule = loadIconModule();
7169

72-
isErrorLogged = true;
73-
}
70+
/**
71+
* Fallback component displayed when no icon library is available
72+
*/
73+
const FallbackIcon = ({ name, color, size, ...rest }: IconProps) => {
74+
console.warn(
75+
`Tried to use the icon '${name}' in a component from 'react-native-paper', but none of the required icon libraries are installed.`,
76+
`To fix this, please install one of the following:\n` +
77+
`- @expo/vector-icons\n` +
78+
`- @react-native-vector-icons/material-design-icons\n` +
79+
`- react-native-vector-icons\n\n` +
80+
`You can also use another method to specify icon: https://callstack.github.io/react-native-paper/docs/guides/icons`
81+
);
7482

75-
return (
76-
<Text
77-
{...rest}
78-
style={[styles.icon, { color, fontSize: size }]}
79-
// @ts-expect-error: Text doesn't support this, but it seems to affect TouchableNativeFeedback
80-
pointerEvents="none"
81-
selectable={false}
82-
>
83-
84-
</Text>
85-
);
86-
};
87-
}
83+
return (
84+
<Text
85+
{...rest}
86+
style={[styles.icon, { color, fontSize: size }]}
87+
selectable={false}
88+
>
89+
90+
</Text>
91+
);
92+
};
8893

89-
export const accessibilityProps: AccessibilityProps =
90-
Platform.OS === 'web'
91-
? {
92-
role: 'img',
93-
focusable: false,
94-
}
95-
: {
96-
accessibilityElementsHidden: true,
97-
importantForAccessibility:
98-
'no-hide-descendants' as 'no-hide-descendants',
99-
};
94+
const MaterialCommunityIcons: IconModuleType = IconModule || FallbackIcon;
10095

101-
const defaultIcon = ({
96+
/**
97+
* Default icon component that handles icon rendering with proper styling and accessibility
98+
*/
99+
const DefaultIcon = ({
102100
name,
103101
color = black,
104102
size,
105103
direction,
106104
allowFontScaling,
107105
testID,
108-
}: IconProps) => (
109-
<MaterialCommunityIcons
110-
allowFontScaling={allowFontScaling}
111-
name={name}
112-
color={color}
113-
size={size}
114-
style={[
115-
{
116-
transform: [{ scaleX: direction === 'rtl' ? -1 : 1 }],
117-
lineHeight: size,
118-
},
119-
styles.icon,
120-
]}
121-
pointerEvents="none"
122-
selectable={false}
123-
testID={testID}
124-
{...accessibilityProps}
125-
/>
126-
);
106+
}: IconProps) => {
107+
return (
108+
<MaterialCommunityIcons
109+
allowFontScaling={allowFontScaling}
110+
name={name}
111+
color={color}
112+
size={size}
113+
style={[
114+
{
115+
transform: [{ scaleX: direction === 'rtl' ? -1 : 1 }],
116+
lineHeight: size,
117+
},
118+
styles.icon,
119+
]}
120+
pointerEvents="none"
121+
selectable={false}
122+
testID={testID}
123+
{...accessibilityProps}
124+
/>
125+
);
126+
};
127127

128128
const styles = StyleSheet.create({
129129
// eslint-disable-next-line react-native/no-color-literals
@@ -132,4 +132,4 @@ const styles = StyleSheet.create({
132132
},
133133
});
134134

135-
export default defaultIcon;
135+
export default DefaultIcon;

0 commit comments

Comments
 (0)