@react-navigation/bottom-tabs 8.0.0-alpha.2 → 8.0.0-alpha.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/lib/module/navigators/createBottomTabNavigator.js +1 -18
  2. package/lib/module/navigators/createBottomTabNavigator.js.map +1 -1
  3. package/lib/module/utils/useBottomTabAnimation.js +1 -1
  4. package/lib/module/utils/useBottomTabAnimation.js.map +1 -1
  5. package/lib/module/utils/useBottomTabBarHeight.js +1 -1
  6. package/lib/module/utils/useBottomTabBarHeight.js.map +1 -1
  7. package/lib/module/views/BottomTabBar.js +13 -10
  8. package/lib/module/views/BottomTabBar.js.map +1 -1
  9. package/lib/module/views/BottomTabItem.js +1 -1
  10. package/lib/module/views/BottomTabItem.js.map +1 -1
  11. package/lib/module/views/BottomTabViewCustom.js +64 -66
  12. package/lib/module/views/BottomTabViewCustom.js.map +1 -1
  13. package/lib/module/views/BottomTabViewNativeImpl.js +117 -29
  14. package/lib/module/views/BottomTabViewNativeImpl.js.map +1 -1
  15. package/lib/module/views/ScreenContent.js.map +1 -1
  16. package/lib/module/views/TabBarIcon.js +5 -14
  17. package/lib/module/views/TabBarIcon.js.map +1 -1
  18. package/lib/typescript/src/index.d.ts +1 -1
  19. package/lib/typescript/src/index.d.ts.map +1 -1
  20. package/lib/typescript/src/navigators/createBottomTabNavigator.d.ts.map +1 -1
  21. package/lib/typescript/src/types.d.ts +63 -100
  22. package/lib/typescript/src/types.d.ts.map +1 -1
  23. package/lib/typescript/src/views/BottomTabBar.d.ts.map +1 -1
  24. package/lib/typescript/src/views/BottomTabItem.d.ts +16 -16
  25. package/lib/typescript/src/views/BottomTabItem.d.ts.map +1 -1
  26. package/lib/typescript/src/views/BottomTabViewCustom.d.ts +1 -1
  27. package/lib/typescript/src/views/BottomTabViewCustom.d.ts.map +1 -1
  28. package/lib/typescript/src/views/BottomTabViewNativeImpl.d.ts.map +1 -1
  29. package/lib/typescript/src/views/ScreenContent.d.ts +2 -2
  30. package/lib/typescript/src/views/ScreenContent.d.ts.map +1 -1
  31. package/lib/typescript/src/views/TabBarIcon.d.ts +6 -6
  32. package/lib/typescript/src/views/TabBarIcon.d.ts.map +1 -1
  33. package/package.json +16 -17
  34. package/src/index.tsx +0 -1
  35. package/src/navigators/createBottomTabNavigator.tsx +0 -28
  36. package/src/types.tsx +65 -109
  37. package/src/utils/useBottomTabAnimation.tsx +1 -1
  38. package/src/utils/useBottomTabBarHeight.tsx +1 -1
  39. package/src/views/BottomTabBar.tsx +19 -11
  40. package/src/views/BottomTabItem.tsx +17 -19
  41. package/src/views/BottomTabViewCustom.tsx +119 -117
  42. package/src/views/BottomTabViewNativeImpl.tsx +192 -48
  43. package/src/views/ScreenContent.tsx +1 -2
  44. package/src/views/TabBarIcon.tsx +17 -24
@@ -1,7 +1,7 @@
1
- import { getLabel } from '@react-navigation/elements';
1
+ import { getLabel, type Icon } from '@react-navigation/elements';
2
2
  import {
3
+ ActivityView,
3
4
  Color,
4
- Lazy,
5
5
  SafeAreaProviderCompat,
6
6
  } from '@react-navigation/elements/internal';
