diff --git a/src/components/Appbar/Appbar.tsx b/src/components/Appbar/Appbar.tsx
index e1b251ea9a..231b4a9774 100644
--- a/src/components/Appbar/Appbar.tsx
+++ b/src/components/Appbar/Appbar.tsx
@@ -18,6 +18,7 @@ import {
getAppbarBackgroundColor,
modeAppbarHeight,
renderAppbarContent,
+ filterAppbarActions,
} from './utils';
import { useInternalTheme } from '../../core/theming';
import type { MD3Elevation, ThemeProp } from '../../types';
@@ -210,12 +211,14 @@ const Appbar = ({
React.Children.forEach(children, (child) => {
if (React.isValidElement(child)) {
+ const isLeading = child.props.isLeading === true;
+
if (child.type === AppbarContent) {
hasAppbarContent = true;
- } else if (hasAppbarContent) {
- rightItemsCount++;
- } else {
+ } else if (isLeading || !hasAppbarContent) {
leftItemsCount++;
+ } else {
+ rightItemsCount++;
}
}
});
@@ -228,15 +231,6 @@ const Appbar = ({
shouldAddRightSpacing = shouldCenterContent && rightItemsCount === 0;
}
- const filterAppbarActions = React.useCallback(
- (isLeading = false) =>
- React.Children.toArray(children).filter((child) =>
- // @ts-expect-error: TypeScript complains about the type of type but it doesn't matter
- isLeading ? child.props.isLeading : !child.props.isLeading
- ),
- [children]
- );
-
const spacingStyle = isV3 ? styles.v3Spacing : styles.spacing;
const insets = {
@@ -262,14 +256,32 @@ const Appbar = ({
{...rest}
>
{shouldAddLeftSpacing ? : null}
- {(!isV3 || isMode('small') || isMode('center-aligned')) &&
- renderAppbarContent({
- children,
- isDark,
- theme,
- isV3,
- shouldCenterContent: isV3CenterAlignedMode || shouldCenterContent,
- })}
+ {(!isV3 || isMode('small') || isMode('center-aligned')) && (
+ <>
+ {/* Render only the back action at first place */}
+ {renderAppbarContent({
+ children,
+ isDark,
+ theme,
+ isV3,
+ renderOnly: ['Appbar.BackAction'],
+ shouldCenterContent: isV3CenterAlignedMode || shouldCenterContent,
+ })}
+ {/* Render the rest of the content except the back action */}
+ {renderAppbarContent({
+ // Filter appbar actions - first leading icons, then trailing icons
+ children: [
+ ...filterAppbarActions(children, true),
+ ...filterAppbarActions(children),
+ ],
+ isDark,
+ theme,
+ isV3,
+ renderExcept: ['Appbar.BackAction'],
+ shouldCenterContent: isV3CenterAlignedMode || shouldCenterContent,
+ })}
+ >
+ )}
{(isMode('medium') || isMode('large')) && (
{renderAppbarContent({
- children: filterAppbarActions(false),
+ children: filterAppbarActions(children),
isDark,
isV3,
renderExcept: [
@@ -310,7 +322,6 @@ const Appbar = ({
})}
- {/* Middle of the row, can contain only AppbarContent */}
{renderAppbarContent({
children,
isDark,
diff --git a/src/components/Appbar/AppbarAction.tsx b/src/components/Appbar/AppbarAction.tsx
index 1fbec55652..bc87e335ba 100644
--- a/src/components/Appbar/AppbarAction.tsx
+++ b/src/components/Appbar/AppbarAction.tsx
@@ -48,7 +48,7 @@ export type Props = React.ComponentPropsWithoutRef & {
/**
* @supported Available in v5.x with theme version 3
*
- * Whether it's the leading button.
+ * Whether it's the leading button. Note: If `Appbar.BackAction` is present, it will be rendered before any `isLeading` icons.
*/
isLeading?: boolean;
style?: Animated.WithAnimatedValue>;
diff --git a/src/components/Appbar/utils.ts b/src/components/Appbar/utils.ts
index c69cd67a5a..f5780b0c9d 100644
--- a/src/components/Appbar/utils.ts
+++ b/src/components/Appbar/utils.ts
@@ -113,6 +113,22 @@ export const modeTextVariant = {
'center-aligned': 'titleLarge',
} as const;
+/**
+ * Filtruje akcje w Appbarze na podstawie właściwości isLeading.
+ * @param children - Dzieci komponentu Appbar do przefiltrowania
+ * @param isLeading - Czy filtrować akcje wiodące (true) czy niewiodące (false). Domyślnie false.
+ * @returns Przefiltrowana tablica elementów React
+ */
+export const filterAppbarActions = (
+ children: React.ReactNode,
+ isLeading = false
+) => {
+ return React.Children.toArray(children).filter((child) => {
+ if (!React.isValidElement(child)) return false;
+ return isLeading ? child.props.isLeading : !child.props.isLeading;
+ });
+};
+
export const renderAppbarContent = ({
children,
isDark,
diff --git a/src/components/__tests__/Appbar/__snapshots__/Appbar.test.tsx.snap b/src/components/__tests__/Appbar/__snapshots__/Appbar.test.tsx.snap
index 9b00150ddf..0eca20beef 100644
--- a/src/components/__tests__/Appbar/__snapshots__/Appbar.test.tsx.snap
+++ b/src/components/__tests__/Appbar/__snapshots__/Appbar.test.tsx.snap
@@ -652,7 +652,9 @@ exports[`Appbar passes additional props to AppbarBackAction, AppbarContent and A
"paddingHorizontal": 0,
},
[
- false,
+ {
+ "marginLeft": 12,
+ },
false,
undefined,
],