From 660f4629d406216f040e8a849b363de8f5843a02 Mon Sep 17 00:00:00 2001 From: Bao Nguyen Date: Sun, 23 Aug 2026 11:09:16 +0700 Subject: [PATCH 1/2] fix(appbar): make back icon respect the icon from Provider settings --- src/components/Appbar/AppbarBackIcon.tsx | 7 +- .../__tests__/Appbar/Appbar.test.tsx | 64 ++++++++++++++++++- 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/components/Appbar/AppbarBackIcon.tsx b/src/components/Appbar/AppbarBackIcon.tsx index ff827b3f5f..3383909603 100644 --- a/src/components/Appbar/AppbarBackIcon.tsx +++ b/src/components/Appbar/AppbarBackIcon.tsx @@ -2,7 +2,7 @@ import { Image, Platform, StyleSheet, View } from 'react-native'; import type { ColorValue } from 'react-native'; import { useLocale } from '../../core/locale'; -import MaterialCommunityIcon from '../MaterialCommunityIcon'; +import Icon from '../Icon'; const AppbarBackIcon = ({ size, @@ -34,11 +34,10 @@ const AppbarBackIcon = ({ /> ) : ( - ); }; diff --git a/src/components/__tests__/Appbar/Appbar.test.tsx b/src/components/__tests__/Appbar/Appbar.test.tsx index 95aec82ddd..b59977ef67 100644 --- a/src/components/__tests__/Appbar/Appbar.test.tsx +++ b/src/components/__tests__/Appbar/Appbar.test.tsx @@ -1,6 +1,10 @@ -import { describe, expect, it } from '@jest/globals'; +import { Platform, Text as RNText } from 'react-native'; + +import { afterEach, describe, expect, it } from '@jest/globals'; +import { render as rtlRender } from '@testing-library/react-native'; import { SafeAreaProvider } from 'react-native-safe-area-context'; +import PaperProvider from '../../../core/PaperProvider'; import { render, screen } from '../../../test-utils'; import { DarkTheme, LightTheme } from '../../../theme/schemes'; import { tokens } from '../../../theme/tokens'; @@ -11,6 +15,7 @@ import { modeTextVariant, renderAppbarContent as utilRenderAppbarContent, } from '../../Appbar/utils'; +import type { IconProps } from '../../MaterialCommunityIcon'; import Menu from '../../Menu/Menu'; import Searchbar from '../../Searchbar'; import Text from '../../Typography/Text'; @@ -309,3 +314,60 @@ describe('getAppbarBorders', () => { expect(getAppbarBorders({ height: 60, top: 13 })).toEqual({}); }); }); + +describe('Appbar.BackAction icon', () => { + const originalPlatform = Platform.OS; + + afterEach(() => { + Platform.OS = originalPlatform; + }); + + const CustomIcon = ({ name, size, direction, testID }: IconProps) => ( + + {`custom-${name}`} + + ); + + const renderBackAction = (direction?: 'ltr' | 'rtl') => + rtlRender( + + {}} testID="back-action" /> + + ); + + it('renders the icon provided through PaperProvider settings', async () => { + Platform.OS = 'android'; + + await renderBackAction(); + + expect( + screen.getByText('custom-arrow-left', { includeHiddenElements: true }) + ).toBeOnTheScreen(); + }); + + it('keeps the icon mirrored in RTL', async () => { + Platform.OS = 'android'; + + await renderBackAction('rtl'); + + expect( + screen.getByText('custom-arrow-left', { includeHiddenElements: true }) + ).toHaveStyle({ transform: [{ scaleX: -1 }] }); + }); + + it('keeps the icon unmirrored in LTR', async () => { + Platform.OS = 'android'; + + await renderBackAction('ltr'); + + expect( + screen.getByText('custom-arrow-left', { includeHiddenElements: true }) + ).toHaveStyle({ transform: [{ scaleX: 1 }] }); + }); +}); From dcacc981ff7d46559c3fcf2a071437aaedec8bba Mon Sep 17 00:00:00 2001 From: Bao Nguyen Date: Tue, 25 Aug 2026 09:04:54 +0700 Subject: [PATCH 2/2] fix(appbar): respect the configured icon renderer on iOS Keep the bundled chevron only while the default renderer is in place, so an icon renderer passed through PaperProvider settings is also used for the back icon on iOS. --- src/components/Appbar/AppbarBackIcon.tsx | 12 +++++++++++- src/components/__tests__/Appbar/Appbar.test.tsx | 10 ++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/components/Appbar/AppbarBackIcon.tsx b/src/components/Appbar/AppbarBackIcon.tsx index 3383909603..41a85a4a81 100644 --- a/src/components/Appbar/AppbarBackIcon.tsx +++ b/src/components/Appbar/AppbarBackIcon.tsx @@ -1,8 +1,12 @@ +import * as React from 'react'; import { Image, Platform, StyleSheet, View } from 'react-native'; import type { ColorValue } from 'react-native'; import { useLocale } from '../../core/locale'; +import { SettingsContext } from '../../core/settings'; +import type { Settings } from '../../core/settings'; import Icon from '../Icon'; +import MaterialCommunityIcon from '../MaterialCommunityIcon'; const AppbarBackIcon = ({ size, @@ -12,10 +16,16 @@ const AppbarBackIcon = ({ color: ColorValue; }) => { const { direction } = useLocale(); + const { icon } = React.useContext(SettingsContext); const isRTL = direction === 'rtl'; const iosIconSize = size - 3; - return Platform.OS === 'ios' ? ( + // The bundled chevron is only kept while the default icon renderer is in + // place, so a renderer configured through `PaperProvider` wins on iOS too. + const shouldUseIOSAsset = + Platform.OS === 'ios' && (!icon || icon === MaterialCommunityIcon); + + return shouldUseIOSAsset ? ( { ).toBeOnTheScreen(); }); + it('renders the icon provided through PaperProvider settings on iOS', async () => { + Platform.OS = 'ios'; + + await renderBackAction(); + + expect( + screen.getByText('custom-arrow-left', { includeHiddenElements: true }) + ).toBeOnTheScreen(); + }); + it('keeps the icon mirrored in RTL', async () => { Platform.OS = 'android';