已关闭
fix: 补充close/open链卸载守卫与兜底;panresponderThreshold阈值生效;supportedOrientations朝向约束 #32
fix: 补充close/open链卸载守卫与兜底;panresponderThreshold阈值生效;supportedOrientations朝向约束 #32
已关闭
mazheng创建于 8月31日关闭于 9月17日
共 6 个文件变更+333-98
@@ -1,3 +1,12 @@
1+# v14.0.2-beta.2
2+ 
3+- fix: 修复关闭弹窗时抛出 TypeError 的问题。为 open/close 链路补充组件卸载守卫(卸载后置空 ref、丢弃迟到的动画回调),并在 animatable 宿主缺失时走无动画兜底,避免 `isTransitioning` 卡在 true 后再也无法打开/关闭弹窗。
4+- fix: `panResponderThreshold` 属性生效。滑动识别改为在累计位移超过阈值后才触发,低于阈值的手势视为点击,弹窗不再位移,`onSwipeStart`/`onSwipeMove` 也不会误触发。
5+- fix: `hideModalContentWhileAnimating` 属性生效。原逻辑依赖 `useNativeDriver` 且依赖弹窗可见期恒为 true 的 `showContent`,导致属性始终不起作用;现改为由进出场过渡自身驱动,取值为 true 时整个动画过程都隐藏弹窗内容,且不再受动画驱动方式限制。
6+- feat: HarmonyOS 上按 `supportedOrientations` 约束弹窗布局尺寸,窗口旋转到未声明支持的方向时,弹窗仍按支持的方向渲染(iOS 原生能力的布局层模拟,不会真正锁定窗口方向)。
7+- fix: 滑动百分比改用真实窗口尺寸计算,修复朝向约束下分母为负、导致遮罩透明度异常与 `onSwipeMove` 回传百分比越界的问题。
8+- docs: 更新中英文文档中 `hideModalContentWhileAnimating`、`panResponderThreshold` 的 HarmonyOS 平台支持情况,并同步移除对应的遗留问题描述。
9+ 
1# v14.0.2-beta.110# v14.0.2-beta.1
2 11 
3- fix: 解决 77 框架上获取版本号空指针问题,添加非空处理12- fix: 解决 77 框架上获取版本号空指针问题,添加非空处理
@@ -181,7 +181,7 @@ export default DefaultModal;
181| onSwipeMove | `func` | (percentageShown) => null | no | all | yes | 每次滑动事件触发时调用 |181| onSwipeMove | `func` | (percentageShown) => null | no | all | yes | 每次滑动事件触发时调用 |
182| onSwipeComplete | `func` | ({ swipingDirection }) => null | no | all | yes | 达到滑动阈值时触发 |182| onSwipeComplete | `func` | ({ swipingDirection }) => null | no | all | yes | 达到滑动阈值时触发 |
183| onSwipeCancel | `func` | () => null | no | all | yes | 未达到滑动阈值时触发 |183| onSwipeCancel | `func` | () => null | no | all | yes | 未达到滑动阈值时触发 |
184-| panResponderThreshold | `number` | 4 | no | all | no | 触摸响应器开始识别滑动事件的阈值 |184+| panResponderThreshold | `number` | 4 | no | all | yes | 触摸响应器开始识别滑动事件的阈值 |
185| scrollOffset | `number` | 0 | no | all | no | 大于 0 时禁用滑动关闭功能,用于实现可滚动内容 |185| scrollOffset | `number` | 0 | no | all | no | 大于 0 时禁用滑动关闭功能,用于实现可滚动内容 |
186| scrollOffsetMax | `number` | 0 | no | all | yes | 用于实现内容可滚动时的越界滚动效果 |186| scrollOffsetMax | `number` | 0 | no | all | yes | 用于实现内容可滚动时的越界滚动效果 |
187| scrollTo | `func` | null | no | all | yes | 用于实现可滚动弹窗 |187| scrollTo | `func` | null | no | all | yes | 用于实现可滚动弹窗 |
@@ -190,7 +190,7 @@ export default DefaultModal;
190| swipeDirection | `string` or `array` | null | no | all | yes | 定义弹窗可滑动的方向,支持 up/down/left/right 单个值或数组组合 |190| swipeDirection | `string` or `array` | null | no | all | yes | 定义弹窗可滑动的方向,支持 up/down/left/right 单个值或数组组合 |
191| useNativeDriver | `bool` | false | no | all | yes | 是否使用原生驱动执行动画 |191| useNativeDriver | `bool` | false | no | all | yes | 是否使用原生驱动执行动画 |
192| useNativeDriverForBackdrop | `bool` | null | no | all | yes | 遮罩层动画是否使用原生驱动(避免安卓端闪烁问题) |192| useNativeDriverForBackdrop | `bool` | null | no | all | yes | 遮罩层动画是否使用原生驱动(避免安卓端闪烁问题) |
193-| hideModalContentWhileAnimating | `bool` | false | no | all | no | 动画完成前隐藏弹窗内容以提升性能 |193+| hideModalContentWhileAnimating | `bool` | false | no | all | yes | 动画完成前隐藏弹窗内容以提升性能 |
194| propagateSwipe | `bool` or `func` | false | no | all | no | 允许滑动事件传递给子组件(如弹窗内的滚动视图) |194| propagateSwipe | `bool` or `func` | false | no | all | no | 允许滑动事件传递给子组件(如弹窗内的滚动视图) |
195| style | `any` | null | no | all | yes | 应用到弹窗的样式 |195| style | `any` | null | no | all | yes | 应用到弹窗的样式 |
196| hardwareAccelerated | `bool` | false | no | android | no | 强制为 Modal 独立窗口开启 GPU 硬件加速渲染 |196| hardwareAccelerated | `bool` | false | no | android | no | 强制为 Modal 独立窗口开启 GPU 硬件加速渲染 |
@@ -210,8 +210,7 @@ export default DefaultModal;
210 210 
211## 遗留问题211## 遗留问题
212 212 
213-- [ ] hideModalContentWhileAnimating 属性无效果,上游社区 bug。213+- [ ] 三端表现一致,存在滑动冲突问题,在此场景下不支持 scrollOffset,propagateSwipe。
214-- [ ] 三端表现一致,存在滑动冲突问题,在此场景下不支持 scrollOffset,propagateSwipe,panResponderThreshold。
215- [ ] 组件显示及关闭时框架或 ArkUI 的 modal 的 isVisible 状态切换与动画的结束时机存在时序竞争,导致视觉呈现 Modal 闪烁。214- [ ] 组件显示及关闭时框架或 ArkUI 的 modal 的 isVisible 状态切换与动画的结束时机存在时序竞争,导致视觉呈现 Modal 闪烁。
216 215 
217## 其他216## 其他
@@ -181,7 +181,7 @@ export default DefaultModal;
181| onSwipeMove | `func` | (percentageShown) => null | no | all | yes | Called on each swipe event |181| onSwipeMove | `func` | (percentageShown) => null | no | all | yes | Called on each swipe event |
182| onSwipeComplete | `func` | ({ swipingDirection }) => null | no | all | yes | Triggered when the swipe threshold is reached |182| onSwipeComplete | `func` | ({ swipingDirection }) => null | no | all | yes | Triggered when the swipe threshold is reached |
183| onSwipeCancel | `func` | () => null | no | all | yes | Triggered when the swipe threshold is not reached |183| onSwipeCancel | `func` | () => null | no | all | yes | Triggered when the swipe threshold is not reached |
184-| panResponderThreshold | `number` | 4 | no | all | no | Threshold at which the touch responder starts recognizing swipe events |184+| panResponderThreshold | `number` | 4 | no | all | yes | Threshold at which the touch responder starts recognizing swipe events |
185| scrollOffset | `number` | 0 | no | all | no | When greater than 0, disables swipe-to-close; used for scrollable content |185| scrollOffset | `number` | 0 | no | all | no | When greater than 0, disables swipe-to-close; used for scrollable content |
186| scrollOffsetMax | `number` | 0 | no | all | yes | Used to implement overscroll effects when content is scrollable |186| scrollOffsetMax | `number` | 0 | no | all | yes | Used to implement overscroll effects when content is scrollable |
187| scrollTo | `func` | null | no | all | yes | Used to implement a scrollable modal |187| scrollTo | `func` | null | no | all | yes | Used to implement a scrollable modal |
@@ -190,7 +190,7 @@ export default DefaultModal;
190| swipeDirection | `string` or `array` | null | no | all | yes | Defines the swipe direction(s) of the modal; supports a single value or an array combination of up/down/left/right |190| swipeDirection | `string` or `array` | null | no | all | yes | Defines the swipe direction(s) of the modal; supports a single value or an array combination of up/down/left/right |
191| useNativeDriver | `bool` | false | no | all | yes | Whether to use the native driver to run animations |191| useNativeDriver | `bool` | false | no | all | yes | Whether to use the native driver to run animations |
192| useNativeDriverForBackdrop | `bool` | null | no | all | yes | Whether the backdrop animation uses the native driver (avoids flicker on Android) |192| useNativeDriverForBackdrop | `bool` | null | no | all | yes | Whether the backdrop animation uses the native driver (avoids flicker on Android) |
193-| hideModalContentWhileAnimating | `bool` | false | no | all | no | Hide the modal content before the animation completes to improve performance |193+| hideModalContentWhileAnimating | `bool` | false | no | all | yes | Hide the modal content before the animation completes to improve performance |
194| propagateSwipe | `bool` or `func` | false | no | all | no | Allow swipe events to propagate to child components (e.g., a scroll view inside the modal) |194| propagateSwipe | `bool` or `func` | false | no | all | no | Allow swipe events to propagate to child components (e.g., a scroll view inside the modal) |
195| style | `any` | null | no | all | yes | Style applied to the modal |195| style | `any` | null | no | all | yes | Style applied to the modal |
196| hardwareAccelerated | `bool` | false | no | android | no | Force GPU hardware-accelerated rendering for the Modal's independent window |196| hardwareAccelerated | `bool` | false | no | android | no | Force GPU hardware-accelerated rendering for the Modal's independent window |
@@ -210,8 +210,7 @@ export default DefaultModal;
210 210 
211## Known Issues211## Known Issues
212 212 
213-- [ ] The hideModalContentWhileAnimating property has no effect; it’s an upstream community bug.213+- [ ] Consistent behavior across all three platforms. There are sliding conflict issues, and scrollOffset and propagateSwipe are not supported in this scenario.
214-- [ ] Consistent behavior across all three platforms. There are sliding conflict issues, and scrollOffset, propagateSwipe, and panResponderThreshold are not supported in this scenario.
215- [ ] When the component shows and dismisses, a timing race condition exists between the `isVisible` state toggle of framework/ArkUI Modal and animation finish timing, which causes Modal visual flickering.214- [ ] When the component shows and dismisses, a timing race condition exists between the `isVisible` state toggle of framework/ArkUI Modal and animation finish timing, which causes Modal visual flickering.
216 215 
217## Others216## Others
@@ -8,7 +8,7 @@
8 "start": "hdc rport tcp:8081 tcp:8081 && react-native start",8 "start": "hdc rport tcp:8081 tcp:8081 && react-native start",
9 "codegen": "react-native codegen-harmony --rnoh-module-path ./harmony/entry/oh_modules/@rnoh/react-native-openharmony",9 "codegen": "react-native codegen-harmony --rnoh-module-path ./harmony/entry/oh_modules/@rnoh/react-native-openharmony",
10 "pack:pkg": "cd ../ && npm pack && cd ./example",10 "pack:pkg": "cd ../ && npm pack && cd ./example",
11- "install:pkg": "npm uninstall @react-native-ohos/react-native-modal && npm run pack:pkg && npm i @react-native-ohos/react-native-modal@file:../react-native-ohos-react-native-modal-14.0.2-beta.1.tgz",11+ "install:pkg": "npm uninstall @react-native-ohos/react-native-modal && npm run pack:pkg && npm i @react-native-ohos/react-native-modal@file:../react-native-ohos-react-native-modal-14.0.2-beta.2.tgz",
12 "dev": "npm run codegen && react-native bundle-harmony --dev --minify=false",12 "dev": "npm run codegen && react-native bundle-harmony --dev --minify=false",
13 "prod": "npm run codegen && react-native bundle-harmony --dev=false --minify=true",13 "prod": "npm run codegen && react-native bundle-harmony --dev=false --minify=true",
14 "postinstall": "node ./scripts/create-build-profile",14 "postinstall": "node ./scripts/create-build-profile",
@@ -17,7 +17,7 @@
17 },17 },
18 "dependencies": {18 "dependencies": {
19 "@react-native-oh/react-native-harmony": "0.77.18-1",19 "@react-native-oh/react-native-harmony": "0.77.18-1",
20- "@react-native-ohos/react-native-modal": "file:../react-native-ohos-react-native-modal-14.0.2-beta.1.tgz",20+ "@react-native-ohos/react-native-modal": "file:../react-native-ohos-react-native-modal-14.0.2-beta.2.tgz",
21 "react": "18.3.1",21 "react": "18.3.1",
22 "react-native": "0.77.1",22 "react-native": "0.77.1",
23 "react-native-harmony": "npm:@react-native-oh/react-native-harmony@0.77.18-1"23 "react-native-harmony": "npm:@react-native-oh/react-native-harmony@0.77.18-1"
@@ -1,6 +1,6 @@
1{1{
2 "name": "@react-native-ohos/react-native-modal",2 "name": "@react-native-ohos/react-native-modal",
3- "version": "14.0.2-beta.1",3+ "version": "14.0.2-beta.2",
4 "description": "An enhanced React Native modal",4 "description": "An enhanced React Native modal",
5 "main": "dist/index.js",5 "main": "dist/index.js",
6 "types": "dist/index.d.ts",6 "types": "dist/index.d.ts",
@@ -47,9 +47,19 @@ export type OnSwipeCompleteParams = {
47 47 
48type State = {48type State = {
49 showContent: boolean;49 showContent: boolean;
50+ // True from the moment an entrance/exit transition is kicked off until it
51+ // settles. Unlike the isTransitioning instance field this lives in state,
52+ // so toggling it re-renders and hideModalContentWhileAnimating can actually
53+ // take effect.
54+ isAnimatingContent: boolean;
50 isVisible: boolean;55 isVisible: boolean;
51 deviceWidth: number;56 deviceWidth: number;
52 deviceHeight: number;57 deviceHeight: number;
58+ // Real (unconstrained) window size. The backdrop is sized from the real
59+ // window at render time, so these are tracked to detect rotations that do
60+ // not change the orientation-constrained geometry and still re-render.
61+ realWindowWidth: number;
62+ realWindowHeight: number;
53 isSwipeable: boolean;63 isSwipeable: boolean;
54 pan: OrNull<Animated.ValueXY>;64 pan: OrNull<Animated.ValueXY>;
55};65};