expo-router 55.0.0 → 55.0.1
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.
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/router/ExpoRouterModule.kt +1 -0
- package/build/layouts/stack-utils/toolbar/StackToolbarMenu.d.ts.map +1 -1
- package/build/layouts/stack-utils/toolbar/StackToolbarMenu.js +11 -6
- package/build/layouts/stack-utils/toolbar/StackToolbarMenu.js.map +1 -1
- package/build/link/LinkWithPreview.js +3 -3
- package/build/link/LinkWithPreview.js.map +1 -1
- package/build/link/zoom/ZoomTransitionEnabler.ios.d.ts +11 -0
- package/build/link/zoom/ZoomTransitionEnabler.ios.d.ts.map +1 -1
- package/build/link/zoom/ZoomTransitionEnabler.ios.js +44 -10
- package/build/link/zoom/ZoomTransitionEnabler.ios.js.map +1 -1
- package/build/link/zoom/link-apple-zoom.js +2 -2
- package/build/link/zoom/link-apple-zoom.js.map +1 -1
- package/build/link/zoom/usePreventZoomTransitionDismissal.ios.d.ts.map +1 -1
- package/build/link/zoom/usePreventZoomTransitionDismissal.ios.js +30 -7
- package/build/link/zoom/usePreventZoomTransitionDismissal.ios.js.map +1 -1
- package/build/link/zoom/zoom-transition-context-providers.ios.d.ts.map +1 -1
- package/build/link/zoom/zoom-transition-context-providers.ios.js +16 -3
- package/build/link/zoom/zoom-transition-context-providers.ios.js.map +1 -1
- package/build/link/zoom/zoom-transition-context.d.ts +5 -2
- package/build/link/zoom/zoom-transition-context.d.ts.map +1 -1
- package/build/link/zoom/zoom-transition-context.js +4 -0
- package/build/link/zoom/zoom-transition-context.js.map +1 -1
- package/build/modal/web/utils.d.ts +0 -9
- package/build/modal/web/utils.d.ts.map +1 -1
- package/build/modal/web/utils.js +3 -20
- package/build/modal/web/utils.js.map +1 -1
- package/build/utils/stackPresentation.d.ts +11 -0
- package/build/utils/stackPresentation.d.ts.map +1 -0
- package/build/utils/stackPresentation.js +28 -0
- package/build/utils/stackPresentation.js.map +1 -0
- package/expo-module.config.json +1 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1-sources.jar +0 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1-sources.jar.md5 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1-sources.jar.sha1 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1-sources.jar.sha256 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1-sources.jar.sha512 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1.aar +0 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1.aar.md5 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1.aar.sha1 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1.aar.sha256 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1.aar.sha512 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0/expo.modules.router-55.0.0.module → 55.0.1/expo.modules.router-55.0.1.module} +22 -22
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1.module.md5 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1.module.sha1 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1.module.sha256 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1.module.sha512 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0/expo.modules.router-55.0.0.pom → 55.0.1/expo.modules.router-55.0.1.pom} +1 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1.pom.md5 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1.pom.sha1 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1.pom.sha256 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.1/expo.modules.router-55.0.1.pom.sha512 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml +4 -4
- package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.md5 +1 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha1 +1 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha256 +1 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha512 +1 -1
- package/package.json +2 -2
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0-sources.jar +0 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0-sources.jar.md5 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0-sources.jar.sha1 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0-sources.jar.sha256 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0-sources.jar.sha512 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.aar +0 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.aar.md5 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.aar.sha1 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.aar.sha256 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.aar.sha512 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.module.md5 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.module.sha1 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.module.sha256 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.module.sha512 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.pom.md5 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.pom.sha1 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.pom.sha256 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.pom.sha512 +0 -1
- package/plugin/tsconfig.tsbuildinfo +0 -1
package/android/build.gradle
CHANGED
|
@@ -4,13 +4,13 @@ plugins {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
group = 'expo.modules.router'
|
|
7
|
-
version = '55.0.
|
|
7
|
+
version = '55.0.1'
|
|
8
8
|
|
|
9
9
|
android {
|
|
10
10
|
namespace "expo.modules.router"
|
|
11
11
|
defaultConfig {
|
|
12
12
|
versionCode 1
|
|
13
|
-
versionName "55.0.
|
|
13
|
+
versionName "55.0.1"
|
|
14
14
|
}
|
|
15
15
|
lintOptions {
|
|
16
16
|
abortOnError false
|
|
@@ -114,6 +114,7 @@ class ExpoRouterModule : Module() {
|
|
|
114
114
|
"onerrorcontainer" to com.google.android.material.R.attr.colorOnErrorContainer,
|
|
115
115
|
"outline" to com.google.android.material.R.attr.colorOutline,
|
|
116
116
|
"outlinevariant" to com.google.android.material.R.attr.colorOutlineVariant,
|
|
117
|
+
"background" to android.R.attr.colorBackground,
|
|
117
118
|
"onbackground" to com.google.android.material.R.attr.colorOnBackground,
|
|
118
119
|
"surface" to com.google.android.material.R.attr.colorSurface,
|
|
119
120
|
"onsurface" to com.google.android.material.R.attr.colorOnSurface,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StackToolbarMenu.d.ts","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,yBAAyB,EACzB,+BAA+B,EAEhC,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAA4B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAGL,KAAK,mBAAmB,EAGzB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"StackToolbarMenu.d.ts","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu.tsx"],"names":[],"mappings":"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"}
|
|
@@ -118,6 +118,15 @@ function convertStackToolbarMenuPropsToRNHeaderItem(props, isBottomPlacement = f
|
|
|
118
118
|
}
|
|
119
119
|
return item;
|
|
120
120
|
}
|
|
121
|
+
// Custom menu action icons are not supported in react-navigation yet
|
|
122
|
+
// But they are supported in react-native-screens
|
|
123
|
+
// TODO(@ubax): Remove this workaround once react-navigation supports custom icons for menu actions.
|
|
124
|
+
// https://linear.app/expo/issue/ENG-19853/remove-custom-conversion-logic-for-icon-from-packagesexpo
|
|
125
|
+
function convertImageIconToPlatformIcon(icon) {
|
|
126
|
+
return icon.tinted
|
|
127
|
+
? { type: 'templateSource', templateSource: icon.source }
|
|
128
|
+
: { type: 'imageSource', imageSource: icon.source };
|
|
129
|
+
}
|
|
121
130
|
function convertStackToolbarSubmenuMenuPropsToRNHeaderItem(props) {
|
|
122
131
|
if (props.hidden) {
|
|
123
132
|
return undefined;
|
|
@@ -148,13 +157,11 @@ function convertStackToolbarSubmenuMenuPropsToRNHeaderItem(props) {
|
|
|
148
157
|
}
|
|
149
158
|
// TODO: Add elementSize to react-native-screens
|
|
150
159
|
if (sharedProps.icon) {
|
|
151
|
-
// Only SF Symbols are supported in submenu icons
|
|
152
|
-
// TODO(@ubax): Add support for other images in react-native-screens
|
|
153
160
|
if (sharedProps.icon.type === 'sfSymbol') {
|
|
154
161
|
item.icon = sharedProps.icon;
|
|
155
162
|
}
|
|
156
163
|
else {
|
|
157
|
-
|
|
164
|
+
item.icon = convertImageIconToPlatformIcon(sharedProps.icon);
|
|
158
165
|
}
|
|
159
166
|
}
|
|
160
167
|
return item;
|
|
@@ -209,13 +216,11 @@ function convertStackToolbarMenuActionPropsToRNHeaderItem(props) {
|
|
|
209
216
|
item.keepsMenuPresented = unstable_keepPresented;
|
|
210
217
|
}
|
|
211
218
|
if (sharedProps.icon) {
|
|
212
|
-
// Only SF Symbols are supported in submenu icons
|
|
213
|
-
// TODO(@ubax): Add support for other images in react-native-screens
|
|
214
219
|
if (sharedProps.icon.type === 'sfSymbol') {
|
|
215
220
|
item.icon = sharedProps.icon;
|
|
216
221
|
}
|
|
217
222
|
else {
|
|
218
|
-
|
|
223
|
+
item.icon = convertImageIconToPlatformIcon(sharedProps.icon);
|
|
219
224
|
}
|
|
220
225
|
}
|
|
221
226
|
return item;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StackToolbarMenu.js","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport type {\n NativeStackHeaderItemMenu,\n NativeStackHeaderItemMenuAction,\n NativeStackHeaderItemMenuSubmenu,\n} from '@react-navigation/native-stack';\nimport type { ImageRef } from 'expo-image';\nimport { Children, useId, useMemo, type ReactNode } from 'react';\nimport {\n StyleSheet,\n type ColorValue,\n type ImageSourcePropType,\n type StyleProp,\n type TextStyle,\n} from 'react-native';\nimport type { SFSymbol } from 'sf-symbols-typescript';\n\nimport { useToolbarPlacement } from './context';\nimport {\n convertStackHeaderSharedPropsToRNSharedHeaderItem,\n extractIconRenderingMode,\n extractXcassetName,\n type StackHeaderItemSharedProps,\n} from './shared';\nimport { StackToolbarLabel, StackToolbarIcon, StackToolbarBadge } from './toolbar-primitives';\nimport { LinkMenuAction } from '../../../link/elements';\nimport { NativeLinkPreviewAction } from '../../../link/preview/native';\nimport {\n filterAllowedChildrenElements,\n getFirstChildOfType,\n isChildOfType,\n} from '../../../utils/children';\n\n/**\n * Computes the label and menu title from children and title prop.\n *\n * - If only `title` prop is provided, it is used for both the label (button text) and menu title\n * - If only `.Label` child is provided, it is used for the label and the menu title is an empty string\n * - If both `.Label` child and `title` prop are provided. `.Label` is used for the label, and `title` is used for the menu title\n */\nfunction computeMenuLabelAndTitle(\n children: ReactNode,\n title: string | undefined\n): { label: string; menuTitle: string } {\n const labelChild = getFirstChildOfType(children, StackToolbarLabel);\n const labelFromChild = labelChild?.props.children;\n return {\n label: labelFromChild ?? title ?? '',\n menuTitle: title ?? '',\n };\n}\n\nexport interface StackToolbarMenuProps {\n accessibilityLabel?: string;\n accessibilityHint?: string;\n /**\n * Menu content - can include icons, labels, badges and menu actions.\n *\n * @example\n * ```tsx\n * <Stack.Toolbar.Menu>\n * <Stack.Toolbar.Icon sfSymbol=\"ellipsis.circle\" />\n * <Stack.Toolbar.Label>Options</Stack.Toolbar.Label>\n * <Stack.Toolbar.MenuAction onPress={() => {}}>Action 1</Stack.Toolbar.MenuAction>\n * </Stack.Toolbar.Menu>\n * ```\n */\n children?: ReactNode;\n /**\n * If `true`, the menu item will be displayed as destructive.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive) for more information.\n */\n destructive?: boolean;\n disabled?: boolean;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu item.\n *\n * > **Note**: This prop is only supported in toolbar with `placement=\"bottom\"`.\n */\n image?: ImageRef;\n /**\n * Whether to hide the shared background.\n *\n * @see [Official Apple documentation](https://developer.apple.com/documentation/uikit/uibarbuttonitem/hidessharedbackground) for more information.\n *\n * @platform iOS 26+\n */\n hidesSharedBackground?: boolean;\n /**\n * Whether the menu should be hidden.\n *\n * @default false\n */\n hidden?: boolean;\n /**\n * Icon for the menu item.\n *\n * Can be an SF Symbol name or an image source.\n *\n * > **Note**: When used in `placement=\"bottom\"`, only string SFSymbols are supported. Use the `image` prop to provide custom images.\n */\n icon?: StackHeaderItemSharedProps['icon'];\n /**\n * Controls how image-based icons are rendered on iOS.\n *\n * - `'template'`: iOS applies tint color to the icon (useful for monochrome icons)\n * - `'original'`: Preserves original icon colors (useful for multi-color icons)\n *\n * **Default behavior:**\n * - If `tintColor` is specified, defaults to `'template'`\n * - If no `tintColor`, defaults to `'original'`\n *\n * This prop only affects image-based icons (not SF Symbols).\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uiimage/renderingmode-swift.enum) for more information.\n *\n * @platform ios\n */\n iconRenderingMode?: 'template' | 'original';\n /**\n * If `true`, the menu will be displayed inline.\n * This means that the menu will not be collapsed\n *\n * > **Note**: Inline menus are only supported in submenus.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayinline) for more information.\n */\n inline?: boolean;\n /**\n * If `true`, the menu will be displayed as a palette.\n * This means that the menu will be displayed as one row\n *\n * > **Note**: Palette menus are only supported in submenus.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayaspalette) for more information.\n */\n palette?: boolean;\n /**\n * Whether to separate the background of this item from other header items.\n *\n * @default false\n */\n separateBackground?: boolean;\n /**\n * Style for the label of the header item.\n */\n style?: StackHeaderItemSharedProps['style'];\n /**\n * The tint color to apply to the button item\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uibarbuttonitem/tintcolor) for more information.\n */\n tintColor?: StackHeaderItemSharedProps['tintColor'];\n /**\n * Optional title to show on top of the menu.\n */\n title?: string;\n /**\n * @default 'plain'\n */\n variant?: StackHeaderItemSharedProps['variant'];\n // TODO(@ubax): Add elementSize support in react-native-screens for header menus.\n /**\n * The preferred size of the menu elements.\n *\n * > **Note**: This prop is only supported in `Stack.Toolbar.Bottom`.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/preferredelementsize) for more information.\n *\n * @platform iOS 16.0+\n */\n elementSize?: 'auto' | 'small' | 'medium' | 'large';\n}\n\n/**\n * Use as `Stack.Toolbar.Menu` to provide menus in iOS toolbar.\n * It accepts `Stack.Toolbar.MenuAction` and nested `Stack.Toolbar.Menu`\n * elements. Menu can be configured using both component props and child\n * elements.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n * import { Alert } from 'react-native';\n *\n * export default function Page() {\n * return (\n * <>\n * <Stack.Toolbar placement=\"right\">\n * <Stack.Toolbar.Menu icon=\"ellipsis.circle\">\n * <Stack.Toolbar.MenuAction onPress={() => Alert.alert('Action pressed!')}>\n * Action 1\n * </Stack.Toolbar.MenuAction>\n * </Stack.Toolbar.Menu>\n * </Stack.Toolbar>\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * @see [Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/menus) for more information about menus on iOS.\n *\n * @platform ios\n */\nexport const StackToolbarMenu: React.FC<StackToolbarMenuProps> = (props) => {\n const placement = useToolbarPlacement();\n\n if (placement !== 'bottom') {\n // For placement other than bottom, this component will not render, and should be\n // converted to RN header item using convertStackToolbarMenuPropsToRNHeaderItem.\n // So if we reach here, it means we're not inside a toolbar or something else is wrong.\n throw new Error('Stack.Toolbar.Menu must be used inside a Stack.Toolbar');\n }\n\n const validChildren = useMemo(\n () => filterAllowedChildrenElements(props.children, ALLOWED_CHILDREN),\n [props.children]\n );\n\n const sharedProps = convertStackToolbarMenuPropsToRNHeaderItem(props, true);\n\n const computedLabel = sharedProps?.label;\n const computedMenuTitle = sharedProps?.menu?.title;\n const icon = sharedProps?.icon?.type === 'sfSymbol' ? sharedProps.icon.name : undefined;\n const xcassetName = extractXcassetName(props);\n const imageRenderingMode = extractIconRenderingMode(props) ?? props.iconRenderingMode;\n\n if (process.env.NODE_ENV !== 'production') {\n const allChildren = Children.toArray(props.children);\n if (allChildren.length !== validChildren.length) {\n throw new Error(\n `Stack.Toolbar.Menu only accepts Stack.Toolbar.Menu, Stack.Toolbar.MenuAction, Stack.Toolbar.Label, Stack.Toolbar.Icon, and Stack.Toolbar.Badge as its children.`\n );\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n const hasBadge = getFirstChildOfType(props.children, StackToolbarBadge);\n if (hasBadge) {\n console.warn(\n 'Stack.Toolbar.Badge is not supported in bottom toolbar (iOS limitation). The badge will be ignored.'\n );\n }\n }\n\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n return (\n <NativeToolbarMenu\n {...props}\n icon={icon}\n xcassetName={xcassetName}\n image={props.image}\n imageRenderingMode={imageRenderingMode}\n label={computedLabel}\n title={computedMenuTitle}\n children={validChildren}\n />\n );\n};\n\nexport function convertStackToolbarMenuPropsToRNHeaderItem(\n props: StackToolbarMenuProps,\n isBottomPlacement: boolean = false\n): NativeStackHeaderItemMenu | undefined {\n if (props.hidden) {\n return undefined;\n }\n const { title, ...rest } = props;\n const actions = Children.toArray(props.children).filter(\n (child) =>\n isChildOfType(child, StackToolbarMenuAction) || isChildOfType(child, StackToolbarMenu)\n );\n\n const { label: computedLabel, menuTitle: computedMenuTitle } = computeMenuLabelAndTitle(\n props.children,\n title\n );\n\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(rest, isBottomPlacement);\n\n const item: NativeStackHeaderItemMenu = {\n ...sharedProps,\n label: computedLabel,\n type: 'menu',\n menu: {\n multiselectable: true,\n items: actions\n .map((action) => {\n if (isChildOfType(action, StackToolbarMenu)) {\n return convertStackToolbarSubmenuMenuPropsToRNHeaderItem(action.props);\n }\n return convertStackToolbarMenuActionPropsToRNHeaderItem(action.props);\n })\n .filter((i) => !!i),\n },\n };\n if (computedMenuTitle) {\n item.menu.title = computedMenuTitle;\n }\n\n return item;\n}\n\nfunction convertStackToolbarSubmenuMenuPropsToRNHeaderItem(\n props: StackToolbarMenuProps\n): NativeStackHeaderItemMenuSubmenu | undefined {\n if (props.hidden) {\n return undefined;\n }\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(props);\n const actions = Children.toArray(props.children).filter(\n (child) =>\n isChildOfType(child, StackToolbarMenuAction) || isChildOfType(child, StackToolbarMenu)\n );\n\n const item: NativeStackHeaderItemMenuSubmenu = {\n type: 'submenu',\n items: actions\n .map((action) => {\n if (isChildOfType(action, StackToolbarMenu)) {\n return convertStackToolbarSubmenuMenuPropsToRNHeaderItem(action.props);\n }\n return convertStackToolbarMenuActionPropsToRNHeaderItem(action.props);\n })\n .filter((i) => !!i),\n label: sharedProps.label || props.title || '',\n multiselectable: true,\n };\n\n if (props.inline !== undefined) {\n item.inline = props.inline;\n }\n if (props.palette !== undefined) {\n item.layout = props.palette ? 'palette' : 'default';\n }\n if (props.destructive !== undefined) {\n item.destructive = props.destructive;\n }\n // TODO: Add elementSize to react-native-screens\n\n if (sharedProps.icon) {\n // Only SF Symbols are supported in submenu icons\n // TODO(@ubax): Add support for other images in react-native-screens\n if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n console.warn(\n 'When Icon is used inside Stack.Toolbar.Menu used as a submenu, only sfSymbol icons are supported. This is a limitation of React Native Screens.'\n );\n }\n }\n\n return item;\n}\n\nexport interface StackToolbarMenuActionProps {\n /**\n * Can be an Icon, Label or string title.\n */\n children?: ReactNode;\n /**\n * If `true`, the menu item will be disabled and not selectable.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/disabled) for more information.\n */\n disabled?: boolean;\n icon?: SFSymbol | ImageSourcePropType;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu action.\n *\n * > **Note**: This prop is only supported in `Stack.Toolbar.Bottom`.\n */\n image?: ImageRef;\n /**\n * Controls how image-based icons are rendered on iOS.\n *\n * - `'template'`: iOS applies tint color to the icon (useful for monochrome icons)\n * - `'original'`: Preserves original icon colors (useful for multi-color icons)\n *\n * **Default behavior:**\n * - If `tintColor` is specified, defaults to `'template'`\n * - If no `tintColor`, defaults to `'original'`\n *\n * This prop only affects image-based icons (not SF Symbols).\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uiimage/renderingmode-swift.enum) for more information.\n *\n * @platform ios\n */\n iconRenderingMode?: 'template' | 'original';\n /**\n * If `true`, the menu item will be displayed as destructive.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive) for more information.\n */\n destructive?: boolean;\n /**\n * If `true`, the menu will be kept presented after the action is selected.\n *\n * This is marked as unstable, because when action is selected it will recreate the menu,\n * which will close all opened submenus and reset the scroll position.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/keepsmenupresented) for more information.\n */\n unstable_keepPresented?: boolean;\n /**\n * If `true`, the menu item will be displayed as selected.\n */\n isOn?: boolean;\n onPress?: () => void;\n /**\n * An elaborated title that explains the purpose of the action.\n */\n discoverabilityLabel?: string;\n /**\n * An optional subtitle for the menu item.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/subtitle) for more information.\n */\n subtitle?: string;\n hidden?: boolean;\n}\n\n/**\n * An action item for a `Stack.Toolbar.Menu`.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * export default function Page() {\n * return (\n * <>\n * <Stack.Toolbar placement=\"right\">\n * <Stack.Toolbar.Menu icon=\"ellipsis.circle\">\n * <Stack.Toolbar.MenuAction onPress={() => alert('Action pressed!')}>\n * Action 1\n * </Stack.Toolbar.MenuAction>\n * </Stack.Toolbar.Menu>\n * </Stack.Toolbar>\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * @platform ios\n */\nexport const StackToolbarMenuAction: React.FC<StackToolbarMenuActionProps> = (props) => {\n const placement = useToolbarPlacement();\n\n if (placement !== 'bottom') {\n throw new Error('Stack.Toolbar.MenuAction must be used inside a Stack.Toolbar.Menu');\n }\n\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n const icon = typeof props.icon === 'string' ? props.icon : undefined;\n return (\n <NativeToolbarMenuAction\n {...props}\n icon={icon}\n image={props.image}\n imageRenderingMode={props.iconRenderingMode}\n />\n );\n};\n\nexport function convertStackToolbarMenuActionPropsToRNHeaderItem(\n props: StackToolbarMenuActionProps\n): NativeStackHeaderItemMenuAction {\n const { children, isOn, unstable_keepPresented, icon, ...rest } = props;\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(props);\n const item: NativeStackHeaderItemMenuAction = {\n ...rest,\n description: props.subtitle,\n type: 'action',\n label: sharedProps.label,\n state: isOn ? 'on' : 'off',\n onPress: props.onPress ?? (() => {}),\n };\n if (unstable_keepPresented !== undefined) {\n item.keepsMenuPresented = unstable_keepPresented;\n }\n if (sharedProps.icon) {\n // Only SF Symbols are supported in submenu icons\n // TODO(@ubax): Add support for other images in react-native-screens\n if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n console.warn(\n 'When Icon is used inside Stack.Toolbar.MenuAction, only sfSymbol icons are supported. This is a limitation of React Native Screens.'\n );\n }\n }\n return item;\n}\n\n// #region NativeToolbarMenu\n\ninterface NativeToolbarMenuProps {\n accessibilityLabel?: string;\n accessibilityHint?: string;\n children?: ReactNode;\n subtitle?: string;\n destructive?: boolean;\n disabled?: boolean;\n hidden?: boolean;\n hidesSharedBackground?: boolean;\n icon?: SFSymbol;\n xcassetName?: string;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu item.\n */\n image?: ImageRef;\n imageRenderingMode?: 'template' | 'original';\n inline?: boolean;\n label?: string;\n palette?: boolean;\n separateBackground?: boolean;\n style?: StyleProp<TextStyle>;\n title?: string;\n tintColor?: ColorValue;\n variant?: 'plain' | 'done' | 'prominent';\n elementSize?: 'auto' | 'small' | 'medium' | 'large';\n}\n\n/**\n * Native toolbar menu component for bottom toolbar.\n * Renders as NativeLinkPreviewAction.\n */\nconst NativeToolbarMenu: React.FC<NativeToolbarMenuProps> = ({\n accessibilityHint,\n accessibilityLabel,\n separateBackground,\n hidesSharedBackground,\n palette,\n inline,\n hidden,\n subtitle,\n title,\n label,\n destructive,\n children,\n icon,\n xcassetName,\n image,\n imageRenderingMode,\n tintColor,\n variant,\n style,\n elementSize,\n}) => {\n const identifier = useId();\n\n const titleStyle = StyleSheet.flatten(style);\n const renderingMode = imageRenderingMode ?? (tintColor !== undefined ? 'template' : 'original');\n return (\n <NativeLinkPreviewAction\n sharesBackground={!separateBackground}\n hidesSharedBackground={hidesSharedBackground}\n hidden={hidden}\n icon={icon}\n xcassetName={xcassetName}\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n image={image}\n imageRenderingMode={renderingMode}\n destructive={destructive}\n subtitle={subtitle}\n accessibilityLabel={accessibilityLabel}\n accessibilityHint={accessibilityHint}\n displayAsPalette={palette}\n displayInline={inline}\n preferredElementSize={elementSize}\n tintColor={tintColor}\n titleStyle={titleStyle}\n barButtonItemStyle={variant === 'done' ? 'prominent' : variant}\n title={title ?? ''}\n label={label}\n onSelected={() => {}}\n children={children}\n identifier={identifier}\n />\n );\n};\n\n// #endregion\n\n// #region NativeToolbarMenuAction\n\n/**\n * Native toolbar menu action - reuses LinkMenuAction.\n */\nconst NativeToolbarMenuAction = LinkMenuAction;\n\n// #endregion\n\nconst ALLOWED_CHILDREN = [\n StackToolbarMenu,\n StackToolbarMenuAction,\n NativeToolbarMenu,\n NativeToolbarMenuAction,\n StackToolbarLabel,\n StackToolbarIcon,\n StackToolbarBadge,\n];\n"]}
|
|
1
|
+
{"version":3,"file":"StackToolbarMenu.js","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport type {\n NativeStackHeaderItemMenu,\n NativeStackHeaderItemMenuAction,\n NativeStackHeaderItemMenuSubmenu,\n} from '@react-navigation/native-stack';\nimport type { ImageRef } from 'expo-image';\nimport { Children, useId, useMemo, type ReactNode } from 'react';\nimport {\n StyleSheet,\n type ColorValue,\n type ImageSourcePropType,\n type StyleProp,\n type TextStyle,\n} from 'react-native';\nimport type { PlatformIconIOS } from 'react-native-screens';\nimport type { SFSymbol } from 'sf-symbols-typescript';\n\nimport { useToolbarPlacement } from './context';\nimport {\n convertStackHeaderSharedPropsToRNSharedHeaderItem,\n extractIconRenderingMode,\n extractXcassetName,\n type StackHeaderItemSharedProps,\n} from './shared';\nimport { StackToolbarLabel, StackToolbarIcon, StackToolbarBadge } from './toolbar-primitives';\nimport { LinkMenuAction } from '../../../link/elements';\nimport { NativeLinkPreviewAction } from '../../../link/preview/native';\nimport {\n filterAllowedChildrenElements,\n getFirstChildOfType,\n isChildOfType,\n} from '../../../utils/children';\n\n/**\n * Computes the label and menu title from children and title prop.\n *\n * - If only `title` prop is provided, it is used for both the label (button text) and menu title\n * - If only `.Label` child is provided, it is used for the label and the menu title is an empty string\n * - If both `.Label` child and `title` prop are provided. `.Label` is used for the label, and `title` is used for the menu title\n */\nfunction computeMenuLabelAndTitle(\n children: ReactNode,\n title: string | undefined\n): { label: string; menuTitle: string } {\n const labelChild = getFirstChildOfType(children, StackToolbarLabel);\n const labelFromChild = labelChild?.props.children;\n return {\n label: labelFromChild ?? title ?? '',\n menuTitle: title ?? '',\n };\n}\n\nexport interface StackToolbarMenuProps {\n accessibilityLabel?: string;\n accessibilityHint?: string;\n /**\n * Menu content - can include icons, labels, badges and menu actions.\n *\n * @example\n * ```tsx\n * <Stack.Toolbar.Menu>\n * <Stack.Toolbar.Icon sfSymbol=\"ellipsis.circle\" />\n * <Stack.Toolbar.Label>Options</Stack.Toolbar.Label>\n * <Stack.Toolbar.MenuAction onPress={() => {}}>Action 1</Stack.Toolbar.MenuAction>\n * </Stack.Toolbar.Menu>\n * ```\n */\n children?: ReactNode;\n /**\n * If `true`, the menu item will be displayed as destructive.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive) for more information.\n */\n destructive?: boolean;\n disabled?: boolean;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu item.\n *\n * > **Note**: This prop is only supported in toolbar with `placement=\"bottom\"`.\n */\n image?: ImageRef;\n /**\n * Whether to hide the shared background.\n *\n * @see [Official Apple documentation](https://developer.apple.com/documentation/uikit/uibarbuttonitem/hidessharedbackground) for more information.\n *\n * @platform iOS 26+\n */\n hidesSharedBackground?: boolean;\n /**\n * Whether the menu should be hidden.\n *\n * @default false\n */\n hidden?: boolean;\n /**\n * Icon for the menu item.\n *\n * Can be an SF Symbol name or an image source.\n *\n * > **Note**: When used in `placement=\"bottom\"`, only string SFSymbols are supported. Use the `image` prop to provide custom images.\n */\n icon?: StackHeaderItemSharedProps['icon'];\n /**\n * Controls how image-based icons are rendered on iOS.\n *\n * - `'template'`: iOS applies tint color to the icon (useful for monochrome icons)\n * - `'original'`: Preserves original icon colors (useful for multi-color icons)\n *\n * **Default behavior:**\n * - If `tintColor` is specified, defaults to `'template'`\n * - If no `tintColor`, defaults to `'original'`\n *\n * This prop only affects image-based icons (not SF Symbols).\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uiimage/renderingmode-swift.enum) for more information.\n *\n * @platform ios\n */\n iconRenderingMode?: 'template' | 'original';\n /**\n * If `true`, the menu will be displayed inline.\n * This means that the menu will not be collapsed\n *\n * > **Note**: Inline menus are only supported in submenus.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayinline) for more information.\n */\n inline?: boolean;\n /**\n * If `true`, the menu will be displayed as a palette.\n * This means that the menu will be displayed as one row\n *\n * > **Note**: Palette menus are only supported in submenus.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayaspalette) for more information.\n */\n palette?: boolean;\n /**\n * Whether to separate the background of this item from other header items.\n *\n * @default false\n */\n separateBackground?: boolean;\n /**\n * Style for the label of the header item.\n */\n style?: StackHeaderItemSharedProps['style'];\n /**\n * The tint color to apply to the button item\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uibarbuttonitem/tintcolor) for more information.\n */\n tintColor?: StackHeaderItemSharedProps['tintColor'];\n /**\n * Optional title to show on top of the menu.\n */\n title?: string;\n /**\n * @default 'plain'\n */\n variant?: StackHeaderItemSharedProps['variant'];\n // TODO(@ubax): Add elementSize support in react-native-screens for header menus.\n /**\n * The preferred size of the menu elements.\n *\n * > **Note**: This prop is only supported in `Stack.Toolbar.Bottom`.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/preferredelementsize) for more information.\n *\n * @platform iOS 16.0+\n */\n elementSize?: 'auto' | 'small' | 'medium' | 'large';\n}\n\n/**\n * Use as `Stack.Toolbar.Menu` to provide menus in iOS toolbar.\n * It accepts `Stack.Toolbar.MenuAction` and nested `Stack.Toolbar.Menu`\n * elements. Menu can be configured using both component props and child\n * elements.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n * import { Alert } from 'react-native';\n *\n * export default function Page() {\n * return (\n * <>\n * <Stack.Toolbar placement=\"right\">\n * <Stack.Toolbar.Menu icon=\"ellipsis.circle\">\n * <Stack.Toolbar.MenuAction onPress={() => Alert.alert('Action pressed!')}>\n * Action 1\n * </Stack.Toolbar.MenuAction>\n * </Stack.Toolbar.Menu>\n * </Stack.Toolbar>\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * @see [Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/menus) for more information about menus on iOS.\n *\n * @platform ios\n */\nexport const StackToolbarMenu: React.FC<StackToolbarMenuProps> = (props) => {\n const placement = useToolbarPlacement();\n\n if (placement !== 'bottom') {\n // For placement other than bottom, this component will not render, and should be\n // converted to RN header item using convertStackToolbarMenuPropsToRNHeaderItem.\n // So if we reach here, it means we're not inside a toolbar or something else is wrong.\n throw new Error('Stack.Toolbar.Menu must be used inside a Stack.Toolbar');\n }\n\n const validChildren = useMemo(\n () => filterAllowedChildrenElements(props.children, ALLOWED_CHILDREN),\n [props.children]\n );\n\n const sharedProps = convertStackToolbarMenuPropsToRNHeaderItem(props, true);\n\n const computedLabel = sharedProps?.label;\n const computedMenuTitle = sharedProps?.menu?.title;\n const icon = sharedProps?.icon?.type === 'sfSymbol' ? sharedProps.icon.name : undefined;\n const xcassetName = extractXcassetName(props);\n const imageRenderingMode = extractIconRenderingMode(props) ?? props.iconRenderingMode;\n\n if (process.env.NODE_ENV !== 'production') {\n const allChildren = Children.toArray(props.children);\n if (allChildren.length !== validChildren.length) {\n throw new Error(\n `Stack.Toolbar.Menu only accepts Stack.Toolbar.Menu, Stack.Toolbar.MenuAction, Stack.Toolbar.Label, Stack.Toolbar.Icon, and Stack.Toolbar.Badge as its children.`\n );\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n const hasBadge = getFirstChildOfType(props.children, StackToolbarBadge);\n if (hasBadge) {\n console.warn(\n 'Stack.Toolbar.Badge is not supported in bottom toolbar (iOS limitation). The badge will be ignored.'\n );\n }\n }\n\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n return (\n <NativeToolbarMenu\n {...props}\n icon={icon}\n xcassetName={xcassetName}\n image={props.image}\n imageRenderingMode={imageRenderingMode}\n label={computedLabel}\n title={computedMenuTitle}\n children={validChildren}\n />\n );\n};\n\nexport function convertStackToolbarMenuPropsToRNHeaderItem(\n props: StackToolbarMenuProps,\n isBottomPlacement: boolean = false\n): NativeStackHeaderItemMenu | undefined {\n if (props.hidden) {\n return undefined;\n }\n const { title, ...rest } = props;\n const actions = Children.toArray(props.children).filter(\n (child) =>\n isChildOfType(child, StackToolbarMenuAction) || isChildOfType(child, StackToolbarMenu)\n );\n\n const { label: computedLabel, menuTitle: computedMenuTitle } = computeMenuLabelAndTitle(\n props.children,\n title\n );\n\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(rest, isBottomPlacement);\n\n const item: NativeStackHeaderItemMenu = {\n ...sharedProps,\n label: computedLabel,\n type: 'menu',\n menu: {\n multiselectable: true,\n items: actions\n .map((action) => {\n if (isChildOfType(action, StackToolbarMenu)) {\n return convertStackToolbarSubmenuMenuPropsToRNHeaderItem(action.props);\n }\n return convertStackToolbarMenuActionPropsToRNHeaderItem(action.props);\n })\n .filter((i) => !!i),\n },\n };\n if (computedMenuTitle) {\n item.menu.title = computedMenuTitle;\n }\n\n return item;\n}\n\n// Custom menu action icons are not supported in react-navigation yet\n// But they are supported in react-native-screens\n// TODO(@ubax): Remove this workaround once react-navigation supports custom icons for menu actions.\n// https://linear.app/expo/issue/ENG-19853/remove-custom-conversion-logic-for-icon-from-packagesexpo\nfunction convertImageIconToPlatformIcon(icon: {\n source: ImageSourcePropType;\n tinted?: boolean;\n}): PlatformIconIOS {\n return icon.tinted\n ? { type: 'templateSource', templateSource: icon.source }\n : { type: 'imageSource', imageSource: icon.source };\n}\n\nfunction convertStackToolbarSubmenuMenuPropsToRNHeaderItem(\n props: StackToolbarMenuProps\n): NativeStackHeaderItemMenuSubmenu | undefined {\n if (props.hidden) {\n return undefined;\n }\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(props);\n const actions = Children.toArray(props.children).filter(\n (child) =>\n isChildOfType(child, StackToolbarMenuAction) || isChildOfType(child, StackToolbarMenu)\n );\n\n const item: NativeStackHeaderItemMenuSubmenu = {\n type: 'submenu',\n items: actions\n .map((action) => {\n if (isChildOfType(action, StackToolbarMenu)) {\n return convertStackToolbarSubmenuMenuPropsToRNHeaderItem(action.props);\n }\n return convertStackToolbarMenuActionPropsToRNHeaderItem(action.props);\n })\n .filter((i) => !!i),\n label: sharedProps.label || props.title || '',\n multiselectable: true,\n };\n\n if (props.inline !== undefined) {\n item.inline = props.inline;\n }\n if (props.palette !== undefined) {\n item.layout = props.palette ? 'palette' : 'default';\n }\n if (props.destructive !== undefined) {\n item.destructive = props.destructive;\n }\n // TODO: Add elementSize to react-native-screens\n\n if (sharedProps.icon) {\n if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n item.icon = convertImageIconToPlatformIcon(\n sharedProps.icon\n ) as unknown as NativeStackHeaderItemMenuSubmenu['icon'];\n }\n }\n\n return item;\n}\n\nexport interface StackToolbarMenuActionProps {\n /**\n * Can be an Icon, Label or string title.\n */\n children?: ReactNode;\n /**\n * If `true`, the menu item will be disabled and not selectable.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/disabled) for more information.\n */\n disabled?: boolean;\n icon?: SFSymbol | ImageSourcePropType;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu action.\n *\n * > **Note**: This prop is only supported in `Stack.Toolbar.Bottom`.\n */\n image?: ImageRef;\n /**\n * Controls how image-based icons are rendered on iOS.\n *\n * - `'template'`: iOS applies tint color to the icon (useful for monochrome icons)\n * - `'original'`: Preserves original icon colors (useful for multi-color icons)\n *\n * **Default behavior:**\n * - If `tintColor` is specified, defaults to `'template'`\n * - If no `tintColor`, defaults to `'original'`\n *\n * This prop only affects image-based icons (not SF Symbols).\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uiimage/renderingmode-swift.enum) for more information.\n *\n * @platform ios\n */\n iconRenderingMode?: 'template' | 'original';\n /**\n * If `true`, the menu item will be displayed as destructive.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive) for more information.\n */\n destructive?: boolean;\n /**\n * If `true`, the menu will be kept presented after the action is selected.\n *\n * This is marked as unstable, because when action is selected it will recreate the menu,\n * which will close all opened submenus and reset the scroll position.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/keepsmenupresented) for more information.\n */\n unstable_keepPresented?: boolean;\n /**\n * If `true`, the menu item will be displayed as selected.\n */\n isOn?: boolean;\n onPress?: () => void;\n /**\n * An elaborated title that explains the purpose of the action.\n */\n discoverabilityLabel?: string;\n /**\n * An optional subtitle for the menu item.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/subtitle) for more information.\n */\n subtitle?: string;\n hidden?: boolean;\n}\n\n/**\n * An action item for a `Stack.Toolbar.Menu`.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * export default function Page() {\n * return (\n * <>\n * <Stack.Toolbar placement=\"right\">\n * <Stack.Toolbar.Menu icon=\"ellipsis.circle\">\n * <Stack.Toolbar.MenuAction onPress={() => alert('Action pressed!')}>\n * Action 1\n * </Stack.Toolbar.MenuAction>\n * </Stack.Toolbar.Menu>\n * </Stack.Toolbar>\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * @platform ios\n */\nexport const StackToolbarMenuAction: React.FC<StackToolbarMenuActionProps> = (props) => {\n const placement = useToolbarPlacement();\n\n if (placement !== 'bottom') {\n throw new Error('Stack.Toolbar.MenuAction must be used inside a Stack.Toolbar.Menu');\n }\n\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n const icon = typeof props.icon === 'string' ? props.icon : undefined;\n return (\n <NativeToolbarMenuAction\n {...props}\n icon={icon}\n image={props.image}\n imageRenderingMode={props.iconRenderingMode}\n />\n );\n};\n\nexport function convertStackToolbarMenuActionPropsToRNHeaderItem(\n props: StackToolbarMenuActionProps\n): NativeStackHeaderItemMenuAction {\n const { children, isOn, unstable_keepPresented, icon, ...rest } = props;\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(props);\n const item: NativeStackHeaderItemMenuAction = {\n ...rest,\n description: props.subtitle,\n type: 'action',\n label: sharedProps.label,\n state: isOn ? 'on' : 'off',\n onPress: props.onPress ?? (() => {}),\n };\n if (unstable_keepPresented !== undefined) {\n item.keepsMenuPresented = unstable_keepPresented;\n }\n if (sharedProps.icon) {\n if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n item.icon = convertImageIconToPlatformIcon(\n sharedProps.icon\n ) as unknown as NativeStackHeaderItemMenuAction['icon'];\n }\n }\n return item;\n}\n\n// #region NativeToolbarMenu\n\ninterface NativeToolbarMenuProps {\n accessibilityLabel?: string;\n accessibilityHint?: string;\n children?: ReactNode;\n subtitle?: string;\n destructive?: boolean;\n disabled?: boolean;\n hidden?: boolean;\n hidesSharedBackground?: boolean;\n icon?: SFSymbol;\n xcassetName?: string;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu item.\n */\n image?: ImageRef;\n imageRenderingMode?: 'template' | 'original';\n inline?: boolean;\n label?: string;\n palette?: boolean;\n separateBackground?: boolean;\n style?: StyleProp<TextStyle>;\n title?: string;\n tintColor?: ColorValue;\n variant?: 'plain' | 'done' | 'prominent';\n elementSize?: 'auto' | 'small' | 'medium' | 'large';\n}\n\n/**\n * Native toolbar menu component for bottom toolbar.\n * Renders as NativeLinkPreviewAction.\n */\nconst NativeToolbarMenu: React.FC<NativeToolbarMenuProps> = ({\n accessibilityHint,\n accessibilityLabel,\n separateBackground,\n hidesSharedBackground,\n palette,\n inline,\n hidden,\n subtitle,\n title,\n label,\n destructive,\n children,\n icon,\n xcassetName,\n image,\n imageRenderingMode,\n tintColor,\n variant,\n style,\n elementSize,\n}) => {\n const identifier = useId();\n\n const titleStyle = StyleSheet.flatten(style);\n const renderingMode = imageRenderingMode ?? (tintColor !== undefined ? 'template' : 'original');\n return (\n <NativeLinkPreviewAction\n sharesBackground={!separateBackground}\n hidesSharedBackground={hidesSharedBackground}\n hidden={hidden}\n icon={icon}\n xcassetName={xcassetName}\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n image={image}\n imageRenderingMode={renderingMode}\n destructive={destructive}\n subtitle={subtitle}\n accessibilityLabel={accessibilityLabel}\n accessibilityHint={accessibilityHint}\n displayAsPalette={palette}\n displayInline={inline}\n preferredElementSize={elementSize}\n tintColor={tintColor}\n titleStyle={titleStyle}\n barButtonItemStyle={variant === 'done' ? 'prominent' : variant}\n title={title ?? ''}\n label={label}\n onSelected={() => {}}\n children={children}\n identifier={identifier}\n />\n );\n};\n\n// #endregion\n\n// #region NativeToolbarMenuAction\n\n/**\n * Native toolbar menu action - reuses LinkMenuAction.\n */\nconst NativeToolbarMenuAction = LinkMenuAction;\n\n// #endregion\n\nconst ALLOWED_CHILDREN = [\n StackToolbarMenu,\n StackToolbarMenuAction,\n NativeToolbarMenu,\n NativeToolbarMenuAction,\n StackToolbarLabel,\n StackToolbarIcon,\n StackToolbarBadge,\n];\n"]}
|
|
@@ -102,7 +102,7 @@ function LinkWithPreview({ children, ...rest }) {
|
|
|
102
102
|
if (hasPreview) {
|
|
103
103
|
blockPressRef.current = true;
|
|
104
104
|
isPreviewTapped.current = false;
|
|
105
|
-
prefetch(rest.
|
|
105
|
+
prefetch(rest.href);
|
|
106
106
|
setIsCurrenPreviewOpen(true);
|
|
107
107
|
}
|
|
108
108
|
}} onPreviewWillClose={() => {
|
|
@@ -117,12 +117,12 @@ function LinkWithPreview({ children, ...rest }) {
|
|
|
117
117
|
}} onPreviewDidClose={() => {
|
|
118
118
|
blockPressRef.current = false;
|
|
119
119
|
if (hasPreview && isPreviewTapped.current && isPad) {
|
|
120
|
-
router.navigate(rest.
|
|
120
|
+
router.navigate(rest.href, { __internal__PreviewKey: nextScreenId });
|
|
121
121
|
}
|
|
122
122
|
}} onPreviewTapped={() => {
|
|
123
123
|
isPreviewTapped.current = true;
|
|
124
124
|
if (!isPad) {
|
|
125
|
-
router.navigate(rest.
|
|
125
|
+
router.navigate(rest.href, { __internal__PreviewKey: nextScreenId });
|
|
126
126
|
}
|
|
127
127
|
}} style={{ display: 'contents' }} disableForceFlatten>
|
|
128
128
|
<NativeMenuContext_1.NativeMenuContext value>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkWithPreview.js","sourceRoot":"","sources":["../../src/link/LinkWithPreview.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"LinkWithPreview.js","sourceRoot":"","sources":["../../src/link/LinkWithPreview.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { Platform } from 'react-native';\n\nimport { useRouter } from '../hooks';\nimport { BaseExpoRouterLink } from './BaseExpoRouterLink';\nimport { InternalLinkPreviewContext } from './InternalLinkPreviewContext';\nimport { NativeMenuContext } from './NativeMenuContext';\nimport { LinkMenu, LinkPreview, LinkTrigger } from './elements';\nimport { resolveHref } from './href';\nimport type { Href } from '../types';\nimport { useLinkPreviewContext } from './preview/LinkPreviewContext';\nimport { NativeLinkPreview } from './preview/native';\nimport { useNextScreenId } from './preview/useNextScreenId';\nimport { LinkProps } from './useLinkHooks';\nimport { getFirstChildOfType } from '../utils/children';\nimport { shouldLinkExternally } from '../utils/url';\n\nconst isPad = Platform.OS === 'ios' && Platform.isPad;\n\ninterface LinkWithPreviewProps extends LinkProps {\n hrefForPreviewNavigation: Href;\n}\n\nexport function LinkWithPreview({ children, ...rest }: LinkWithPreviewProps) {\n const router = useRouter();\n const { setOpenPreviewKey } = useLinkPreviewContext();\n const [isCurrentPreviewOpen, setIsCurrenPreviewOpen] = useState(false);\n\n const hrefWithoutQuery = resolveHref(rest.hrefForPreviewNavigation).split('?')[0];\n const prevHrefWithoutQuery = useRef(hrefWithoutQuery);\n\n useEffect(() => {\n if (isCurrentPreviewOpen) {\n if (prevHrefWithoutQuery.current !== hrefWithoutQuery) {\n throw new Error(\n 'Link does not support changing the href prop after the preview has been opened. Please ensure that the href prop is stable and does not change between renders.'\n );\n }\n } else {\n prevHrefWithoutQuery.current = hrefWithoutQuery;\n }\n }, [hrefWithoutQuery]);\n\n const [{ nextScreenId, tabPath }, prefetch] = useNextScreenId();\n\n useEffect(() => {\n if (rest.replace) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('Using replace links with preview is not supported');\n } else {\n console.warn('Using replace links with preview is not supported');\n }\n }\n }, [rest.href, rest.replace]);\n\n const triggerElement = React.useMemo(\n () => getFirstChildOfType(children, LinkTrigger),\n [children]\n );\n const menuElement = React.useMemo(() => getFirstChildOfType(children, LinkMenu), [children]);\n const previewElement = React.useMemo(\n () => getFirstChildOfType(children, LinkPreview),\n [children]\n );\n\n if ((previewElement || menuElement) && !triggerElement) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n 'When you use Link.Preview, you must use Link.Trigger to specify the trigger element.'\n );\n } else {\n console.warn(\n 'When you use Link.Preview, you must use Link.Trigger to specify the trigger element.'\n );\n }\n }\n\n const trigger = React.useMemo(\n () => triggerElement ?? <LinkTrigger>{children}</LinkTrigger>,\n [triggerElement, children]\n );\n\n const preview = React.useMemo(\n () => (shouldLinkExternally(String(rest.href)) || !previewElement ? null : previewElement),\n [previewElement, rest.href]\n );\n\n const isPreviewTapped = useRef(false);\n const blockPressRef = useRef(false);\n\n const tabPathValue = useMemo(\n () => ({\n path: tabPath,\n }),\n [tabPath]\n );\n\n const hasPreview = !!previewElement;\n\n if (rest.replace) {\n return <BaseExpoRouterLink children={children} {...rest} />;\n }\n\n return (\n <NativeLinkPreview\n nextScreenId={isPad ? undefined : nextScreenId}\n tabPath={isPad ? undefined : tabPathValue}\n onWillPreviewOpen={() => {\n if (hasPreview) {\n blockPressRef.current = true;\n isPreviewTapped.current = false;\n prefetch(rest.href);\n setIsCurrenPreviewOpen(true);\n }\n }}\n onPreviewWillClose={() => {\n if (hasPreview) {\n setIsCurrenPreviewOpen(false);\n // When preview was not tapped, then we need to enable the screen stack animation\n // Otherwise this will happen in StackNavigator, when new screen is opened\n if (!isPreviewTapped.current || isPad) {\n setOpenPreviewKey(undefined);\n }\n }\n }}\n onPreviewDidClose={() => {\n blockPressRef.current = false;\n if (hasPreview && isPreviewTapped.current && isPad) {\n router.navigate(rest.href, { __internal__PreviewKey: nextScreenId });\n }\n }}\n onPreviewTapped={() => {\n isPreviewTapped.current = true;\n if (!isPad) {\n router.navigate(rest.href, { __internal__PreviewKey: nextScreenId });\n }\n }}\n style={{ display: 'contents' }}\n disableForceFlatten>\n <NativeMenuContext value>\n <InternalLinkPreviewContext\n value={{\n isVisible: isCurrentPreviewOpen,\n href: rest.hrefForPreviewNavigation,\n blockPressRef,\n }}>\n <BaseExpoRouterLink {...rest} children={trigger} ref={rest.ref} />\n {preview}\n {menuElement}\n </InternalLinkPreviewContext>\n </NativeMenuContext>\n </NativeLinkPreview>\n );\n}\n"]}
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import type { ZoomTransitionEnablerProps } from './ZoomTransitionEnabler.types';
|
|
2
|
+
import { INTERNAL_EXPO_ROUTER_ZOOM_TRANSITION_SCREEN_ID_PARAM_NAME, INTERNAL_EXPO_ROUTER_ZOOM_TRANSITION_SOURCE_ID_PARAM_NAME } from '../../navigationParams';
|
|
2
3
|
export declare function disableZoomTransition(): void;
|
|
3
4
|
export declare function isZoomTransitionEnabled(): boolean;
|
|
4
5
|
export declare function ZoomTransitionEnabler({ route }: ZoomTransitionEnablerProps): import("react").JSX.Element | null;
|
|
6
|
+
/**
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export declare function useShouldEnableZoomTransition(route: unknown): route is {
|
|
10
|
+
key: string;
|
|
11
|
+
params: {
|
|
12
|
+
[INTERNAL_EXPO_ROUTER_ZOOM_TRANSITION_SOURCE_ID_PARAM_NAME]: string;
|
|
13
|
+
[INTERNAL_EXPO_ROUTER_ZOOM_TRANSITION_SCREEN_ID_PARAM_NAME]: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
5
16
|
//# sourceMappingURL=ZoomTransitionEnabler.ios.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZoomTransitionEnabler.ios.d.ts","sourceRoot":"","sources":["../../../src/link/zoom/ZoomTransitionEnabler.ios.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"ZoomTransitionEnabler.ios.d.ts","sourceRoot":"","sources":["../../../src/link/zoom/ZoomTransitionEnabler.ios.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAGhF,OAAO,EAGL,yDAAyD,EACzD,yDAAyD,EAC1D,MAAM,wBAAwB,CAAC;AAOhC,wBAAgB,qBAAqB,SAEpC;AAED,wBAAgB,uBAAuB,YAEtC;AAED,wBAAgB,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,0BAA0B,sCAmC1E;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI;IACtE,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE;QACN,CAAC,yDAAyD,CAAC,EAAE,MAAM,CAAC;QACpE,CAAC,yDAAyD,CAAC,EAAE,MAAM,CAAC;KACrE,CAAC;CACH,CAuCA"}
|
|
@@ -3,10 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.disableZoomTransition = disableZoomTransition;
|
|
4
4
|
exports.isZoomTransitionEnabled = isZoomTransitionEnabled;
|
|
5
5
|
exports.ZoomTransitionEnabler = ZoomTransitionEnabler;
|
|
6
|
+
exports.useShouldEnableZoomTransition = useShouldEnableZoomTransition;
|
|
6
7
|
const react_1 = require("react");
|
|
7
8
|
const zoom_transition_context_1 = require("./zoom-transition-context");
|
|
8
9
|
const descriptors_context_1 = require("../../fork/native-stack/descriptors-context");
|
|
9
10
|
const navigationParams_1 = require("../../navigationParams");
|
|
11
|
+
const stackPresentation_1 = require("../../utils/stackPresentation");
|
|
10
12
|
const PreviewRouteContext_1 = require("../preview/PreviewRouteContext");
|
|
11
13
|
const native_1 = require("../preview/native");
|
|
12
14
|
let _isZoomTransitionEnabled = process.env.EXPO_OS === 'ios';
|
|
@@ -17,6 +19,36 @@ function isZoomTransitionEnabled() {
|
|
|
17
19
|
return _isZoomTransitionEnabled;
|
|
18
20
|
}
|
|
19
21
|
function ZoomTransitionEnabler({ route }) {
|
|
22
|
+
const shouldEnableZoomTransition = useShouldEnableZoomTransition(route);
|
|
23
|
+
const targetContext = (0, react_1.use)(zoom_transition_context_1.ZoomTransitionTargetContext);
|
|
24
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
25
|
+
if (shouldEnableZoomTransition && targetContext?.addEnabler && targetContext?.removeEnabler) {
|
|
26
|
+
targetContext.addEnabler();
|
|
27
|
+
return () => {
|
|
28
|
+
targetContext.removeEnabler();
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return () => { };
|
|
32
|
+
}, [shouldEnableZoomTransition]);
|
|
33
|
+
if (shouldEnableZoomTransition) {
|
|
34
|
+
const params = route.params;
|
|
35
|
+
const zoomTransitionId = params[navigationParams_1.INTERNAL_EXPO_ROUTER_ZOOM_TRANSITION_SOURCE_ID_PARAM_NAME];
|
|
36
|
+
// Read dismissalBoundsRect from context (set by usePreventZoomTransitionDismissal hook)
|
|
37
|
+
const dismissalBoundsRect = targetContext.dismissalBoundsRect;
|
|
38
|
+
// Read gestureEnabled from the screen descriptor so that gestureEnabled: false
|
|
39
|
+
// automatically blocks the native zoom transition dismissal gesture,
|
|
40
|
+
// even when the user hasn't called usePreventZoomTransitionDismissal().
|
|
41
|
+
const descriptorsMap = (0, react_1.use)(descriptors_context_1.DescriptorsContext);
|
|
42
|
+
const gestureEnabled = descriptorsMap[route.key]?.options?.gestureEnabled;
|
|
43
|
+
const effectiveDismissalBoundsRect = dismissalBoundsRect ?? (gestureEnabled === false ? { maxX: 0, maxY: 0 } : null);
|
|
44
|
+
return (<native_1.LinkZoomTransitionEnabler zoomTransitionSourceIdentifier={zoomTransitionId} dismissalBoundsRect={effectiveDismissalBoundsRect}/>);
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
function useShouldEnableZoomTransition(route) {
|
|
20
52
|
const isPreview = (0, PreviewRouteContext_1.useIsPreview)();
|
|
21
53
|
if (isZoomTransitionEnabled() &&
|
|
22
54
|
!isPreview &&
|
|
@@ -24,27 +56,29 @@ function ZoomTransitionEnabler({ route }) {
|
|
|
24
56
|
typeof route === 'object' &&
|
|
25
57
|
'params' in route &&
|
|
26
58
|
typeof route.params === 'object' &&
|
|
59
|
+
route.params &&
|
|
27
60
|
'key' in route &&
|
|
28
61
|
typeof route.key === 'string') {
|
|
29
|
-
const params = route.params
|
|
62
|
+
const params = route.params;
|
|
30
63
|
const internalParams = (0, navigationParams_1.getInternalExpoRouterParams)(params);
|
|
31
64
|
const zoomTransitionId = internalParams[navigationParams_1.INTERNAL_EXPO_ROUTER_ZOOM_TRANSITION_SOURCE_ID_PARAM_NAME];
|
|
32
65
|
const zoomTransitionScreenId = internalParams[navigationParams_1.INTERNAL_EXPO_ROUTER_ZOOM_TRANSITION_SCREEN_ID_PARAM_NAME];
|
|
33
|
-
const
|
|
34
|
-
const hasZoomTransition = !!zoomTransitionId && zoomTransitionScreenId === route.key && !isLinkPreviewNavigation;
|
|
66
|
+
const hasZoomTransition = !!zoomTransitionId && zoomTransitionScreenId === route.key;
|
|
35
67
|
if (hasZoomTransition && typeof zoomTransitionId === 'string') {
|
|
36
|
-
// Read dismissalBoundsRect from context (set by usePreventZoomTransitionDismissal hook)
|
|
37
|
-
const targetContext = (0, react_1.use)(zoom_transition_context_1.ZoomTransitionTargetContext);
|
|
38
|
-
const dismissalBoundsRect = targetContext.dismissalBoundsRect;
|
|
39
68
|
// Read gestureEnabled from the screen descriptor so that gestureEnabled: false
|
|
40
69
|
// automatically blocks the native zoom transition dismissal gesture,
|
|
41
70
|
// even when the user hasn't called usePreventZoomTransitionDismissal().
|
|
42
71
|
const descriptorsMap = (0, react_1.use)(descriptors_context_1.DescriptorsContext);
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
|
|
72
|
+
const isLinkPreviewNavigation = !!internalParams[navigationParams_1.INTERNAL_EXPO_ROUTER_IS_PREVIEW_NAVIGATION_PARAM_NAME];
|
|
73
|
+
const isPresentedAsModal = (0, stackPresentation_1.isModalPresentation)(descriptorsMap[route.key]?.options);
|
|
74
|
+
if (isLinkPreviewNavigation && !isPresentedAsModal) {
|
|
75
|
+
console.warn('[expo-router] Zoom transition with link preview is only supported for screens presented modally. Please set the screen presentation to "fullScreenModal" or another modal presentation style.');
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
46
80
|
}
|
|
47
81
|
}
|
|
48
|
-
return
|
|
82
|
+
return false;
|
|
49
83
|
}
|
|
50
84
|
//# sourceMappingURL=ZoomTransitionEnabler.ios.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZoomTransitionEnabler.ios.js","sourceRoot":"","sources":["../../../src/link/zoom/ZoomTransitionEnabler.ios.tsx"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"ZoomTransitionEnabler.ios.js","sourceRoot":"","sources":["../../../src/link/zoom/ZoomTransitionEnabler.ios.tsx"],"names":[],"mappings":"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","sourcesContent":["import { use, useLayoutEffect } from 'react';\n\nimport type { ZoomTransitionEnablerProps } from './ZoomTransitionEnabler.types';\nimport { ZoomTransitionTargetContext } from './zoom-transition-context';\nimport { DescriptorsContext } from '../../fork/native-stack/descriptors-context';\nimport {\n getInternalExpoRouterParams,\n INTERNAL_EXPO_ROUTER_IS_PREVIEW_NAVIGATION_PARAM_NAME,\n INTERNAL_EXPO_ROUTER_ZOOM_TRANSITION_SCREEN_ID_PARAM_NAME,\n INTERNAL_EXPO_ROUTER_ZOOM_TRANSITION_SOURCE_ID_PARAM_NAME,\n} from '../../navigationParams';\nimport { isModalPresentation } from '../../utils/stackPresentation';\nimport { useIsPreview } from '../preview/PreviewRouteContext';\nimport { LinkZoomTransitionEnabler } from '../preview/native';\n\nlet _isZoomTransitionEnabled = process.env.EXPO_OS === 'ios';\n\nexport function disableZoomTransition() {\n _isZoomTransitionEnabled = false;\n}\n\nexport function isZoomTransitionEnabled() {\n return _isZoomTransitionEnabled;\n}\n\nexport function ZoomTransitionEnabler({ route }: ZoomTransitionEnablerProps) {\n const shouldEnableZoomTransition = useShouldEnableZoomTransition(route);\n const targetContext = use(ZoomTransitionTargetContext);\n useLayoutEffect(() => {\n if (shouldEnableZoomTransition && targetContext?.addEnabler && targetContext?.removeEnabler) {\n targetContext.addEnabler();\n return () => {\n targetContext.removeEnabler();\n };\n }\n return () => {};\n }, [shouldEnableZoomTransition]);\n if (shouldEnableZoomTransition) {\n const params = route.params;\n const zoomTransitionId = params[INTERNAL_EXPO_ROUTER_ZOOM_TRANSITION_SOURCE_ID_PARAM_NAME];\n\n // Read dismissalBoundsRect from context (set by usePreventZoomTransitionDismissal hook)\n const dismissalBoundsRect = targetContext.dismissalBoundsRect;\n\n // Read gestureEnabled from the screen descriptor so that gestureEnabled: false\n // automatically blocks the native zoom transition dismissal gesture,\n // even when the user hasn't called usePreventZoomTransitionDismissal().\n const descriptorsMap = use(DescriptorsContext);\n const gestureEnabled = descriptorsMap[route.key]?.options?.gestureEnabled;\n const effectiveDismissalBoundsRect =\n dismissalBoundsRect ?? (gestureEnabled === false ? { maxX: 0, maxY: 0 } : null);\n\n return (\n <LinkZoomTransitionEnabler\n zoomTransitionSourceIdentifier={zoomTransitionId}\n dismissalBoundsRect={effectiveDismissalBoundsRect}\n />\n );\n }\n return null;\n}\n\n/**\n * @internal\n */\nexport function useShouldEnableZoomTransition(route: unknown): route is {\n key: string;\n params: {\n [INTERNAL_EXPO_ROUTER_ZOOM_TRANSITION_SOURCE_ID_PARAM_NAME]: string;\n [INTERNAL_EXPO_ROUTER_ZOOM_TRANSITION_SCREEN_ID_PARAM_NAME]: string;\n };\n} {\n const isPreview = useIsPreview();\n if (\n isZoomTransitionEnabled() &&\n !isPreview &&\n route &&\n typeof route === 'object' &&\n 'params' in route &&\n typeof route.params === 'object' &&\n route.params &&\n 'key' in route &&\n typeof route.key === 'string'\n ) {\n const params = route.params;\n const internalParams = getInternalExpoRouterParams(params);\n const zoomTransitionId =\n internalParams[INTERNAL_EXPO_ROUTER_ZOOM_TRANSITION_SOURCE_ID_PARAM_NAME];\n const zoomTransitionScreenId =\n internalParams[INTERNAL_EXPO_ROUTER_ZOOM_TRANSITION_SCREEN_ID_PARAM_NAME];\n const hasZoomTransition = !!zoomTransitionId && zoomTransitionScreenId === route.key;\n if (hasZoomTransition && typeof zoomTransitionId === 'string') {\n // Read gestureEnabled from the screen descriptor so that gestureEnabled: false\n // automatically blocks the native zoom transition dismissal gesture,\n // even when the user hasn't called usePreventZoomTransitionDismissal().\n const descriptorsMap = use(DescriptorsContext);\n\n const isLinkPreviewNavigation =\n !!internalParams[INTERNAL_EXPO_ROUTER_IS_PREVIEW_NAVIGATION_PARAM_NAME];\n const isPresentedAsModal = isModalPresentation(descriptorsMap[route.key]?.options);\n if (isLinkPreviewNavigation && !isPresentedAsModal) {\n console.warn(\n '[expo-router] Zoom transition with link preview is only supported for screens presented modally. Please set the screen presentation to \"fullScreenModal\" or another modal presentation style.'\n );\n } else {\n return true;\n }\n }\n }\n return false;\n}\n"]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.LinkAppleZoom = LinkAppleZoom;
|
|
5
5
|
const react_1 = require("react");
|
|
6
|
-
const
|
|
6
|
+
const ZoomTransitionEnabler_1 = require("./ZoomTransitionEnabler");
|
|
7
7
|
const zoom_transition_context_1 = require("./zoom-transition-context");
|
|
8
8
|
const Slot_1 = require("../../ui/Slot");
|
|
9
9
|
const native_1 = require("../preview/native");
|
|
@@ -14,7 +14,7 @@ const native_1 = require("../preview/native");
|
|
|
14
14
|
* @platform ios 18+
|
|
15
15
|
*/
|
|
16
16
|
function LinkAppleZoom(props) {
|
|
17
|
-
if (!(0,
|
|
17
|
+
if (!(0, ZoomTransitionEnabler_1.isZoomTransitionEnabled)()) {
|
|
18
18
|
return <Slot_1.Slot {...props}/>;
|
|
19
19
|
}
|
|
20
20
|
return <LinkAppleZoomImpl {...props}/>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link-apple-zoom.js","sourceRoot":"","sources":["../../../src/link/zoom/link-apple-zoom.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AA6Bb,sCAKC;AAhCD,iCAAyE;AAEzE,
|
|
1
|
+
{"version":3,"file":"link-apple-zoom.js","sourceRoot":"","sources":["../../../src/link/zoom/link-apple-zoom.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AA6Bb,sCAKC;AAhCD,iCAAyE;AAEzE,mEAAkE;AAClE,uEAAwE;AACxE,wCAAqC;AACrC,8CAA6D;AAgB7D;;;;;GAKG;AACH,SAAgB,aAAa,CAAC,KAAyB;IACrD,IAAI,CAAC,IAAA,+CAAuB,GAAE,EAAE,CAAC;QAC/B,OAAO,CAAC,WAAI,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;IAC7B,CAAC;IACD,OAAO,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AAC1C,CAAC;AAMD,SAAS,iBAAiB,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,IAAI,EAA0B;IACrF,MAAM,KAAK,GAAG,IAAA,WAAG,EAAC,qDAA2B,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACxF,CAAC;IACD,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC;IAEtD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,SAAS,EAAE,CAAC;QACZ,OAAO,YAAY,CAAC;IACtB,CAAC,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC;IAE9B,MAAM,kBAAkB,GAAG,gBAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAExD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,IAAI,kBAAkB,EAAE,CAAC;YAChE,OAAO,CAAC,IAAI,CACV,wJAAwJ,CACzJ,CAAC;QACJ,CAAC;IACH,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAEzB,IAAI,kBAAkB,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CACL,CAAC,iCAAwB,CACvB,UAAU,CAAC,CAAC,UAAU,CAAC,CACvB,SAAS,CAAC,CAAC,aAAa,CAAC;IACzB,+GAA+G;IAC/G,wBAAwB,CACxB;MAAA,CAAC,WAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,WAAI,CAClC;IAAA,EAAE,iCAAwB,CAAC,CAC5B,CAAC;AACJ,CAAC","sourcesContent":["'use client';\n\nimport { Children, use, useEffect, type PropsWithChildren } from 'react';\n\nimport { isZoomTransitionEnabled } from './ZoomTransitionEnabler';\nimport { ZoomTransitionSourceContext } from './zoom-transition-context';\nimport { Slot } from '../../ui/Slot';\nimport { LinkZoomTransitionSource } from '../preview/native';\n\nexport interface LinkAppleZoomProps extends PropsWithChildren {\n /**\n * Defines the rectangle used for the zoom transition's alignment. This rectangle is specified in the zoomed screen's coordinate space.\n *\n * @platform ios 18+\n */\n alignmentRect?: {\n x: number;\n y: number;\n width: number;\n height: number;\n };\n}\n\n/**\n * When this component is used inside a Link, [zoom transition](https://developer.apple.com/documentation/uikit/enhancing-your-app-with-fluid-transitions?language=objc)\n * will be used when navigating to the link's href.\n *\n * @platform ios 18+\n */\nexport function LinkAppleZoom(props: LinkAppleZoomProps) {\n if (!isZoomTransitionEnabled()) {\n return <Slot {...props} />;\n }\n return <LinkAppleZoomImpl {...props} />;\n}\n\ntype LinkAppleZoomImplProps = LinkAppleZoomProps & {\n onPress?: () => void;\n};\n\nfunction LinkAppleZoomImpl({ children, alignmentRect, ...rest }: LinkAppleZoomImplProps) {\n const value = use(ZoomTransitionSourceContext);\n if (!value) {\n throw new Error('[expo-router] Link.ZoomTransitionSource must be used within a Link');\n }\n const { identifier, addSource, removeSource } = value;\n\n useEffect(() => {\n addSource();\n return removeSource;\n }, [addSource, removeSource]);\n\n const hasTooManyChildren = Children.count(children) > 1;\n\n useEffect(() => {\n if (process.env.NODE_ENV !== 'production' && hasTooManyChildren) {\n console.warn(\n '[expo-router] Link.ZoomTransitionSource only accepts a single child component. Please wrap multiple children in a View or another container component.'\n );\n }\n }, [hasTooManyChildren]);\n\n if (hasTooManyChildren) {\n return null;\n }\n\n return (\n <LinkZoomTransitionSource\n identifier={identifier}\n alignment={alignmentRect}\n // Note(@ubax): Even though we always set this to true, I want to keep the prop here for easier future changes.\n animateAspectRatioChange>\n <Slot {...rest}>{children}</Slot>\n </LinkZoomTransitionSource>\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePreventZoomTransitionDismissal.ios.d.ts","sourceRoot":"","sources":["../../../src/link/zoom/usePreventZoomTransitionDismissal.ios.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,wCAAwC,EAAE,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"usePreventZoomTransitionDismissal.ios.d.ts","sourceRoot":"","sources":["../../../src/link/zoom/usePreventZoomTransitionDismissal.ios.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,wCAAwC,EAAE,MAAM,2CAA2C,CAAC;AAU1G,wBAAgB,iCAAiC,CAC/C,OAAO,CAAC,EAAE,wCAAwC,QA6EnD"}
|
|
@@ -8,14 +8,31 @@ const zoom_transition_context_1 = require("./zoom-transition-context");
|
|
|
8
8
|
const descriptors_context_1 = require("../../fork/native-stack/descriptors-context");
|
|
9
9
|
const navigationParams_1 = require("../../navigationParams");
|
|
10
10
|
const useNavigation_1 = require("../../useNavigation");
|
|
11
|
+
const stack_1 = require("../../utils/stack");
|
|
12
|
+
const stackPresentation_1 = require("../../utils/stackPresentation");
|
|
13
|
+
const useSafeLayoutEffect_1 = require("../../views/useSafeLayoutEffect");
|
|
14
|
+
const PreviewRouteContext_1 = require("../preview/PreviewRouteContext");
|
|
11
15
|
function usePreventZoomTransitionDismissal(options) {
|
|
12
16
|
const context = (0, react_1.use)(zoom_transition_context_1.ZoomTransitionTargetContext);
|
|
13
17
|
const route = (0, native_1.useRoute)();
|
|
14
18
|
const navigation = (0, useNavigation_1.useNavigation)();
|
|
19
|
+
const isPreview = (0, PreviewRouteContext_1.useIsPreview)();
|
|
20
|
+
const isFocused = navigation.isFocused();
|
|
21
|
+
const isPreloaded = isPreview ? false : (0, stack_1.isRoutePreloadedInStack)(navigation.getState(), route);
|
|
15
22
|
const descriptorsMap = (0, react_1.use)(descriptors_context_1.DescriptorsContext);
|
|
16
23
|
const currentDescriptor = descriptorsMap[route.key];
|
|
17
24
|
const gestureEnabled = currentDescriptor?.options?.gestureEnabled;
|
|
18
|
-
(0,
|
|
25
|
+
const isModal = (0, stackPresentation_1.isModalPresentation)(currentDescriptor?.options);
|
|
26
|
+
(0, useSafeLayoutEffect_1.useSafeLayoutEffect)(() => {
|
|
27
|
+
if (isPreview)
|
|
28
|
+
return;
|
|
29
|
+
if (isModal) {
|
|
30
|
+
console.warn('[expo-router] usePreventZoomTransitionDismissal has no effect on screens presented modally. Please remove this hook from the screen component or change the screen presentation to a non-modal style.');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (!context.hasEnabler) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
19
36
|
const rect = options?.unstable_dismissalBoundsRect;
|
|
20
37
|
// Validate rect if provided
|
|
21
38
|
if (rect) {
|
|
@@ -37,12 +54,14 @@ function usePreventZoomTransitionDismissal(options) {
|
|
|
37
54
|
// 3. Otherwise, allow normal dismissal (null rect)
|
|
38
55
|
const computedRect = rect ?? (gestureEnabled === false ? { maxX: 0, maxY: 0 } : null);
|
|
39
56
|
context.setDismissalBoundsRect?.(computedRect);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
57
|
+
if (!isPreloaded || (isPreloaded && isFocused)) {
|
|
58
|
+
// Disable React Navigation's gesture handler when we have custom bounds to prevent conflicts.
|
|
59
|
+
// The native zoom transition's interactiveDismissShouldBegin callback handles dismissal instead.
|
|
60
|
+
// We use the internal option to preserve the user's gestureEnabled setting.
|
|
61
|
+
navigation.setOptions({
|
|
62
|
+
[navigationParams_1.INTERNAL_EXPO_ROUTER_GESTURE_ENABLED_OPTION_NAME]: computedRect ? false : undefined,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
46
65
|
// Cleanup on unmount
|
|
47
66
|
return () => {
|
|
48
67
|
context.setDismissalBoundsRect?.(null);
|
|
@@ -55,6 +74,10 @@ function usePreventZoomTransitionDismissal(options) {
|
|
|
55
74
|
context.setDismissalBoundsRect,
|
|
56
75
|
gestureEnabled,
|
|
57
76
|
navigation,
|
|
77
|
+
isFocused,
|
|
78
|
+
isPreloaded,
|
|
79
|
+
isModal,
|
|
80
|
+
isPreview,
|
|
58
81
|
]);
|
|
59
82
|
}
|
|
60
83
|
//# sourceMappingURL=usePreventZoomTransitionDismissal.ios.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePreventZoomTransitionDismissal.ios.js","sourceRoot":"","sources":["../../../src/link/zoom/usePreventZoomTransitionDismissal.ios.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;
|
|
1
|
+
{"version":3,"file":"usePreventZoomTransitionDismissal.ios.js","sourceRoot":"","sources":["../../../src/link/zoom/usePreventZoomTransitionDismissal.ios.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAeb,8EA8EC;AA3FD,qDAAoD;AACpD,iCAA4B;AAG5B,uEAAwE;AACxE,qFAAiF;AACjF,6DAA0F;AAC1F,uDAAoD;AACpD,6CAA4D;AAC5D,qEAAoE;AACpE,yEAAsE;AACtE,wEAA8D;AAE9D,SAAgB,iCAAiC,CAC/C,OAAkD;IAElD,MAAM,OAAO,GAAG,IAAA,WAAG,EAAC,qDAA2B,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,IAAA,iBAAQ,GAAE,CAAC;IACzB,MAAM,UAAU,GAAG,IAAA,6BAAa,GAAE,CAAC;IACnC,MAAM,SAAS,GAAG,IAAA,kCAAY,GAAE,CAAC;IACjC,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,EAAE,CAAC;IACzC,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAA,+BAAuB,EAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC;IAE9F,MAAM,cAAc,GAAG,IAAA,WAAG,EAAC,wCAAkB,CAAC,CAAC;IAC/C,MAAM,iBAAiB,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpD,MAAM,cAAc,GAAG,iBAAiB,EAAE,OAAO,EAAE,cAAc,CAAC;IAClE,MAAM,OAAO,GAAG,IAAA,uCAAmB,EAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;IAEhE,IAAA,yCAAmB,EAAC,GAAG,EAAE;QACvB,IAAI,SAAS;YAAE,OAAO;QACtB,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CACV,uMAAuM,CACxM,CAAC;YACF,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,OAAO,EAAE,4BAA4B,CAAC;QAEnD,4BAA4B;QAC5B,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;YAExC,gDAAgD;YAChD,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;gBAC7D,OAAO,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;gBACxF,OAAO;YACT,CAAC;YACD,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;gBAC7D,OAAO,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;gBACxF,OAAO;YACT,CAAC;QACH,CAAC;QAED,wDAAwD;QACxD,qCAAqC;QACrC,yFAAyF;QACzF,uDAAuD;QACvD,mDAAmD;QACnD,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,cAAc,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEtF,OAAO,CAAC,sBAAsB,EAAE,CAAC,YAAY,CAAC,CAAC;QAE/C,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC,EAAE,CAAC;YAC/C,8FAA8F;YAC9F,iGAAiG;YACjG,4EAA4E;YAC5E,UAAU,CAAC,UAAU,CAAC;gBACpB,CAAC,mEAAgD,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;aACrF,CAAC,CAAC;QACL,CAAC;QAED,qBAAqB;QACrB,OAAO,GAAG,EAAE;YACV,OAAO,CAAC,sBAAsB,EAAE,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC,CAAC;IACJ,CAAC,EAAE;QACD,OAAO,EAAE,4BAA4B,EAAE,IAAI;QAC3C,OAAO,EAAE,4BAA4B,EAAE,IAAI;QAC3C,OAAO,EAAE,4BAA4B,EAAE,IAAI;QAC3C,OAAO,EAAE,4BAA4B,EAAE,IAAI;QAC3C,OAAO,CAAC,sBAAsB;QAC9B,cAAc;QACd,UAAU;QACV,SAAS;QACT,WAAW;QACX,OAAO;QACP,SAAS;KACV,CAAC,CAAC;AACL,CAAC","sourcesContent":["'use client';\n\nimport { useRoute } from '@react-navigation/native';\nimport { use } from 'react';\n\nimport type { UsePreventZoomTransitionDismissalOptions } from './usePreventZoomTransitionDismissal.types';\nimport { ZoomTransitionTargetContext } from './zoom-transition-context';\nimport { DescriptorsContext } from '../../fork/native-stack/descriptors-context';\nimport { INTERNAL_EXPO_ROUTER_GESTURE_ENABLED_OPTION_NAME } from '../../navigationParams';\nimport { useNavigation } from '../../useNavigation';\nimport { isRoutePreloadedInStack } from '../../utils/stack';\nimport { isModalPresentation } from '../../utils/stackPresentation';\nimport { useSafeLayoutEffect } from '../../views/useSafeLayoutEffect';\nimport { useIsPreview } from '../preview/PreviewRouteContext';\n\nexport function usePreventZoomTransitionDismissal(\n options?: UsePreventZoomTransitionDismissalOptions\n) {\n const context = use(ZoomTransitionTargetContext);\n const route = useRoute();\n const navigation = useNavigation();\n const isPreview = useIsPreview();\n const isFocused = navigation.isFocused();\n const isPreloaded = isPreview ? false : isRoutePreloadedInStack(navigation.getState(), route);\n\n const descriptorsMap = use(DescriptorsContext);\n const currentDescriptor = descriptorsMap[route.key];\n const gestureEnabled = currentDescriptor?.options?.gestureEnabled;\n const isModal = isModalPresentation(currentDescriptor?.options);\n\n useSafeLayoutEffect(() => {\n if (isPreview) return;\n if (isModal) {\n console.warn(\n '[expo-router] usePreventZoomTransitionDismissal has no effect on screens presented modally. Please remove this hook from the screen component or change the screen presentation to a non-modal style.'\n );\n return;\n }\n if (!context.hasEnabler) {\n return;\n }\n const rect = options?.unstable_dismissalBoundsRect;\n\n // Validate rect if provided\n if (rect) {\n const { minX, maxX, minY, maxY } = rect;\n\n // Validate that max > min when both are defined\n if (minX !== undefined && maxX !== undefined && minX >= maxX) {\n console.warn('[expo-router] unstable_dismissalBoundsRect: minX must be less than maxX');\n return;\n }\n if (minY !== undefined && maxY !== undefined && minY >= maxY) {\n console.warn('[expo-router] unstable_dismissalBoundsRect: minY must be less than maxY');\n return;\n }\n }\n\n // Determine the final rect to use for dismissal bounds:\n // 1. If user provided a rect, use it\n // 2. If user disabled gestures entirely (gestureEnabled={false}), block the whole screen\n // by setting impossible bounds { maxX: 0, maxY: 0 }\n // 3. Otherwise, allow normal dismissal (null rect)\n const computedRect = rect ?? (gestureEnabled === false ? { maxX: 0, maxY: 0 } : null);\n\n context.setDismissalBoundsRect?.(computedRect);\n\n if (!isPreloaded || (isPreloaded && isFocused)) {\n // Disable React Navigation's gesture handler when we have custom bounds to prevent conflicts.\n // The native zoom transition's interactiveDismissShouldBegin callback handles dismissal instead.\n // We use the internal option to preserve the user's gestureEnabled setting.\n navigation.setOptions({\n [INTERNAL_EXPO_ROUTER_GESTURE_ENABLED_OPTION_NAME]: computedRect ? false : undefined,\n });\n }\n\n // Cleanup on unmount\n return () => {\n context.setDismissalBoundsRect?.(null);\n };\n }, [\n options?.unstable_dismissalBoundsRect?.minX,\n options?.unstable_dismissalBoundsRect?.maxX,\n options?.unstable_dismissalBoundsRect?.minY,\n options?.unstable_dismissalBoundsRect?.maxY,\n context.setDismissalBoundsRect,\n gestureEnabled,\n navigation,\n isFocused,\n isPreloaded,\n isModal,\n isPreview,\n ]);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zoom-transition-context-providers.ios.d.ts","sourceRoot":"","sources":["../../../src/link/zoom/zoom-transition-context-providers.ios.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,wCAAwC,EACxC,wCAAwC,EACzC,MAAM,2CAA2C,CAAC;AASnD,wBAAgB,mCAAmC,CAAC,EAClD,QAAQ,EACR,SAAS,GACV,EAAE,wCAAwC,+BAgD1C;AAED,wBAAgB,mCAAmC,CAAC,EAClD,KAAK,EACL,QAAQ,GACT,EAAE,wCAAwC,+
|
|
1
|
+
{"version":3,"file":"zoom-transition-context-providers.ios.d.ts","sourceRoot":"","sources":["../../../src/link/zoom/zoom-transition-context-providers.ios.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,wCAAwC,EACxC,wCAAwC,EACzC,MAAM,2CAA2C,CAAC;AASnD,wBAAgB,mCAAmC,CAAC,EAClD,QAAQ,EACR,SAAS,GACV,EAAE,wCAAwC,+BAgD1C;AAED,wBAAgB,mCAAmC,CAAC,EAClD,KAAK,EACL,QAAQ,GACT,EAAE,wCAAwC,+VA+C1C"}
|