191 lines · 8.1 KB · Text
RawDownload
diff --git a/lib/module/views/NativeStackView.native.js b/lib/module/views/NativeStackView.native.jsindex c342e90bffde9ad5044b6167bdde2e19be219270..5d3e4407aa1bb68b873cf164adf5a9f0b487bb0b 100644--- a/lib/module/views/NativeStackView.native.js+++ b/lib/module/views/NativeStackView.native.js@@ -370,6 +370,17 @@ export function NativeStackView({   return /*#__PURE__*/_jsx(SafeAreaProviderCompat, {     children: /*#__PURE__*/_jsx(ScreenStack, {       style: styles.container,+      onFinishTransitioning: () => {+        // Surface UIKit's transition-completion callback to every route of+        // this navigator. Unlike transitionEnd, this also fires when a modal+        // finishes dismissing — where the presenting screen below receives no+        // appearance callbacks — and for a gesture-driven dismissal it fires+        // before the state pop, while the modal route is still the focused+        // one, so the event must not be targeted at a single route.+        navigation.emit({+          type: 'finishTransitioning'+        });+      },       children: state.routes.concat(state.preloadedRoutes).map((route, index) => {         const descriptor = descriptors[route.key] ?? preloadedDescriptors[route.key];         const isFocused = state.index === index;diff --git a/lib/module/views/useHeaderConfigProps.js b/lib/module/views/useHeaderConfigProps.jsindex 9c21aa48cb580704aa17e59d9cdadcc612a1e4ff..a1b3a38368c5ef2257570f382e87df5d6f55b11e 100644--- a/lib/module/views/useHeaderConfigProps.js+++ b/lib/module/views/useHeaderConfigProps.js@@ -19,6 +19,12 @@ const processBarButtonItems = (items, colors, fonts) => {       }       return item;     }+    if (item.type === 'mailSearchToolbar') {+      return {+        ...item,+        index+      };+    }     if (item.type === 'button' || item.type === 'menu') {       if (item.type === 'menu' && item.menu == null) {         throw new Error(`Menu item must have a 'menu' property defined: ${JSON.stringify(item)}`);@@ -79,7 +85,7 @@ const processBarButtonItems = (items, colors, fonts) => {       }       return processedItem;     }-    throw new Error(`Invalid item type: ${JSON.stringify(item)}. Valid types are 'button', 'menu', 'custom' and 'spacing'.`);+    throw new Error(`Invalid item type: ${JSON.stringify(item)}. Valid types are 'button', 'menu', 'custom', 'spacing' and 'mailSearchToolbar'.`);   }).filter(item => item != null); }; const transformIcon = icon => {@@ -158,8 +164,12 @@ export function useHeaderConfigProps({   headerBack,   route,   title,+  unstable_headerCenterItems: headerCenterItems,   unstable_headerLeftItems: headerLeftItems,-  unstable_headerRightItems: headerRightItems+  unstable_headerRightItems: headerRightItems,+  unstable_headerSubtitle: headerSubtitle,+  unstable_headerToolbarItems: headerToolbarItems,+  unstable_navigationItemStyle: navigationItemStyle }) {   const {     direction@@ -255,6 +265,10 @@ export function useHeaderConfigProps({     tintColor,     canGoBack   });+  const centerItems = headerCenterItems?.({+    tintColor,+    canGoBack+  });   let rightItems = headerRightItems?.({     tintColor,     canGoBack@@ -264,6 +278,10 @@ export function useHeaderConfigProps({     // So we need to reverse them here to match the order     rightItems = [...rightItems].reverse();   }+  const toolbarItems = headerToolbarItems?.({+    tintColor,+    canGoBack+  });   const children = /*#__PURE__*/_jsxs(_Fragment, {     children: [Platform.OS === 'ios' ? /*#__PURE__*/_jsxs(_Fragment, {       children: [leftItems ? leftItems.map((item, index) => {@@ -272,13 +290,23 @@ export function useHeaderConfigProps({           // eslint-disable-next-line @eslint-react/no-array-index-key           , {             hidesSharedBackground: item.hidesSharedBackground,+            identifier: item.identifier,             children: item.element           }, index);         }         return null;       }) : headerLeftElement != null ? /*#__PURE__*/_jsx(ScreenStackHeaderLeftView, {         children: headerLeftElement-      }) : null, headerTitleElement != null ? /*#__PURE__*/_jsx(ScreenStackHeaderCenterView, {+      }) : null, centerItems ? centerItems.map((item, index) => {+        if (item.type === 'custom') {+          return /*#__PURE__*/_jsx(ScreenStackHeaderCenterView, {+            hidesSharedBackground: item.hidesSharedBackground,+            identifier: item.identifier,+            children: item.element+          }, index);+        }+        return null;+      }) : headerTitleElement != null ? /*#__PURE__*/_jsx(ScreenStackHeaderCenterView, {         children: headerTitleElement       }) : null]     }) : /*#__PURE__*/_jsxs(_Fragment, {@@ -321,6 +349,7 @@ export function useHeaderConfigProps({         // eslint-disable-next-line @eslint-react/no-array-index-key         , {           hidesSharedBackground: item.hidesSharedBackground,+          identifier: item.identifier,           children: item.element         }, index);       }@@ -356,6 +385,7 @@ export function useHeaderConfigProps({     largeTitleFontWeight,     largeTitleHideShadow: headerLargeTitleShadowVisible === false,     title: titleText,+    subtitle: headerSubtitle,     titleColor,     titleFontFamily,     titleFontSize,@@ -364,6 +394,9 @@ export function useHeaderConfigProps({     disableTopInsetApplication: !headerTopInsetEnabled,     translucent: translucent === true,     children,+    navigationItemStyle,+    headerToolbarItems: processBarButtonItems(toolbarItems, colors, fonts),+    headerCenterBarButtonItems: processBarButtonItems(centerItems, colors, fonts),     headerLeftBarButtonItems: processBarButtonItems(leftItems, colors, fonts),     headerRightBarButtonItems: processBarButtonItems(rightItems, colors, fonts),     experimental_userInterfaceStyle: dark ? 'dark' : 'light'diff --git a/lib/typescript/src/types.d.ts b/lib/typescript/src/types.d.tsindex 2f1351a89f0f2e67e854dc81e392198326b71834..ccf8556911fa1fa17588f06b56edb2151a712bf0 100644--- a/lib/typescript/src/types.d.ts+++ b/lib/typescript/src/types.d.ts@@ -1091,6 +1091,13 @@ export type NativeStackHeaderItemSpacing = {  */ export type NativeStackHeaderItemCustom = {     type: 'custom';+    /**+     * An identifier used to match items across transitions.+     * Only available from iOS 26.0 and later.+     *+     * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/identifier+     */+    identifier?: string;     /**      * A React Element to display as the item.      */diff --git a/src/types.tsx b/src/types.tsxindex 7488b1cf20afe36b5c585fbfcd369471fdb6ab8d..f4bd78e48c687024ba84e998fac79e9eb16f1a80 100644--- a/src/types.tsx+++ b/src/types.tsx@@ -1156,6 +1156,13 @@ export type NativeStackHeaderItemSpacing = {  */ export type NativeStackHeaderItemCustom = {   type: 'custom';+  /**+   * An identifier used to match items across transitions.+   * Only available from iOS 26.0 and later.+   *+   * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/identifier+   */+  identifier?: string;   /**    * A React Element to display as the item.    */diff --git a/src/views/useHeaderConfigProps.tsx b/src/views/useHeaderConfigProps.tsxindex 3f3fff405048b3c2250afbe99dd7f35cecb9a6d5..bb062b898cfa77f8c02f951dc9d81b51672d7d0e 100644--- a/src/views/useHeaderConfigProps.tsx+++ b/src/views/useHeaderConfigProps.tsx@@ -397,6 +397,7 @@ export function useHeaderConfigProps({                     // eslint-disable-next-line @eslint-react/no-array-index-key                     key={index}                     hidesSharedBackground={item.hidesSharedBackground}+                    identifier={item.identifier}                   >                     {item.element}                   </ScreenStackHeaderLeftView>@@ -471,6 +472,7 @@ export function useHeaderConfigProps({                 // eslint-disable-next-line @eslint-react/no-array-index-key                 key={index}                 hidesSharedBackground={item.hidesSharedBackground}+                identifier={item.identifier}               >                 {item.element}               </ScreenStackHeaderRightView>