From 919ce91c96ac3176bc5238908389eadb9d203e79 Mon Sep 17 00:00:00 2001 From: dos1in Date: Mon, 27 Apr 2026 17:00:07 +0800 Subject: [PATCH 1/4] feat(rn): add page-container component --- .../template/wx/component-config/index.js | 2 + .../wx/component-config/page-container.js | 33 ++++++++ .../wx/component-config/unsupported.js | 2 +- .../components/react/mpx-page-container.tsx | 83 +++++++++++++++++++ .../lib/utils/dom-tag-config.js | 2 +- 5 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 packages/webpack-plugin/lib/platform/template/wx/component-config/page-container.js create mode 100644 packages/webpack-plugin/lib/runtime/components/react/mpx-page-container.tsx diff --git a/packages/webpack-plugin/lib/platform/template/wx/component-config/index.js b/packages/webpack-plugin/lib/platform/template/wx/component-config/index.js index b5a65229fb..3af422b845 100644 --- a/packages/webpack-plugin/lib/platform/template/wx/component-config/index.js +++ b/packages/webpack-plugin/lib/platform/template/wx/component-config/index.js @@ -21,6 +21,7 @@ const navigator = require('./navigator') const pickerViewColumn = require('./picker-view-column') const pickerView = require('./picker-view') const picker = require('./picker') +const pageContainer = require('./page-container') const progress = require('./progress') const radioGroup = require('./radio-group') const radio = require('./radio') @@ -121,6 +122,7 @@ module.exports = function getComponentConfigs ({ warn, error }) { form({ print }), input({ print }), picker({ print }), + pageContainer({ print }), pickerView({ print }), pickerViewColumn({ print }), slider({ print }), diff --git a/packages/webpack-plugin/lib/platform/template/wx/component-config/page-container.js b/packages/webpack-plugin/lib/platform/template/wx/component-config/page-container.js new file mode 100644 index 0000000000..78738f83c7 --- /dev/null +++ b/packages/webpack-plugin/lib/platform/template/wx/component-config/page-container.js @@ -0,0 +1,33 @@ +const TAG_NAME = 'page-container' + +module.exports = function () { + return { + test: TAG_NAME, + ios (tag, { el }) { + el.isBuiltIn = true + return 'mpx-page-container' + }, + android (tag, { el }) { + el.isBuiltIn = true + return 'mpx-page-container' + }, + harmony (tag, { el }) { + el.isBuiltIn = true + return 'mpx-page-container' + }, + event: [ + { + test: /^(beforeleave)$/, + ios (eventName) { + return eventName + }, + android (eventName) { + return eventName + }, + harmony (eventName) { + return eventName + } + } + ] + } +} diff --git a/packages/webpack-plugin/lib/platform/template/wx/component-config/unsupported.js b/packages/webpack-plugin/lib/platform/template/wx/component-config/unsupported.js index 0c880ea06a..c5dd753820 100644 --- a/packages/webpack-plugin/lib/platform/template/wx/component-config/unsupported.js +++ b/packages/webpack-plugin/lib/platform/template/wx/component-config/unsupported.js @@ -13,7 +13,7 @@ const JD_UNSUPPORTED_TAG_NAME_ARR = ['functional-page-navigator', 'live-pusher', // 快应用不支持的标签集合 const QA_UNSUPPORTED_TAG_NAME_ARR = ['movable-view', 'movable-area', 'open-data', 'official-account', 'editor', 'functional-page-navigator', 'live-player', 'live-pusher', 'ad', 'cover-image'] // RN不支持的标签集合 -const RN_UNSUPPORTED_TAG_NAME_ARR = ['open-data', 'official-account', 'editor', 'functional-page-navigator', 'live-player', 'live-pusher', 'ad', 'audio', 'match-media', 'page-container', 'editor', 'keyboard-accessory', 'map'] +const RN_UNSUPPORTED_TAG_NAME_ARR = ['open-data', 'official-account', 'editor', 'functional-page-navigator', 'live-player', 'live-pusher', 'ad', 'audio', 'match-media', 'editor', 'keyboard-accessory', 'map'] /** * @param {function(object): function} print diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-page-container.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-page-container.tsx new file mode 100644 index 0000000000..ed76a81890 --- /dev/null +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-page-container.tsx @@ -0,0 +1,83 @@ +/** + * ✔ show + * ✔ overlay + * ✔ bind:beforeleave + */ +import { ReactNode, useContext, useEffect, useRef } from 'react' +import { StyleSheet, View } from 'react-native' +import Portal from './mpx-portal' +import { RouteContext } from './context' +import { getCustomEvent } from './getInnerListeners' + +interface PageContainerProps { + show?: boolean + overlay?: boolean + bindbeforeleave?: (event?: any) => void + children?: ReactNode +} + +const styles = StyleSheet.create({ + container: { + position: 'absolute', + top: 0, + right: 0, + bottom: 0, + left: 0, + zIndex: 100 + }, + overlay: { + position: 'absolute', + top: 0, + right: 0, + bottom: 0, + left: 0, + backgroundColor: 'rgba(0,0,0,0.6)' + }, + content: { + position: 'absolute', + top: 0, + right: 0, + bottom: 0, + left: 0 + } +}) + +const _PageContainer = (props: PageContainerProps) => { + const { show = false, overlay = true, bindbeforeleave, children } = props + const { navigation } = useContext(RouteContext) || {} + const showRef = useRef(show) + const propsRef = useRef(props) + + showRef.current = show + propsRef.current = props + + useEffect(() => { + if (!navigation?.addListener) return + + return navigation.addListener('beforeRemove', (e: any) => { + if (!showRef.current) return + + e.preventDefault?.() + propsRef.current.bindbeforeleave?.( + getCustomEvent('beforeleave', e, { detail: {} }, propsRef.current) + ) + }) + }, [navigation, bindbeforeleave]) + + if (!show) return null + + return ( + + + {overlay ? : null} + + {children} + + + + ) +} + +_PageContainer.displayName = 'MpxPageContainer' + +export default _PageContainer diff --git a/packages/webpack-plugin/lib/utils/dom-tag-config.js b/packages/webpack-plugin/lib/utils/dom-tag-config.js index a07accc10f..cece3ce2f7 100644 --- a/packages/webpack-plugin/lib/utils/dom-tag-config.js +++ b/packages/webpack-plugin/lib/utils/dom-tag-config.js @@ -87,7 +87,7 @@ const isBuildInWebTag = makeMap( const isBuildInReactTag = makeMap( 'mpx-web-view,mpx-view,mpx-video,mpx-textarea,mpx-text,mpx-switch,' + 'mpx-swiper,mpx-swiper-item,mpx-scroll-view,' + - 'mpx-root-portal,mpx-radio,mpx-radio-group,mpx-navigator,mpx-movable-view,' + + 'mpx-root-portal,mpx-page-container,mpx-radio,mpx-radio-group,mpx-navigator,mpx-movable-view,' + 'mpx-movable-area,mpx-label,mpx-input,' + 'mpx-image,mpx-form,mpx-checkbox,mpx-checkbox-group,mpx-button,' + 'mpx-rich-text,mpx-picker-view-column,mpx-picker-view,mpx-picker,' + From d16ab9775702ab89aea691b1c46605701f6e4e84 Mon Sep 17 00:00:00 2001 From: dos1in Date: Mon, 27 Apr 2026 19:06:29 +0800 Subject: [PATCH 2/4] docs(rn): update component documentation and add page-container details --- docs-vitepress/guide/rn/component.md | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/docs-vitepress/guide/rn/component.md b/docs-vitepress/guide/rn/component.md index 9f726bfe32..0c7cac447b 100644 --- a/docs-vitepress/guide/rn/component.md +++ b/docs-vitepress/guide/rn/component.md @@ -5,7 +5,7 @@ ### 目录概览 {#directory-overview} - #### 基础组件 -**容器组件**:[view](#view) · [scroll-view](#scroll-view) · [swiper](#swiper) · [swiper-item](#swiper-item) · [movable-area](#movable-area) · [movable-view](#movable-view) · [root-portal](#root-portal) · [sticky-section](#sticky-section) · [sticky-header](#sticky-header) · [cover-view](#cover-view) +**容器组件**:[view](#view) · [scroll-view](#scroll-view) · [swiper](#swiper) · [swiper-item](#swiper-item) · [movable-area](#movable-area) · [movable-view](#movable-view) · [page-container](#page-container) · [root-portal](#root-portal) · [sticky-section](#sticky-section) · [sticky-header](#sticky-header) · [cover-view](#cover-view) **媒体组件**:[image](#image) · [video](#video) · [canvas](#canvas) @@ -731,6 +731,28 @@ API > [!tip] 注意 > > - style 样式不支持中使用百分比计算、css variable + +### page-container +页面内容容器,常用于实现“假页”弹层。容器展示期间会拦截页面返回行为(包含返回按钮与侧滑返回),并通过回调通知业务侧自行关闭容器。 + +属性 + +| 属性名 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| show | boolean | `false` | 是否显示容器 | +| overlay | boolean | `true` | 是否显示遮罩层 | + +事件 + +| 事件名 | 说明 | +| --- | --- | +| bind:beforeleave | 触发返回离开前回调,业务可在回调中更新 `show=false` 关闭容器 | + +> [!tip] 注意 +> +> - 当前仅支持 `show`、`overlay` 与 `bind:beforeleave` 三项能力。 +> - 容器显示时会自动禁用页面返回手势,并在隐藏时恢复,避免 `native-stack` 场景下手势返回与 JS 状态不一致。 +> - 该组件依赖导航上下文,仅在 RN 页面路由栈内生效。 ### sticky-section 吸顶布局容器,仅支持作为 `` 的直接子节点 From 57384902d8ac2bce76bd1a5074244f3094eef536 Mon Sep 17 00:00:00 2001 From: dos1in Date: Mon, 27 Apr 2026 19:07:12 +0800 Subject: [PATCH 3/4] fix: lint fix --- .../lib/runtime/components/react/mpx-page-container.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-page-container.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-page-container.tsx index ed76a81890..4fbff45222 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-page-container.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-page-container.tsx @@ -42,7 +42,7 @@ const styles = StyleSheet.create({ } }) -const _PageContainer = (props: PageContainerProps) => { +const PageContainer = (props: PageContainerProps) => { const { show = false, overlay = true, bindbeforeleave, children } = props const { navigation } = useContext(RouteContext) || {} const showRef = useRef(show) @@ -78,6 +78,6 @@ const _PageContainer = (props: PageContainerProps) => { ) } -_PageContainer.displayName = 'MpxPageContainer' +PageContainer.displayName = 'MpxPageContainer' -export default _PageContainer +export default PageContainer From 65cb53063775c58e98efb5a30c8d6dea6964e138 Mon Sep 17 00:00:00 2001 From: dos1in Date: Mon, 27 Apr 2026 21:04:12 +0800 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=85=83=E7=B4=A0=E4=BA=8B=E4=BB=B6=E8=A2=AB=E6=8B=A6=E6=88=AA?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runtime/components/react/mpx-page-container.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-page-container.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-page-container.tsx index 4fbff45222..1097bc9d2a 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-page-container.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-page-container.tsx @@ -31,14 +31,16 @@ const styles = StyleSheet.create({ right: 0, bottom: 0, left: 0, - backgroundColor: 'rgba(0,0,0,0.6)' + backgroundColor: 'rgba(0,0,0,0.6)', + zIndex: 0 }, content: { position: 'absolute', top: 0, right: 0, bottom: 0, - left: 0 + left: 0, + zIndex: 1 } }) @@ -68,8 +70,8 @@ const PageContainer = (props: PageContainerProps) => { return ( - - {overlay ? : null} + + {overlay ? : null} {children}