From e36b47b792ad0f9722b079f0e0b17e5c38100af7 Mon Sep 17 00:00:00 2001 From: yandadaFreedom Date: Fri, 26 Jun 2026 11:36:54 +0800 Subject: [PATCH 1/6] feat(core): support RN screenOptions config --- .../mpx2rn/references/rn-script-reference.md | 4 +++ docs-vitepress/guide/rn/application-api.md | 26 +++++++++++++++++++ packages/core/@types/index.d.ts | 14 ++++++++++ packages/core/src/platform/createApp.ios.js | 6 ++--- 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/.agents/skills/mpx2rn/references/rn-script-reference.md b/.agents/skills/mpx2rn/references/rn-script-reference.md index e6ec76815e..3dc2f03e2f 100644 --- a/.agents/skills/mpx2rn/references/rn-script-reference.md +++ b/.agents/skills/mpx2rn/references/rn-script-reference.md @@ -698,6 +698,9 @@ Mpx.config.rnConfig = { onStateChange(state) { console.log("navigation state", state) }, + screenOptions: { + animation: "none" + }, openTypeHandler: { onShareAppMessage(shareInfo) { console.log("share", shareInfo) @@ -714,6 +717,7 @@ Mpx.config.rnConfig = { | `projectName` | 由构建注入到 RN 入口,与 `AppRegistry.registerComponent` 相关(偏构建侧)。 | | `parseAppProps` | `(props) => { initialRouteName?, initialParams? }`,解析外层传入 App 根组件的初始路由。 | | `onStateChange` | 导航 state 变化时回调。 | +| `screenOptions` | 自定义 React Navigation `Stack.Navigator` 的 `screenOptions`,会与 Mpx 默认配置合并,用户配置优先。 | | `disableAppStateListener` | 为 `true` 时不注册 `AppState` 监听(避免与宿主 App 重复)。 | | `openTypeHandler` | 对象,注册 `button` 组件在 RN 上 `open-type` 的容器侧实现,未注册对应键时点击会告警。 | | `openTypeHandler.onShareAppMessage` | 对应模板中 `open-type="share"`:框架会先取当前页 `onShareAppMessage` 的返回(含与默认 `title` / `path` 的合并及可选 `promise` 异步结果),再调用本回调,入参为 `{ title, path, imageUrl? }`,由宿主调起系统分享等能力。 | diff --git a/docs-vitepress/guide/rn/application-api.md b/docs-vitepress/guide/rn/application-api.md index ba225bbfa8..211602b651 100644 --- a/docs-vitepress/guide/rn/application-api.md +++ b/docs-vitepress/guide/rn/application-api.md @@ -428,6 +428,32 @@ createComponent({ 在需要将 RN 应用嵌入到现有的 NA 应用中时,可能需要将 RN 的路由栈同步到 NA 中以便于进行路径关系,此时可在此回调中将 RN 路径栈同步到容器中。 +#### mpx.config.rnConfig.screenOptions + +```ts +Record +``` + +用于自定义传入 React Navigation `Stack.Navigator` 的 `screenOptions`。框架会先提供默认配置,再合并用户配置,用户配置优先。 + +默认配置如下: + +```js +{ + headerShown: false, + statusBarTranslucent: mpx.config.rnConfig.statusBarTranslucent ?? true, + statusBarBackgroundColor: 'transparent' +} +``` + +如果需要统一修改转场动画,可配置对象: + +```js +mpx.config.rnConfig.screenOptions = { + animation: 'none' +} +``` + #### mpx.config.rnConfig.onAppBack ```ts diff --git a/packages/core/@types/index.d.ts b/packages/core/@types/index.d.ts index 41c6840928..76ae70f083 100644 --- a/packages/core/@types/index.d.ts +++ b/packages/core/@types/index.d.ts @@ -294,6 +294,13 @@ export interface RnConfig { */ onStateChange?: (state: Record) => void + /** + * 自定义 React Navigation Stack.Navigator 的 screenOptions。 + * + * 会与 Mpx 默认 screenOptions 合并,用户配置优先。 + */ + screenOptions?: Record + /** * 用于获取初始路由配置的函数。 * @@ -320,6 +327,13 @@ export interface RnConfig { */ disableAppStateListener?: boolean + /** + * Stack screenOptions 中 statusBarTranslucent 的默认值。 + * + * @default true + */ + statusBarTranslucent?: boolean + /** * RN 文本类组件是否允许跟随系统字体缩放。 * diff --git a/packages/core/src/platform/createApp.ios.js b/packages/core/src/platform/createApp.ios.js index b6cc29f464..4d7e079fbd 100644 --- a/packages/core/src/platform/createApp.ios.js +++ b/packages/core/src/platform/createApp.ios.js @@ -133,7 +133,7 @@ export default function createApp (options) { cb(options) }) } else if (value === 'hide' || value === 'exit') { - global.__mpxAppCbs.hide.forEach((cb) => { + global.__mpxAppCbs.hide.forEach((cb) => { cb({ reason: value === 'exit' ? 0 : 3 }) @@ -211,11 +211,11 @@ export default function createApp (options) { }, []) const { initialRouteName, initialParams } = initialRouteRef.current - const navScreenOpts = { + const navScreenOpts = Object.assign({ headerShown: false, statusBarTranslucent: Mpx.config.rnConfig.statusBarTranslucent ?? true, statusBarBackgroundColor: 'transparent' - } + }, Mpx.config.rnConfig.screenOptions) return createElement(SafeAreaProvider, null, From 84d9d2e12b0e0c7ff1e225645fd34d6f8d31b6d5 Mon Sep 17 00:00:00 2001 From: yandadaFreedom Date: Fri, 26 Jun 2026 16:07:15 +0800 Subject: [PATCH 2/6] fix: ts error --- .../lib/runtime/components/react/mpx-canvas/index.tsx | 6 ++++-- .../lib/runtime/components/react/mpx-canvas/utils.tsx | 4 +++- .../lib/runtime/components/react/mpx-web-view.tsx | 7 ++++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/index.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/index.tsx index 53d94aeff5..4232bc43f8 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/index.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/index.tsx @@ -33,6 +33,8 @@ import { createImageData as canvasCreateImageData } from './ImageData' import { useConstructorsRegistry } from './constructorsRegistry' import Portal from '../mpx-portal' +type WebViewInstance = WebView<{}> + const stylesheet = StyleSheet.create({ container: { overflow: 'hidden', flex: 0 }, webview: { @@ -268,7 +270,7 @@ const _Canvas = forwardRef, CanvasPr canvasComponent = createElement(View, innerProps, createElement( WebView, { - ref: (element) => { + ref: (element: WebViewInstance | null) => { if (canvasRef.current) { canvasRef.current.webview = element } @@ -293,7 +295,7 @@ const _Canvas = forwardRef, CanvasPr } canvasComponent = createElement(View, innerProps, createElement(WebView, { - ref: (element) => { + ref: (element: WebViewInstance | null) => { if (canvasRef.current) { canvasRef.current.webview = element } diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/utils.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/utils.tsx index 8749001213..cac5c09643 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/utils.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-canvas/utils.tsx @@ -2,6 +2,8 @@ import { useEffect, useRef } from 'react' import { WebView } from 'react-native-webview' import Bus from './Bus' +type WebViewInstance = WebView<{}> + export const WEBVIEW_TARGET = '@@WEBVIEW_TARGET' export const constructors: Record = {} @@ -42,7 +44,7 @@ export interface WebviewMessage { } export interface CanvasInstance { - webview: WebView | null; + webview: WebViewInstance | null; bus: Bus | null; context2D: CanvasRenderingContext2D; getContext: (contextType: string) => CanvasRenderingContext2D | null; diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-web-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-web-view.tsx index ff86251681..e723940bf7 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-web-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-web-view.tsx @@ -30,6 +30,7 @@ interface WebViewProps { binderror?: (event: CommonCallbackEvent) => void [x: string]: any } +type WebViewInstance = WebView<{}> type Listener = (type: string, callback: (e: Event) => void) => () => void interface PayloadData { @@ -77,7 +78,7 @@ const styles = StyleSheet.create({ } }) -const _WebView = forwardRef, WebViewProps>((props, ref): JSX.Element | null => { +const _WebView = forwardRef, WebViewProps>((props, ref): JSX.Element | null => { const { src, bindmessage, bindload, binderror } = props const mpx = global.__mpx const errorText: ErrorTextMap = { @@ -98,7 +99,7 @@ const _WebView = forwardRef, WebViewProps>((pr const { pageId } = useContext(RouteContext) || {} const [pageLoadErr, setPageLoadErr] = useState(false) const currentPage = useMemo(() => getCurrentPage(pageId), [pageId]) - const webViewRef = useRef(null) + const webViewRef = useRef(null) const fristLoaded = useRef(false) const isLoadError = useRef(false) const isNavigateBack = useRef(false) @@ -123,7 +124,7 @@ const _WebView = forwardRef, WebViewProps>((pr isNavigateBack.current = false }) - useNodesRef(props, ref, webViewRef, { + useNodesRef(props, ref, webViewRef, { style: defaultWebViewStyle }) From f0daeb8b0a092ce24e0884f48a3503178b3415eb Mon Sep 17 00:00:00 2001 From: yandadaFreedom Date: Wed, 1 Jul 2026 14:20:45 +0800 Subject: [PATCH 3/6] feat: add rn disablePageTransition config --- .../mpx2rn/references/rn-script-reference.md | 8 +++---- docs-vitepress/guide/rn/application-api.md | 22 +++++-------------- packages/core/@types/index.d.ts | 8 +++---- packages/core/src/index.js | 3 ++- packages/core/src/platform/createApp.ios.js | 7 ++++-- 5 files changed, 19 insertions(+), 29 deletions(-) diff --git a/.agents/skills/mpx2rn/references/rn-script-reference.md b/.agents/skills/mpx2rn/references/rn-script-reference.md index 3dc2f03e2f..79d426c1c3 100644 --- a/.agents/skills/mpx2rn/references/rn-script-reference.md +++ b/.agents/skills/mpx2rn/references/rn-script-reference.md @@ -698,9 +698,7 @@ Mpx.config.rnConfig = { onStateChange(state) { console.log("navigation state", state) }, - screenOptions: { - animation: "none" - }, + disablePageTransition: true, openTypeHandler: { onShareAppMessage(shareInfo) { console.log("share", shareInfo) @@ -717,12 +715,12 @@ Mpx.config.rnConfig = { | `projectName` | 由构建注入到 RN 入口,与 `AppRegistry.registerComponent` 相关(偏构建侧)。 | | `parseAppProps` | `(props) => { initialRouteName?, initialParams? }`,解析外层传入 App 根组件的初始路由。 | | `onStateChange` | 导航 state 变化时回调。 | -| `screenOptions` | 自定义 React Navigation `Stack.Navigator` 的 `screenOptions`,会与 Mpx 默认配置合并,用户配置优先。 | +| `disablePageTransition` | 为 `true` 时禁用 RN 页面转场动画,框架内部映射为 `animation: "none"`。 | | `disableAppStateListener` | 为 `true` 时不注册 `AppState` 监听(避免与宿主 App 重复)。 | | `openTypeHandler` | 对象,注册 `button` 组件在 RN 上 `open-type` 的容器侧实现,未注册对应键时点击会告警。 | | `openTypeHandler.onShareAppMessage` | 对应模板中 `open-type="share"`:框架会先取当前页 `onShareAppMessage` 的返回(含与默认 `title` / `path` 的合并及可选 `promise` 异步结果),再调用本回调,入参为 `{ title, path, imageUrl? }`,由宿主调起系统分享等能力。 | | `openTypeHandler.onUserInfo` | 对应模板中 `open-type="getUserInfo"`:由宿主实现获取用户信息的逻辑,结果需满足按钮侧对 `bindgetuserinfo` 的约定(以 `@mpxjs/webpack-plugin` 中 `mpx-button` 运行时为准)。 | -| `statusBarTranslucent` | 影响 Stack `screenOptions` 中状态栏相关配置。 | +| `statusBarTranslucent` | 影响 RN 导航状态栏相关配置。 | | `getBottomVirtualHeight` | Android 底部虚拟区域高度修正。 | | `loadChunkAsync` | 异步分包加载实现。 | | `downloadChunkAsync` | 分包下载实现,用于实现 preloadRule。 | diff --git a/docs-vitepress/guide/rn/application-api.md b/docs-vitepress/guide/rn/application-api.md index 211602b651..d22f1e5121 100644 --- a/docs-vitepress/guide/rn/application-api.md +++ b/docs-vitepress/guide/rn/application-api.md @@ -428,30 +428,18 @@ createComponent({ 在需要将 RN 应用嵌入到现有的 NA 应用中时,可能需要将 RN 的路由栈同步到 NA 中以便于进行路径关系,此时可在此回调中将 RN 路径栈同步到容器中。 -#### mpx.config.rnConfig.screenOptions +#### mpx.config.rnConfig.disablePageTransition ```ts -Record +boolean ``` -用于自定义传入 React Navigation `Stack.Navigator` 的 `screenOptions`。框架会先提供默认配置,再合并用户配置,用户配置优先。 +用于禁用页面转场动画,默认为 `false`。设置为 `true` 后,框架会在内部导航配置中使用 `animation: 'none'`。 -默认配置如下: +如果需要关闭转场动画,可配置: ```js -{ - headerShown: false, - statusBarTranslucent: mpx.config.rnConfig.statusBarTranslucent ?? true, - statusBarBackgroundColor: 'transparent' -} -``` - -如果需要统一修改转场动画,可配置对象: - -```js -mpx.config.rnConfig.screenOptions = { - animation: 'none' -} +mpx.config.rnConfig.disablePageTransition = true ``` #### mpx.config.rnConfig.onAppBack diff --git a/packages/core/@types/index.d.ts b/packages/core/@types/index.d.ts index 76ae70f083..aa83ee6a5d 100644 --- a/packages/core/@types/index.d.ts +++ b/packages/core/@types/index.d.ts @@ -295,11 +295,11 @@ export interface RnConfig { onStateChange?: (state: Record) => void /** - * 自定义 React Navigation Stack.Navigator 的 screenOptions。 + * 是否禁用页面转场动画。 * - * 会与 Mpx 默认 screenOptions 合并,用户配置优先。 + * @default false */ - screenOptions?: Record + disablePageTransition?: boolean /** * 用于获取初始路由配置的函数。 @@ -328,7 +328,7 @@ export interface RnConfig { disableAppStateListener?: boolean /** - * Stack screenOptions 中 statusBarTranslucent 的默认值。 + * RN 导航状态栏是否默认透明。 * * @default true */ diff --git a/packages/core/src/index.js b/packages/core/src/index.js index 7be9ec943b..cae6a413d1 100644 --- a/packages/core/src/index.js +++ b/packages/core/src/index.js @@ -155,7 +155,8 @@ Mpx.config = { * react-native 相关配置,用于挂载事件等,如 onShareAppMessage */ rnConfig: { - defaultBoxSizing: 'content-box' + defaultBoxSizing: 'content-box', + disablePageTransition: false } } diff --git a/packages/core/src/platform/createApp.ios.js b/packages/core/src/platform/createApp.ios.js index 4d7e079fbd..a51a87a4c5 100644 --- a/packages/core/src/platform/createApp.ios.js +++ b/packages/core/src/platform/createApp.ios.js @@ -211,11 +211,14 @@ export default function createApp (options) { }, []) const { initialRouteName, initialParams } = initialRouteRef.current - const navScreenOpts = Object.assign({ + const navScreenOpts = { headerShown: false, statusBarTranslucent: Mpx.config.rnConfig.statusBarTranslucent ?? true, statusBarBackgroundColor: 'transparent' - }, Mpx.config.rnConfig.screenOptions) + } + if (Mpx.config.rnConfig.disablePageTransition) { + navScreenOpts.animation = 'none' + } return createElement(SafeAreaProvider, null, From c9ee31552f1cdd1712236d88d316705e2c4ea559 Mon Sep 17 00:00:00 2001 From: yandadaFreedom Date: Wed, 1 Jul 2026 14:43:04 +0800 Subject: [PATCH 4/6] doc: update doc --- .../mpx2rn/references/rn-script-reference.md | 84 ++++++++++++------- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/.agents/skills/mpx2rn/references/rn-script-reference.md b/.agents/skills/mpx2rn/references/rn-script-reference.md index 62ddde13f2..4d1da81874 100644 --- a/.agents/skills/mpx2rn/references/rn-script-reference.md +++ b/.agents/skills/mpx2rn/references/rn-script-reference.md @@ -4,35 +4,59 @@ ## 目录 -- [构造选项](#构造选项) - - [App 构造选项](#app-构造选项) - - [页面 / 组件构造选项](#页面--组件构造选项) - - [页面 / 组件实例方法与属性](#页面--组件实例方法与属性) -- [数据响应](#数据响应) -- [组合式 API](#组合式-api) - - [`setup` 的第一个参数 `props`](#setup-的第一个参数-props) - - [`setup` 的第二个参数 `context`](#setup-的第二个参数-context) - - [`