@@ -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+ */
2640const 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
128128const 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