7
7
  import {
@@ -15,7 +15,13 @@ import {
15
15
  useTheme,
16
16
  } from '@react-navigation/native';
17
17
  import * as React from 'react';
18
- import { Animated, Platform, PlatformColor } from 'react-native';
18
+ import {
19
+ Animated,
20
+ type ColorValue,
21
+ Platform,
22
+ PlatformColor,
23
+ StyleSheet,
24
+ } from 'react-native';
19
25
  import {
20
26
  type PlatformIcon,
21
27
  Tabs,
@@ -24,7 +30,6 @@ import {
24
30
 
25
31
  import type {
26
32
  BottomTabDescriptorMap,
27
- BottomTabIcon,
28
33
  BottomTabNavigationConfig,
29
34
  BottomTabNavigationHelpers,
30
35
  } from '../types';
@@ -57,6 +62,18 @@ export function BottomTabViewNative({
57
62
  const { dark, colors, fonts } = useTheme();
58
63
 
59
64
  const focusedRouteKey = state.routes[state.index].key;
65
+
66
+ const [loaded, setLoaded] = React.useState([focusedRouteKey]);
67
+
68
+ if (!loaded.includes(focusedRouteKey)) {
69
+ setLoaded([...loaded, focusedRouteKey]);
70
+ }
71
+
72
+ const [pendingNavigation, setPendingNavigation] = React.useState<{
73
+ from: string;
74
+ to: string;
75
+ } | null>(null);
76
+
60
77
  const previousRouteKeyRef = React.useRef(focusedRouteKey);
61
78
 
62
79
  React.useEffect(() => {
@@ -75,11 +92,26 @@ export function BottomTabViewNative({
75
92
  ...StackActions.popToTop(),
76
93
  target: prevRoute.state.key,
77
94
  };
95
+
78
96
  navigation.dispatch(popToTopAction);
79
97
  }
80
98
  }
81
99
 
82
100
  previousRouteKeyRef.current = focusedRouteKey;
101
+
102
+ // Delay clearing `isAnimating`
103
+ // This will give time for `popToAction` to get handled before pause
104
+ const timer = setTimeout(() => {
105
+ setPendingNavigation((pending) => {
106
+ if (pending?.to === focusedRouteKey) {
107
+ return null;
108
+ }
109
+
110
+ return pending;
111
+ });
112
+ }, 32);
113
+
114
+ return () => clearTimeout(timer);
83
115
  }, [descriptors, focusedRouteKey, navigation, state.index, state.routes]);
84
116
 
85
117
  const currentOptions = descriptors[state.routes[state.index].key]?.options;
@@ -95,18 +127,67 @@ export function BottomTabViewNative({
95
127
  }),
96
128
  fontSize,
97
129
  fontStyle,
130
+ color: fontColor,
98
131
  } = currentOptions.tabBarLabelStyle || {};
99
132
 
100
- const activeTintColor =
101
- currentOptions.tabBarActiveTintColor ?? colors.primary;
133
+ const backgroundColor =
134
+ currentOptions.tabBarStyle?.backgroundColor ?? colors.background;
135
+
136
+ const shouldHideTabBar = currentOptions.tabBarStyle?.display === 'none';
137
+
138
+ let activeIndicatorColor = currentOptions?.tabBarActiveIndicatorColor;
139
+ let activeTintColor = currentOptions.tabBarActiveTintColor;
140
+ let inactiveTintColor = currentOptions.tabBarInactiveTintColor;
141
+
142
+ // Derive colors based on Material Design guidelines
143
+ // https://m3.material.io/components/navigation-bar/specs
144
+ if (Platform.OS === 'android') {
145
+ switch (getAndroidColorName(backgroundColor)) {
146
+ case 'system_surface_container_light':
147
+ case 'system_surface_container_high_light':
148
+ case 'system_surface_container_highest_light':
149
+ case 'system_surface_container_low_light':
150
+ case 'system_surface_container_lowest_light':
151
+ inactiveTintColor =
152
+ inactiveTintColor ??
153
+ PlatformColor('@android:color/system_on_surface_variant_light');
154
+ activeTintColor =
155
+ activeTintColor ??
156
+ PlatformColor('@android:color/system_on_secondary_container_light');
157
+ activeIndicatorColor =
158
+ activeIndicatorColor ??
159
+ PlatformColor('@android:color/system_secondary_container_light');
160
+ break;
161
+ case 'system_surface_container_dark':
162
+ case 'system_surface_container_high_dark':
163
+ case 'system_surface_container_highest_dark':
164
+ case 'system_surface_container_low_dark':
165
+ case 'system_surface_container_lowest_dark':
166
+ inactiveTintColor =
167
+ inactiveTintColor ??
168
+ PlatformColor('@android:color/system_on_surface_variant_dark');
169
+ activeTintColor =
170
+ activeTintColor ??
171
+ PlatformColor('@android:color/system_on_secondary_container_dark');
172
+ activeIndicatorColor =
173
+ activeIndicatorColor ??
174
+ PlatformColor('@android:color/system_secondary_container_dark');
175
+ break;
176
+ }
177
+ }
102
178
 
103
- const inactiveTintColor =
104
- currentOptions.tabBarInactiveTintColor ??
179
+ inactiveTintColor =
180
+ inactiveTintColor ??
105
181
  Platform.select({ ios: PlatformColor('label'), default: colors.text });
106
182
 
107
- const activeIndicatorColor =
108
- currentOptions?.tabBarActiveIndicatorColor ??
109
- Color(activeTintColor)?.alpha(0.1).string();
183
+ activeTintColor = activeTintColor ?? colors.primary;
184
+
185
+ activeIndicatorColor =
186
+ activeIndicatorColor ??
187
+ Platform.select({
188
+ android: Color(activeTintColor)?.alpha(0.075).string(),
189
+ default: undefined,
190
+ });
110
191
 
111
192
  const onTransitionStart = ({ route }: { route: Route<string> }) => {
112
193
  navigation.emit({
@@ -160,7 +241,7 @@ export function BottomTabViewNative({
160
241
  ? tabBarElement
161
242
  : null}
162
243
  <Tabs.Host
163
- tabBarHidden={hasCustomTabBar}
244
+ tabBarHidden={hasCustomTabBar || shouldHideTabBar}
164
245
  bottomAccessory={
165
246
  bottomAccessory
166
247
  ? (environment) => bottomAccessory({ placement: environment })
@@ -174,16 +255,14 @@ export function BottomTabViewNative({
174
255
  tabBarTintColor={activeTintColor}
175
256
  tabBarItemIconColor={inactiveTintColor}
176
257
  tabBarItemIconColorActive={activeTintColor}
177
- tabBarItemTitleFontColor={inactiveTintColor}
258
+ tabBarItemTitleFontColor={inactiveTintColor ?? fontColor}
178
259
  tabBarItemTitleFontColorActive={activeTintColor}
179
260
  tabBarItemTitleFontFamily={fontFamily}
180
261
  tabBarItemTitleFontWeight={fontWeight}
181
262
  tabBarItemTitleFontSize={fontSize}
182
263
  tabBarItemTitleFontSizeActive={fontSize}
183
264
  tabBarItemTitleFontStyle={fontStyle}
184
- tabBarBackgroundColor={
185
- currentOptions.tabBarStyle?.backgroundColor ?? colors.card
186
- }
265
+ tabBarBackgroundColor={backgroundColor}
187
266
  tabBarItemActiveIndicatorColor={activeIndicatorColor}
188
267
  tabBarItemActiveIndicatorEnabled={
189
268
  currentOptions?.tabBarActiveIndicatorEnabled
@@ -213,6 +292,11 @@ export function BottomTabViewNative({
213
292
  state.routes.findIndex((r) => r.key === route.key);
214
293
 
215
294
  if (!isFocused) {
295
+ setPendingNavigation({
296
+ from: previousRouteKeyRef.current,
297
+ to: route.key,
298
+ });
299
+
216
300
  navigation.dispatch({
217
301
  ...CommonActions.navigate(route.name, route.params),
218
302
  target: state.key,
@@ -229,6 +313,7 @@ export function BottomTabViewNative({
229
313
  const {
230
314
  title,
231
315
  lazy = true,
316
+ inactiveBehavior = 'pause',
232
317
  tabBarLabel,
233
318
  tabBarBadgeStyle,
234
319
  tabBarIcon,
@@ -236,8 +321,11 @@ export function BottomTabViewNative({
236
321
  tabBarSystemItem,
237
322
  tabBarBlurEffect = dark ? 'systemMaterialDark' : 'systemMaterial',
238
323
  tabBarStyle,
324
+ tabBarAccessibilityLabel,
325
+ tabBarButtonTestID,
239
326
  sceneStyle,
240
327
  scrollEdgeEffects,
328
+ overrideScrollViewContentInsetAdjustmentBehavior,
241
329
  } = options;
242
330
 
243
331
  const {
@@ -252,19 +340,21 @@ export function BottomTabViewNative({
252
340
  ? tabBarLabel
253
341
  : getLabel({ label: tabBarLabel, title }, route.name);
254
342
 
343
+ const badgeBackgroundColor =
344
+ tabBarBadgeStyle?.backgroundColor ?? colors.notification;
345
+ const badgeTextColor =
346
+ tabBarBadgeStyle?.color ?? Color.foreground(badgeBackgroundColor);
347
+
255
348
  const tabItemAppearance: TabsScreenItemStateAppearance = {
256
349
  tabBarItemTitleFontFamily: fontFamily,
257
350
  tabBarItemTitleFontSize: fontSize,
258
351
  tabBarItemTitleFontWeight: fontWeight,
259
352
  tabBarItemTitleFontStyle: fontStyle,
353
+ tabBarItemTitleFontColor: inactiveTintColor ?? fontColor,
354
+ tabBarItemIconColor: inactiveTintColor,
355
+ tabBarItemBadgeBackgroundColor: badgeBackgroundColor,
260
356
  };
261
357
 
262
- const badgeBackgroundColor =
263
- tabBarBadgeStyle?.backgroundColor ?? colors.notification;
264
- const badgeTextColor =
265
- tabBarBadgeStyle?.color ??
266
- (Color(badgeBackgroundColor)?.isLight() ? 'black' : 'white');
267
-
268
358
  const getIcon = (selected: boolean) => {
269
359
  if (typeof tabBarIcon === 'function') {
270
360
  const result = tabBarIcon({
@@ -298,6 +388,15 @@ export function BottomTabViewNative({
298
388
  const icon = getIcon(false);
299
389
  const selectedIcon = getIcon(true);
300
390
 
391
+ // For preloaded screens and if lazy is false,
392
+ // Keep them active so that the effects can run
393
+ const isActive =
394
+ inactiveBehavior === 'none' ||
395
+ isPreloaded ||
396
+ pendingNavigation?.from === route.key ||
397
+ pendingNavigation?.to === route.key ||
398
+ (lazy === false && !loaded.includes(route.key));
399
+
301
400
  return (
302
401
  <Tabs.Screen
303
402
  onWillAppear={() => onTransitionStart({ route })}
@@ -308,6 +407,8 @@ export function BottomTabViewNative({
308
407
  selectedIcon={selectedIcon?.ios ?? selectedIcon?.shared}
309
408
  tabBarItemBadgeBackgroundColor={badgeBackgroundColor}
310
409
  tabBarItemBadgeTextColor={badgeTextColor}
410
+ tabBarItemAccessibilityLabel={tabBarAccessibilityLabel}
411
+ tabBarItemTestID={tabBarButtonTestID}
311
412
  badgeValue={tabBarBadge?.toString()}
312
413
  systemItem={tabBarSystemItem}
313
414
  isFocused={isFocused}
@@ -330,9 +431,20 @@ export function BottomTabViewNative({
330
431
  ? 'automatic'
331
432
  : scrollEdgeEffects?.right,
332
433
  }}
333
- // FIXME: if this is not provided, ScrollView on lazy tabs glitches on iOS 18
334
- // For now we provide an empty object before adding proper support
335
- scrollEdgeAppearance={{}}
434
+ scrollEdgeAppearance={{
435
+ tabBarBackgroundColor,
436
+ tabBarShadowColor,
437
+ tabBarBlurEffect,
438
+ stacked: {
439
+ normal: tabItemAppearance,
440
+ },
441
+ inline: {
442
+ normal: tabItemAppearance,
443
+ },
444
+ compactInline: {
445
+ normal: tabItemAppearance,
446
+ },
447
+ }}
336
448
  standardAppearance={{
337
449
  tabBarBackgroundColor,
338
450
  tabBarShadowColor,
@@ -353,25 +465,43 @@ export function BottomTabViewNative({
353
465
  scrollToTop: true,
354
466
  },
355
467
  }}
468
+ overrideScrollViewContentInsetAdjustmentBehavior={
469
+ overrideScrollViewContentInsetAdjustmentBehavior
470
+ }
356
471
  experimental_userInterfaceStyle={dark ? 'dark' : 'light'}
357
472
  >
358
- <Lazy enabled={lazy} visible={isFocused || isPreloaded}>
359
- <ScreenContent
360
- isFocused={isFocused}
361
- route={route}
362
- navigation={navigation}
363
- options={options}
364
- style={sceneStyle}
473
+ {lazy &&
474
+ !loaded.includes(route.key) &&
475
+ !isFocused &&
476
+ !isPreloaded ? null : (
477
+ <ActivityView
478
+ key={route.key}
479
+ mode={isFocused ? 'normal' : isActive ? 'inert' : 'paused'}
480
+ visible={
481
+ // We don't need to hide the content since it's handled natively
482
+ // Hiding may also cause flash due to lag after native tab switch
483
+ // So we leave it always visible
484
+ true
485
+ }
486
+ style={StyleSheet.absoluteFill}
365
487
  >
366
- <AnimatedScreenContent isFocused={isFocused}>
367
- <BottomTabBarHeightContext.Provider value={0}>
368
- <NavigationMetaContext.Provider value={meta}>
369
- {render()}
370
- </NavigationMetaContext.Provider>
371
- </BottomTabBarHeightContext.Provider>
372
- </AnimatedScreenContent>
373
- </ScreenContent>
374
- </Lazy>
488
+ <ScreenContent
489
+ isFocused={isFocused}
490
+ route={route}
491
+ navigation={navigation}
492
+ options={options}
493
+ style={sceneStyle}
494
+ >
495
+ <AnimatedScreenContent isFocused={isFocused}>
496
+ <BottomTabBarHeightContext.Provider value={0}>
497
+ <NavigationMetaContext.Provider value={meta}>
498
+ {render()}
499
+ </NavigationMetaContext.Provider>
500
+ </BottomTabBarHeightContext.Provider>
501
+ </AnimatedScreenContent>
502
+ </ScreenContent>
503
+ </ActivityView>
504
+ )}
375
505
  </Tabs.Screen>
376
506
  );
377
507
  })}
@@ -382,6 +512,7 @@ export function BottomTabViewNative({
382
512
  </SafeAreaProviderCompat>
383
513
  );
384
514
  }
515
+
385
516
  function AnimatedScreenContent({
386
517
  isFocused,
387
518
  children,
@@ -415,7 +546,7 @@ function AnimatedScreenContent({
415
546
  );
416
547
  }
417
548
 
418
- function getPlatformIcon(icon: BottomTabIcon): PlatformIcon {
549
+ function getPlatformIcon(icon: Icon): PlatformIcon {
419
550
  switch (icon.type) {
420
551
  case 'sfSymbol':
421
552
  return {
@@ -430,6 +561,9 @@ function getPlatformIcon(icon: BottomTabIcon): PlatformIcon {
430
561
  type: 'imageSource',
431
562
  imageSource: MaterialSymbol.getImageSource({
432
563
  name: icon.name,
564
+ variant: icon.variant,
565
+ weight: icon.weight,
566
+ size: ICON_SIZE,
433
567
  }),
434
568
  },
435
569
  shared: undefined,
@@ -452,12 +586,6 @@ function getPlatformIcon(icon: BottomTabIcon): PlatformIcon {
452
586
  imageSource: icon.source,
453
587
  },
454
588
  };
455
- case 'drawableResource':
456
- return {
457
- ios: undefined,
458
- android: icon,
459
- shared: undefined,
460
- };
461
589
  default: {
462
590
  const _exhaustiveCheck: never = icon;
463
591
 
@@ -465,3 +593,19 @@ function getPlatformIcon(icon: BottomTabIcon): PlatformIcon {
465
593
  }
466
594
  }
467
595
  }
596
+
597
+ function getAndroidColorName(color: ColorValue) {
598
+ const value = color as unknown;
599
+
600
+ if (
601
+ typeof value === 'object' &&
602
+ value != null &&
603
+ 'resource_paths' in value &&
604
+ Array.isArray(value.resource_paths) &&
605
+ typeof value.resource_paths[0] === 'string'
606
+ ) {
607
+ return value.resource_paths[0].replace('@android:color/', '');
608
+ }
609
+
610
+ return null;
611
+ }
@@ -2,7 +2,6 @@ import { getHeaderTitle, Header } from '@react-navigation/elements';
2
2
  import { Screen } from '@react-navigation/elements/internal';
3
3
  import type { ParamListBase, Route } from '@react-navigation/native';
4
4
  import * as React from 'react';
5
- import { type StyleProp, type ViewStyle } from 'react-native';
6
5
 
7
6
  import type {
8
7
  BottomTabNavigationOptions,
@@ -21,7 +20,7 @@ export function ScreenContent({
21
20
  route: Route<string>;
22
21
  navigation: BottomTabNavigationProp<ParamListBase>;
23
22
  options: BottomTabNavigationOptions;
24
- style?: StyleProp<ViewStyle>;
23
+ style?: React.ComponentProps<typeof Screen>['style'];
25
24
  children: React.ReactNode;
26
25
  }) {
27
26
  const {
@@ -1,4 +1,4 @@
1
- import { Badge } from '@react-navigation/elements';
1
+ import { Badge, type Icon } from '@react-navigation/elements';
2
2
  import { MissingIcon } from '@react-navigation/elements/internal';
3
3
  import { MaterialSymbol, type Route, SFSymbol } from '@react-navigation/native';
4
4
  import React from 'react';
@@ -12,26 +12,24 @@ import {
12
12
  type ViewStyle,
13
13
  } from 'react-native';
14
14
 
15
- import type { BottomTabIcon } from '../types';
16
-
17
15
  export type TabBarIconProps = {
18
16
  route: Route<string>;
19
17
  variant: 'uikit' | 'material';
20
18
  size: 'compact' | 'regular';
21
- badge?: string | number;
22
- badgeStyle?: StyleProp<TextStyle>;
19
+ badge?: string | number | undefined;
20
+ badgeStyle?: StyleProp<TextStyle> | undefined;
23
21
  activeOpacity: number;
24
22
  inactiveOpacity: number;
25
23
  activeTintColor: ColorValue;
26
24
  inactiveTintColor: ColorValue;
27
25
  icon:
28
- | BottomTabIcon
26
+ | Icon
29
27
  | ((props: {
30
28
  focused: boolean;
31
29
  color: ColorValue;
32
30
  size: number;
33
- }) => BottomTabIcon | React.ReactNode);
34
- allowFontScaling?: boolean;
31
+ }) => Icon | React.ReactNode);
32
+ allowFontScaling?: boolean | undefined;
35
33
  style: StyleProp<ViewStyle>;
36
34
  };
37
35
 
@@ -43,8 +41,8 @@ const ICON_SIZE_WIDE = 31;
43
41
  const ICON_SIZE_WIDE_COMPACT = 23;
44
42
  const ICON_SIZE_TALL = 28;
45
43
  const ICON_SIZE_TALL_COMPACT = 20;
46
- const ICON_SIZE_ROUND = 25;
47
- const ICON_SIZE_ROUND_COMPACT = 18;
44
+ const ICON_SIZE_SQUARE = 23;
45
+ const ICON_SIZE_SQUARE_COMPACT = 17;
48
46
  const ICON_SIZE_MATERIAL = 24;
49
47
 
50
48
  export function TabBarIcon({
@@ -65,8 +63,8 @@ export function TabBarIcon({
65
63
  variant === 'material'
66
64
  ? ICON_SIZE_MATERIAL
67
65
  : size === 'compact'
68
- ? ICON_SIZE_ROUND_COMPACT
69
- : ICON_SIZE_ROUND;
66
+ ? ICON_SIZE_SQUARE_COMPACT
67
+ : ICON_SIZE_SQUARE;
70
68
 
71
69
  // We render the icon twice at the same position on top of each other:
72
70
  // active and inactive one, so we can fade between them.
@@ -153,22 +151,17 @@ function renderIcon({
153
151
  }}
154
152
  />
155
153
  );
156
- case 'drawableResource':
157
- return (
158
- <Image
159
- source={{ uri: iconValue.name }}
160
- style={{
161
- width: size,
162
- height: size,
163
- tintColor: iconValue.tinted === false ? undefined : color,
164
- }}
165
- />
166
- );
167
154
  case 'sfSymbol':
168
155
  return <SFSymbol name={iconValue.name} size={size} color={color} />;
169
156
  case 'materialSymbol':
170
157
  return (
171
- <MaterialSymbol name={iconValue.name} size={size} color={color} />
158
+ <MaterialSymbol
159
+ name={iconValue.name}
160
+ variant={iconValue.variant}
161
+ weight={iconValue.weight}
162
+ size={size}
163
+ color={color}
164
+ />
172
165
  );
173
166
  default: {
174
167
  const _exhaustiveCheck: never = iconValue;