| author | |
| committer | |
| log | 053affbed2659f90cd1b1efaaa7a75865c4131c7 |
| tree | e1a151cd1682cb866c5afdb2b2615bdb48ea8292 |
| parent | 074bcd6dc897f9c28b1bbc04737daa6ee3d8e40f |
| signature | Signed by PGP key B5690EEEBB952194 |
7 files changed, 96 insertions(+), 100 deletions(-)
apps/mobile/src/components/CompactBrandTitle.tsx+4-38| ... | ... | @@ -1,32 +1,18 @@ |
| 1 | 1 | import Constants from "expo-constants"; |
| 2 | import type { | |
| 3 | NativeStackHeaderItem, | |
| 4 | NativeStackNavigationOptions, | |
| 5 | } from "@react-navigation/native-stack"; | |
| 2 | import type { NativeStackNavigationOptions } from "@react-navigation/native-stack"; | |
| 6 | 3 | import { Platform, View } from "react-native"; |
| 7 | 4 | |
| 8 | 5 | import { AppText as Text } from "./AppText"; |
| 9 | 6 | import { T3Wordmark } from "./T3Wordmark"; |
| 10 | 7 | import { IPAD_HOME_TITLE_OFFSET } from "../lib/layoutMetrics"; |
| 11 | 8 | import { resolveMobileStageLabel } from "../lib/mobileBranding"; |
| 12 | import { NATIVE_LIQUID_GLASS_SUPPORTED } from "../native/native-glass"; | |
| 13 | ||
| 14 | // Native leading items inherit different UIKit margins than title views. | |
| 15 | const IOS_NATIVE_LEADING_TITLE_OFFSET = -6; | |
| 16 | const IPAD_NATIVE_LEADING_TITLE_OFFSET = 7; | |
| 17 | ||
| 18 | // Branding and connection status share an identity distinct from navigation buttons. | |
| 19 | export const BRAND_HEADER_ITEM_IDENTIFIER = "workspace-brand"; | |
| 20 | 9 | |
| 21 | 10 | /** |
| 22 | 11 | * Horizontal correction applied to content rendered in the brand title slot, |
| 23 | 12 | * shared with the connection-status swap so both align identically. |
| 24 | 13 | */ |
| 25 | export function brandTitleOffset(nativeLeadingItem: boolean): number { | |
| 14 | export function brandTitleOffset(): number { | |
| 26 | 15 | if (Platform.OS !== "ios") return 0; |
| 27 | if (nativeLeadingItem) { | |
| 28 | return Platform.isPad ? IPAD_NATIVE_LEADING_TITLE_OFFSET : IOS_NATIVE_LEADING_TITLE_OFFSET; | |
| 29 | } | |
| 30 | 16 | return Platform.isPad ? IPAD_HOME_TITLE_OFFSET : 0; |
| 31 | 17 | } |
| 32 | 18 | |
| ... | ... | @@ -36,11 +22,10 @@ export function brandTitleOffset(nativeLeadingItem: boolean): number { |
| 36 | 22 | export function CompactBrandTitle( |
| 37 | 23 | props: { |
| 38 | 24 | readonly allowFontScaling?: boolean; |
| 39 | readonly nativeLeadingItem?: boolean; | |
| 40 | 25 | } = {}, |
| 41 | 26 | ) { |
| 42 | 27 | const stageLabel = resolveMobileStageLabel(Constants.expoConfig?.extra?.appVariant); |
| 43 | const titleOffset = brandTitleOffset(props.nativeLeadingItem === true); | |
| 28 | const titleOffset = brandTitleOffset(); | |
| 44 | 29 | |
| 45 | 30 | return ( |
| 46 | 31 | <View |
| ... | ... | @@ -74,32 +59,13 @@ export function renderCompactBrandTitle() { |
| 74 | 59 | return <CompactBrandTitle allowFontScaling={Platform.OS === "ios"} />; |
| 75 | 60 | } |
| 76 | 61 | |
| 77 | export function renderCompactBrandHeaderItems(): NativeStackHeaderItem[] { | |
| 78 | return [ | |
| 79 | { | |
| 80 | element: <CompactBrandTitle nativeLeadingItem />, | |
| 81 | hidesSharedBackground: true, | |
| 82 | identifier: BRAND_HEADER_ITEM_IDENTIFIER, | |
| 83 | type: "custom", | |
| 84 | }, | |
| 85 | ]; | |
| 86 | } | |
| 87 | ||
| 88 | 62 | export function getCompactBrandHeaderOptions( |
| 89 | 63 | fallbackTitleStyle?: NativeStackNavigationOptions["headerTitleStyle"], |
| 90 | 64 | ): NativeStackNavigationOptions { |
| 91 | if (Platform.OS === "ios" && NATIVE_LIQUID_GLASS_SUPPORTED) { | |
| 92 | return { | |
| 93 | headerTitle: "Threads", | |
| 94 | headerTitleStyle: { color: "transparent", fontSize: 18, fontWeight: "800" }, | |
| 95 | title: "Threads", | |
| 96 | unstable_headerLeftItems: renderCompactBrandHeaderItems, | |
| 97 | }; | |
| 98 | } | |
| 99 | ||
| 100 | 65 | return { |
| 101 | 66 | headerTitle: renderCompactBrandTitle, |
| 102 | 67 | headerTitleStyle: fallbackTitleStyle, |
| 103 | 68 | title: "Threads", |
| 69 | unstable_headerLeftItems: undefined, | |
| 104 | 70 | }; |
| 105 | 71 | } |
apps/mobile/src/features/home/HomeRouteScreen.tsx+4-1| ... | ... | @@ -2,7 +2,7 @@ import * as Arr from "effect/Array"; |
| 2 | 2 | import * as Order from "effect/Order"; |
| 3 | 3 | import { useNavigation } from "@react-navigation/native"; |
| 4 | 4 | import { useEffect, useMemo, useState } from "react"; |
| 5 | import { Platform } from "react-native"; | |
| 5 | import { Platform, useWindowDimensions } from "react-native"; | |
| 6 | 6 | |
| 7 | 7 | import { NativeHeaderToolbar, NativeStackScreenOptions } from "../../native/StackHeader"; |
| 8 | 8 | import { useProjects, useThreadShells } from "../../state/entities"; |
| ... | ... | @@ -25,6 +25,7 @@ import { getConnectionAwareBrandHeaderOptions } from "./WorkspaceConnectionTitle |
| 25 | 25 | /* ─── Route screen ───────────────────────────────────────────────────── */ |
| 26 | 26 | |
| 27 | 27 | export function HomeRouteScreen() { |
| 28 | const { width: windowWidth } = useWindowDimensions(); | |
| 28 | 29 | const { layout } = useAdaptiveWorkspaceLayout(); |
| 29 | 30 | const projects = useProjects(); |
| 30 | 31 | const threads = useThreadShells(); |
| ... | ... | @@ -138,8 +139,10 @@ export function HomeRouteScreen() { |
| 138 | 139 | shallow-merged. The brand slot also doubles as the connection |
| 139 | 140 | status surface while an environment reconnects. */} |
| 140 | 141 | <NativeStackScreenOptions |
| 142 | optionsVersion={windowWidth} | |
| 141 | 143 | options={{ |
| 142 | 144 | ...getConnectionAwareBrandHeaderOptions({ |
| 145 | headerWidth: windowWidth, | |
| 143 | 146 | onOpenEnvironments: () => |
| 144 | 147 | navigation.navigate("SettingsSheet", { |
| 145 | 148 | screen: "SettingsContent", |
apps/mobile/src/features/home/WorkspaceConnectionTitle.tsx+21-35| ... | ... | @@ -1,18 +1,14 @@ |
| 1 | import type { | |
| 2 | NativeStackHeaderItem, | |
| 3 | NativeStackNavigationOptions, | |
| 4 | } from "@react-navigation/native-stack"; | |
| 1 | import type { NativeStackNavigationOptions } from "@react-navigation/native-stack"; | |
| 5 | 2 | import { useEffect, useRef, useState, type ReactNode } from "react"; |
| 6 | import { ActivityIndicator, Animated, Platform, Pressable, View } from "react-native"; | |
| 3 | import { ActivityIndicator, Animated, Pressable, View } from "react-native"; | |
| 7 | 4 | |
| 8 | 5 | import { SymbolView } from "../../components/AppSymbol"; |
| 9 | 6 | import { AppText as Text } from "../../components/AppText"; |
| 10 | 7 | import { |
| 11 | BRAND_HEADER_ITEM_IDENTIFIER, | |
| 12 | 8 | brandTitleOffset, |
| 13 | 9 | CompactBrandTitle, |
| 10 | getCompactBrandHeaderOptions, | |
| 14 | 11 | } from "../../components/CompactBrandTitle"; |
| 15 | import { NATIVE_LIQUID_GLASS_SUPPORTED } from "../../native/native-glass"; | |
| 16 | 12 | import { useWorkspaceState } from "../../state/workspace"; |
| 17 | 13 | import { |
| 18 | 14 | workspaceConnectionStatusPresentation, |
| ... | ... | @@ -55,7 +51,11 @@ function useDelayedConnectionStatus(): WorkspaceConnectionStatusPresentation | n |
| 55 | 51 | * native-driver animated nodes blank the re-hosted view entirely. The JS driver |
| 56 | 52 | * updates opacity through the ordinary style path, which those subviews handle. |
| 57 | 53 | */ |
| 58 | function StatusFadeIn(props: { readonly children: ReactNode; readonly grow?: boolean }) { | |
| 54 | function StatusFadeIn(props: { | |
| 55 | readonly children: ReactNode; | |
| 56 | readonly grow?: boolean; | |
| 57 | readonly maxWidth?: number; | |
| 58 | }) { | |
| 59 | 59 | const opacity = useRef(new Animated.Value(0)).current; |
| 60 | 60 | |
| 61 | 61 | useEffect(() => { |
| ... | ... | @@ -71,7 +71,7 @@ function StatusFadeIn(props: { readonly children: ReactNode; readonly grow?: boo |
| 71 | 71 | return ( |
| 72 | 72 | <Animated.View |
| 73 | 73 | style={[ |
| 74 | { alignItems: "center", flexDirection: "row", opacity }, | |
| 74 | { alignItems: "center", flexDirection: "row", maxWidth: props.maxWidth, opacity }, | |
| 75 | 75 | props.grow ? { flex: 1, minWidth: 0 } : null, |
| 76 | 76 | ]} |
| 77 | 77 | > |
| ... | ... | @@ -100,6 +100,8 @@ export function WorkspaceConnectionTitle(props: { |
| 100 | 100 | readonly size?: "navbar" | "pageTitle"; |
| 101 | 101 | /** Horizontal correction so the status aligns with the brand in native title slots. */ |
| 102 | 102 | readonly statusOffset?: number; |
| 103 | /** Space available beside the native header actions. */ | |
| 104 | readonly maxWidth?: number; | |
| 103 | 105 | }) { |
| 104 | 106 | const status = useDelayedConnectionStatus(); |
| 105 | 107 | const size = props.size ?? "navbar"; |
| ... | ... | @@ -115,7 +117,7 @@ export function WorkspaceConnectionTitle(props: { |
| 115 | 117 | } |
| 116 | 118 | |
| 117 | 119 | return ( |
| 118 | <StatusFadeIn grow={props.grow}> | |
| 120 | <StatusFadeIn grow={props.grow} maxWidth={props.maxWidth}> | |
| 119 | 121 | <Pressable |
| 120 | 122 | accessibilityHint="Opens environment settings" |
| 121 | 123 | accessibilityLabel={status.label} |
| ... | ... | @@ -124,7 +126,7 @@ export function WorkspaceConnectionTitle(props: { |
| 124 | 126 | hitSlop={8} |
| 125 | 127 | onPress={props.onPress} |
| 126 | 128 | className="flex-row items-center gap-2" |
| 127 | style={{ marginLeft: props.statusOffset ?? 0 }} | |
| 129 | style={{ flexShrink: 1, marginLeft: props.statusOffset ?? 0 }} | |
| 128 | 130 | > |
| 129 | 131 | {status.showsProgress ? ( |
| 130 | 132 | <ActivityIndicator colorClassName={"accent-icon-muted"} size="small" /> |
| ... | ... | @@ -158,40 +160,24 @@ export function WorkspaceConnectionTitle(props: { |
| 158 | 160 | * this over the static brand options at mount. |
| 159 | 161 | */ |
| 160 | 162 | export function getConnectionAwareBrandHeaderOptions(opts: { |
| 163 | readonly headerWidth: number; | |
| 164 | readonly trailingItemCount?: number; | |
| 161 | 165 | readonly onOpenEnvironments: () => void; |
| 162 | 166 | readonly fallbackTitleStyle?: NativeStackNavigationOptions["headerTitleStyle"]; |
| 163 | 167 | }): NativeStackNavigationOptions { |
| 164 | if (Platform.OS === "ios" && NATIVE_LIQUID_GLASS_SUPPORTED) { | |
| 165 | return { | |
| 166 | headerTitle: "Threads", | |
| 167 | headerTitleStyle: { color: "transparent", fontSize: 18, fontWeight: "800" }, | |
| 168 | title: "Threads", | |
| 169 | unstable_headerLeftItems: (): NativeStackHeaderItem[] => [ | |
| 170 | { | |
| 171 | element: ( | |
| 172 | <WorkspaceConnectionTitle | |
| 173 | brand={<CompactBrandTitle nativeLeadingItem />} | |
| 174 | onPress={opts.onOpenEnvironments} | |
| 175 | statusOffset={brandTitleOffset(true)} | |
| 176 | /> | |
| 177 | ), | |
| 178 | hidesSharedBackground: true, | |
| 179 | identifier: BRAND_HEADER_ITEM_IDENTIFIER, | |
| 180 | type: "custom", | |
| 181 | }, | |
| 182 | ], | |
| 183 | }; | |
| 184 | } | |
| 168 | // Leave room for bar margins, title spacing and the 44-point native actions. | |
| 169 | // Long status labels must not push Settings into UIKit's overflow menu. | |
| 170 | const maxWidth = Math.max(0, opts.headerWidth - 64 - 44 * (opts.trailingItemCount ?? 1)); | |
| 185 | 171 | |
| 186 | 172 | return { |
| 173 | ...getCompactBrandHeaderOptions(opts.fallbackTitleStyle), | |
| 187 | 174 | headerTitle: () => ( |
| 188 | 175 | <WorkspaceConnectionTitle |
| 189 | 176 | brand={<CompactBrandTitle />} |
| 177 | maxWidth={maxWidth} | |
| 190 | 178 | onPress={opts.onOpenEnvironments} |
| 191 | statusOffset={brandTitleOffset(false)} | |
| 179 | statusOffset={brandTitleOffset()} | |
| 192 | 180 | /> |
| 193 | 181 | ), |
| 194 | headerTitleStyle: opts.fallbackTitleStyle, | |
| 195 | title: "Threads", | |
| 196 | 182 | }; |
| 197 | 183 | } |
apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx+3-1| ... | ... | @@ -1158,12 +1158,14 @@ function ThreadNavigationSidebarPane( |
| 1158 | 1158 | return ( |
| 1159 | 1159 | <> |
| 1160 | 1160 | <NativeStackScreenOptions |
| 1161 | optionsVersion={nativeHeaderItems} | |
| 1161 | optionsVersion={[nativeHeaderItems, props.width]} | |
| 1162 | 1162 | options={{ |
| 1163 | 1163 | // Re-applies the shell's static brand slot with the |
| 1164 | 1164 | // connection-status swap so reconnects surface in the header |
| 1165 | 1165 | // instead of shifting the list. |
| 1166 | 1166 | ...getConnectionAwareBrandHeaderOptions({ |
| 1167 | headerWidth: props.width, | |
| 1168 | trailingItemCount: nativeHeaderItems.length, | |
| 1167 | 1169 | onOpenEnvironments: props.onOpenEnvironmentSettings, |
| 1168 | 1170 | fallbackTitleStyle: { fontSize: 18, fontWeight: "800" }, |
| 1169 | 1171 | }), |
docs/internals/mobile-navigation.md+24-12| ... | ... | @@ -5,23 +5,30 @@ The iOS Home and thread routes share the root native stack in |
| 5 | 5 | controller lets UIKit animate the header between routes. The iPad sidebar owns |
| 6 | 6 | a separate, single-screen stack; Android uses its own in-flow headers. |
| 7 | 7 | |
| 8 | On Liquid Glass iOS, Home keeps a transparent native title and renders its brand | |
| 9 | as a custom leading item. A custom `headerTitle` previously shortened the scroll | |
| 10 | fade and removed the blur behind the logo. Preserve the native title when | |
| 11 | changing the brand or its connection-status replacement. | |
| 12 | ||
| 13 | Both brand states use `BRAND_HEADER_ITEM_IDENTIFIER` from | |
| 14 | [`CompactBrandTitle.tsx`](../../apps/mobile/src/components/CompactBrandTitle.tsx). | |
| 15 | The native-stack and react-native-screens patches forward custom item identifiers | |
| 16 | to `UIBarButtonItem.identifier`, just as they do for native buttons and menus. | |
| 17 | UIKit otherwise matches transition items using their position and content, so | |
| 18 | the brand needs an explicit identity separate from navigation controls. Connection | |
| 19 | status changes retain that identity. See [Apple's identifier documentation](https://developer.apple.com/documentation/uikit/uibarbuttonitem/identifier). | |
| 8 | Home and the iPad sidebar render their brand and connection status through | |
| 9 | `headerTitle`, with `Threads` retained as the route title. The editor-style native | |
| 10 | bar aligns that title on the leading side. Do not model the brand as a toolbar | |
| 11 | button: on iOS 26.5 UIKit morphs a background-free custom leading item's rectangle | |
| 12 | into the next screen's glass back button, even with distinct item identifiers. | |
| 13 | Using the title slot lets the brand and native back button animate separately. | |
| 14 | ||
| 15 | The connection-status title has a maximum width based on its header's width and | |
| 16 | trailing actions. A long environment name or larger text must not push Settings | |
| 17 | into UIKit's overflow menu. Keep the full status as the accessibility label | |
| 18 | while visually truncating it. The iPad sidebar uses its pane width, not the full | |
| 19 | window width. | |
| 20 | ||
| 21 | On iOS 26, UIKit does not recognize Fabric's custom text views when shaping the | |
| 22 | native scroll-edge fade. The screens patch gives custom title subviews an empty, | |
| 23 | non-interactive native label matching their bounds. This supplies the fade's | |
| 24 | geometry without drawing anything or turning the title back into a toolbar item. | |
| 25 | Check the top scroll fade as well as push/pop when changing these title views. | |
| 20 | 26 | |
| 21 | 27 | The react-native-screens patch caches leading, trailing, and center item groups |
| 22 | 28 | independently. A button can belong to only one group: constructing another group |
| 23 | 29 | with the same button removes it from the previous one. Unrelated menu updates |
| 24 | 30 | must therefore preserve the other groups while UIKit may be animating them. |
| 31 | ||
| 25 | 32 | Each cache includes the owning header config, its item values, and custom native |
| 26 | 33 | item identities, so changed content or remounted event emitters still rebuild. |
| 27 | 34 | |
| ... | ... | @@ -29,3 +36,8 @@ Custom header identifiers require native code generation and a new mobile build; |
| 29 | 36 | an over-the-air JavaScript update alone is insufficient. The Android view manager |
| 30 | 37 | implements the generated identifier setter as a no-op because this behavior is |
| 31 | 38 | specific to iOS 26 and later. |
| 39 | ||
| 40 | After changing a dependency patch, refresh CocoaPods before rebuilding an | |
| 41 | existing iOS project. pnpm installs each patch hash in a different directory; | |
| 42 | an old Pods project can keep compiling the previous directory even though Metro | |
| 43 | and `apps/mobile/node_modules` resolve to the new patch. |
patches/react-native-screens@4.26.2.patch+34-7| ... | ... | @@ -1107,18 +1107,45 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..a60b96b44e85d3f4b29dc0d190b95ab6 |
| 1107 | 1107 | |
| 1108 | 1108 | if (needsNavigationControllerLayout) { |
| 1109 | 1109 | diff --git a/ios/RNSScreenStackHeaderSubview.mm b/ios/RNSScreenStackHeaderSubview.mm |
| 1110 | index add33c4807e038dcd846f6c72b2fc472ded02809..9a7c7a8a775579c85de39f921e7a362241a72075 100644 | |
| 1110 | index add33c4807e038dcd846f6c72b2fc472ded02809..489afa5fa2da09c1ec6986d1832b58bb595396ae 100644 | |
| 1111 | 1111 | --- a/ios/RNSScreenStackHeaderSubview.mm |
| 1112 | 1112 | +++ b/ios/RNSScreenStackHeaderSubview.mm |
| 1113 | @@ -20,6 +20,7 @@ @implementation RNSScreenStackHeaderSubview { | |
| 1113 | @@ -20,7 +20,9 @@ @implementation RNSScreenStackHeaderSubview { | |
| 1114 | 1114 | // This is a strong reference to UIBarButtonItem which creates a retain cycle. |
| 1115 | 1115 | // The cycle is cleared via `invalidateUIBarButtonItem` method, called by `invalidate` callback. |
| 1116 | 1116 | UIBarButtonItem *_barButtonItem; |
| 1117 | 1117 | + NSString *_barButtonItemIdentifier; |
| 1118 | 1118 | BOOL _hidesSharedBackground; |
| 1119 | + UILabel *_titleScrollEdgeEffectGuide; | |
| 1119 | 1120 | } |
| 1120 | 1121 | |
| 1121 | @@ -124,6 +125,7 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props:: | |
| 1122 | #pragma mark - Common | |
| 1123 | @@ -102,5 +104,24 @@ - (void)updateShadowStateWithFrame:(CGRect)frame | |
| 1124 | - (void)layoutSubviews | |
| 1125 | { | |
| 1126 | [super layoutSubviews]; | |
| 1127 | +#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) | |
| 1128 | + if (@available(iOS 26.0, *)) { | |
| 1129 | + if (_type == RNSScreenStackHeaderSubviewTypeTitle || _type == RNSScreenStackHeaderSubviewTypeCenter) { | |
| 1130 | + // UIKit shapes the navigation bar's scroll-edge fade around native labels, | |
| 1131 | + // but does not recognize Fabric's custom text views. An empty, non-interactive | |
| 1132 | + // label supplies the title's geometry without drawing or becoming a bar item. | |
| 1133 | + if (_titleScrollEdgeEffectGuide == nil) { | |
| 1134 | + _titleScrollEdgeEffectGuide = [UILabel new]; | |
| 1135 | + _titleScrollEdgeEffectGuide.accessibilityElementsHidden = YES; | |
| 1136 | + // Append after Fabric's children so their mount/unmount indices stay intact. | |
| 1137 | + [self addSubview:_titleScrollEdgeEffectGuide]; | |
| 1138 | + } | |
| 1139 | + _titleScrollEdgeEffectGuide.frame = self.bounds; | |
| 1140 | + } else { | |
| 1141 | + [_titleScrollEdgeEffectGuide removeFromSuperview]; | |
| 1142 | + _titleScrollEdgeEffectGuide = nil; | |
| 1143 | + } | |
| 1144 | + } | |
| 1145 | +#endif | |
| 1146 | [self updateShadowStateInContextOfAncestorView:[self findNavigationBar]]; | |
| 1147 | } | |
| 1148 | @@ -124,6 +145,7 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props:: | |
| 1122 | 1149 | const auto &newHeaderSubviewProps = *std::static_pointer_cast<const react::RNSScreenStackHeaderSubviewProps>(props); |
| 1123 | 1150 | |
| 1124 | 1151 | [self setType:[RNSConvert RNSScreenStackHeaderSubviewTypeFromCppEquivalent:newHeaderSubviewProps.type]]; |
| ... | ... | @@ -1126,7 +1153,7 @@ index add33c4807e038dcd846f6c72b2fc472ded02809..9a7c7a8a775579c85de39f921e7a3622 |
| 1126 | 1153 | [self setHidesSharedBackground:newHeaderSubviewProps.hidesSharedBackground]; |
| 1127 | 1154 | [self setSynchronousShadowStateUpdatesEnabled:newHeaderSubviewProps.synchronousShadowStateUpdatesEnabled]; |
| 1128 | 1155 | [super updateProps:props oldProps:oldProps]; |
| 1129 | @@ -276,7 +278,14 @@ - (void)configureBarButtonItem | |
| 1156 | @@ -276,7 +298,14 @@ - (void)configureBarButtonItem | |
| 1130 | 1157 | #if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) |
| 1131 | 1158 | if (@available(iOS 26.0, *)) { |
| 1132 | 1159 | if (_barButtonItem != nil) { |
| ... | ... | @@ -1142,7 +1169,7 @@ index add33c4807e038dcd846f6c72b2fc472ded02809..9a7c7a8a775579c85de39f921e7a3622 |
| 1142 | 1169 | } |
| 1143 | 1170 | } |
| 1144 | 1171 | #endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) |
| 1145 | @@ -284,10 +293,22 @@ - (void)configureBarButtonItem | |
| 1172 | @@ -284,10 +313,22 @@ - (void)configureBarButtonItem | |
| 1146 | 1173 | |
| 1147 | 1174 | - (void)setHidesSharedBackground:(BOOL)hidesSharedBackground |
| 1148 | 1175 | { |
| ... | ... | @@ -1166,7 +1193,7 @@ index add33c4807e038dcd846f6c72b2fc472ded02809..9a7c7a8a775579c85de39f921e7a3622 |
| 1166 | 1193 | |
| 1167 | 1194 | // Needed because of this: https://github.com/facebook/react-native/pull/37274 |
| 1168 | 1195 | diff --git a/lib/commonjs/components/ScreenStackHeaderConfig.js b/lib/commonjs/components/ScreenStackHeaderConfig.js |
| 1169 | index 8c509f2657105cfd86448347c1a01fb73651ff9e..5e3b5185c0ea33c6b98f5daed69239d2c0d0ce90 100644 | |
| 1196 | index 8c509f2657105cfd86448347c1a01fb73651ff9e..e668e089a1788973cb122a150be7846364a2a2cf 100644 | |
| 1170 | 1197 | --- a/lib/commonjs/components/ScreenStackHeaderConfig.js |
| 1171 | 1198 | +++ b/lib/commonjs/components/ScreenStackHeaderConfig.js |
| 1172 | 1199 | @@ -26,17 +26,42 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_ |
| ... | ... | @@ -1338,7 +1365,7 @@ index ab93f62e4a7049d63c6681cecbd6cf8b1d07ce10..9dca2ab640e92161eb647b819a989acd |
| 1338 | 1365 | //# sourceMappingURL=prepareHeaderBarButtonItems.js.map |
| 1339 | 1366 | \ No newline at end of file |
| 1340 | 1367 | diff --git a/lib/module/components/ScreenStackHeaderConfig.js b/lib/module/components/ScreenStackHeaderConfig.js |
| 1341 | index 68e3ba6a78314aba908d07098bb6982d11e6ee80..b787b3cf0284ffb81c80360a06c4059277bf4c1e 100644 | |
| 1368 | index 68e3ba6a78314aba908d07098bb6982d11e6ee80..db5d17bfdac19ed3e664b55b6a73ce49766ac7c5 100644 | |
| 1342 | 1369 | --- a/lib/module/components/ScreenStackHeaderConfig.js |
| 1343 | 1370 | +++ b/lib/module/components/ScreenStackHeaderConfig.js |
| 1344 | 1371 | @@ -22,17 +22,42 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref |
pnpm-lock.yaml+6-6| ... | ... | @@ -94,7 +94,7 @@ patchedDependencies: |
| 94 | 94 | react-native-gesture-handler@2.32.0: 808eb26f9e57cf4945efd3985af4d9c764da6f91f4c9764433cc868602bbf4d3 |
| 95 | 95 | react-native-keyboard-controller@1.21.13: 20be72c84d74253acdcfefbc6defe36dc396944f1a44cab2bdd0e3cd572ae008 |
| 96 | 96 | react-native-nitro-modules@0.35.9: 825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675 |
| 97 | react-native-screens@4.26.2: 5d2e7beefe55f0b7ee157993cbc0ec38d32aa558e4e780764381fe8f96ba728d | |
| 97 | react-native-screens@4.26.2: 149bef30a66351ea9b26b42f87b78c539cb52b880f2387bb323ec80dcac84006 | |
| 98 | 98 | |
| 99 | 99 | importers: |
| 100 | 100 | |
| ... | ... | @@ -248,7 +248,7 @@ importers: |
| 248 | 248 | version: 7.3.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) |
| 249 | 249 | '@react-navigation/native-stack': |
| 250 | 250 | specifier: 7.17.6 |
| 251 | version: 7.17.6(patch_hash=e667c3cef8c78bb9ff4882ee5bd23a432247b843060a9499eb5f07e9e2295552)(1d8c6f507069f6f6aada9b6419c84a6c) | |
| 251 | version: 7.17.6(patch_hash=e667c3cef8c78bb9ff4882ee5bd23a432247b843060a9499eb5f07e9e2295552)(d307537762dff86bcf277a4ec64a11d8) | |
| 252 | 252 | '@shikijs/core': |
| 253 | 253 | specifier: 4.2.0 |
| 254 | 254 | version: 4.2.0 |
| ... | ... | @@ -416,7 +416,7 @@ importers: |
| 416 | 416 | version: 5.7.0(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) |
| 417 | 417 | react-native-screens: |
| 418 | 418 | specifier: ~4.26.0 |
| 419 | version: 4.26.2(patch_hash=5d2e7beefe55f0b7ee157993cbc0ec38d32aa558e4e780764381fe8f96ba728d)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) | |
| 419 | version: 4.26.2(patch_hash=149bef30a66351ea9b26b42f87b78c539cb52b880f2387bb323ec80dcac84006)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) | |
| 420 | 420 | react-native-shiki-engine: |
| 421 | 421 | specifier: ^0.3.12 |
| 422 | 422 | version: 0.3.12(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) |
| ... | ... | @@ -13880,7 +13880,7 @@ snapshots: |
| 13880 | 13880 | optionalDependencies: |
| 13881 | 13881 | '@react-native-masked-view/masked-view': 0.3.2(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) |
| 13882 | 13882 | |
| 13883 | '@react-navigation/native-stack@7.17.6(patch_hash=e667c3cef8c78bb9ff4882ee5bd23a432247b843060a9499eb5f07e9e2295552)(1d8c6f507069f6f6aada9b6419c84a6c)': | |
| 13883 | '@react-navigation/native-stack@7.17.6(patch_hash=e667c3cef8c78bb9ff4882ee5bd23a432247b843060a9499eb5f07e9e2295552)(d307537762dff86bcf277a4ec64a11d8)': | |
| 13884 | 13884 | dependencies: |
| 13885 | 13885 | '@react-navigation/elements': 2.9.26(c10301b6e0c42fc6434d2b643197a81e) |
| 13886 | 13886 | '@react-navigation/native': 7.3.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) |
| ... | ... | @@ -13888,7 +13888,7 @@ snapshots: |
| 13888 | 13888 | react: 19.2.3 |
| 13889 | 13889 | react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) |
| 13890 | 13890 | react-native-safe-area-context: 5.7.0(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) |
| 13891 | react-native-screens: 4.26.2(patch_hash=5d2e7beefe55f0b7ee157993cbc0ec38d32aa558e4e780764381fe8f96ba728d)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) | |
| 13891 | react-native-screens: 4.26.2(patch_hash=149bef30a66351ea9b26b42f87b78c539cb52b880f2387bb323ec80dcac84006)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) | |
| 13892 | 13892 | sf-symbols-typescript: 2.2.0 |
| 13893 | 13893 | warn-once: 0.1.1 |
| 13894 | 13894 | transitivePeerDependencies: |
| ... | ... | @@ -19492,7 +19492,7 @@ snapshots: |
| 19492 | 19492 | react: 19.2.3 |
| 19493 | 19493 | react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) |
| 19494 | 19494 | |
| 19495 | react-native-screens@4.26.2(patch_hash=5d2e7beefe55f0b7ee157993cbc0ec38d32aa558e4e780764381fe8f96ba728d)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): | |
| 19495 | react-native-screens@4.26.2(patch_hash=149bef30a66351ea9b26b42f87b78c539cb52b880f2387bb323ec80dcac84006)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): | |
| 19496 | 19496 | dependencies: |
| 19497 | 19497 | react: 19.2.3 |
| 19498 | 19498 | react-freeze: 1.0.4(react@19.2.3) |