Skip to content

Commit 0baa512

Browse files
authored
Merge branch 'master' into fix-transSubpackageRules-to-main
2 parents 7b72317 + cf063a5 commit 0baa512

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+3156
-609
lines changed

docs-vitepress/api-proxy/interface/menu/getMenuButtonBoundingClientRect.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
获取菜单按钮(右上角胶囊按钮)的布局位置信息。坐标信息以屏幕左上角为原点。
44

5-
支持情况: 微信、支付宝
5+
支持情况: 微信、支付宝、React Native
6+
7+
> **React Native 说明**: 由于 RN 应用没有微信的右上角胶囊按钮,该 API 会基于屏幕尺寸和安全区返回一个模拟的胶囊位置,可用于获取顶部导航区域的参考尺寸,保持代码兼容性。
68
79
[参考文档](https://developers.weixin.qq.com/miniprogram/dev/api/ui/menu/wx.getMenuButtonBoundingClientRect.html)
810

docs-vitepress/guide/rn/application-api.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,3 +476,24 @@ boolean
476476
Mpx 框架默认会使用 `ReactNative.AppState.addEventListener('change', callback)` 作为 Mpx 应用切换切换台的驱动,从而触发对于的钩子(如onhide/onshow)
477477
478478
在需要将 RN 应用嵌入到现有的 NA 应用中时,可能会出现AppState触发时机异常的情况(例如从 RN 页面跳转到 NA 页面时),此时可以将 disableAppStateListener 设置为 true 来禁用框架内部对 AppState 的监听。但需要在合适的时机手动调用 setAppShow() 与 setAppHide() 方法来进行驱动以确保对于的钩子能正常触发。
479+
480+
481+
### 自定义设置底部虚拟按键区高度
482+
483+
#### mpx.config.rnConfig.getBottomVirtualHeight
484+
485+
```ts
486+
() => number
487+
```
488+
Android的不同系统或者手机的虚拟按键区高度可能存在不同的情况,框架内部统一使用了initialWindowMetrics.insets.bottom,如存在需要单独调整的场景可自定义设置虚拟按键区高度。
489+
490+
```javascript
491+
// 例子
492+
import ReactNative from 'react-native'
493+
import { initialWindowMetrics } from 'react-native-safe-area-context'
494+
mpx.config.rnConfig.getBottomVirtualHeight = (bottomHeight) => {
495+
const screenDimensions = ReactNative.Dimensions.get('screen')
496+
const windowDimensions = ReactNative.Dimensions.get('window')
497+
return Math.max(initialWindowMetrics?.insets?.bottom || 0 , (screenDimensions.height - windowDimensions.height - ReactNative.StatusBar.currentHeight) || 0, 0)
498+
}vscode 如何打开markdown
499+
```

docs-vitepress/guide/rn/component.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ movable-view的可移动区域。
401401
| focus | boolean | `false` | 获取焦点 |
402402
| auto-height | boolean | `false` | 是否自动增高,设置 auto-height 时,style.height不生效 |
403403
| confirm-type | string | `done` | 设置键盘右下角按钮的文字,可选值为 `send``search``next``go``done`,不支持 `return` |
404-
| confirm-hold | boolean | `false` | 点击键盘右下角按钮时是否保持键盘不收起 |
404+
| confirm-hold | | | 暂不支持 |
405405
| hold-keyboard | boolean | `false` | 输入框聚焦时,点击页面其他地方是否收起键盘 <badge type="tip" text="2.10.18+" /> |
406406
| cursor | number | | 指定 focus 时的光标位置 |
407407
| cursor-color | string | | 光标颜色 |

docs-vitepress/guide/rn/style.md

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
RN 样式属性和 Web/小程序中 CSS 样式属性是相交关系:
1717

1818
- **RN 独有属性**`tintColor``writingDirection` 等,CSS 不支持
19-
- **CSS 独有属性**`clip-path``animation``transition` 等,RN 不支持
19+
- **CSS 独有属性**`clip-path``animation` 等,RN 不支持
2020

2121
因此,在跨平台开发时:
2222
1. **优先使用交集属性**:尽量使用两边都支持的样式属性
@@ -1429,3 +1429,110 @@ object-fit: contain; /* 完整显示,保持比例 */
14291429
object-fit: cover; /* 覆盖填充,保持比例,可能裁剪 */
14301430
object-fit: scale-down; /* 缩小显示 */
14311431
```
1432+
1433+
1434+
## 跨端动画
1435+
基础组件 view 支持两种动画形式 createAnimation API 和 transition,
1436+
可以通过设置 animation 属于来使用 createAnimation API 动画,通过 class 或者 style 设置 css transition 来使用 transition 动画,
1437+
可以用过 prop enable-animation = api/transition 来指定使用 createAnimation API/transition 的动画形式,,enable-animation 设置 true 默认为 createAnimation API 形式,需要注意的是指定动画类型后,对应的动画参数也需要匹配设置,详细使用文档如下:
1438+
1439+
### createAnimation 动画API
1440+
创建一个动画实例 animation,调用实例的方法来描述动画,最后通过动画实例的 export 方法导出动画数据传递给组件的 animation 属性。
1441+
详情参考以下动画部分微信小程序文档,以下仅描述支持能力有差异部分:
1442+
#### [wx.createAnimation](https://developers.weixin.qq.com/miniprogram/dev/api/ui/animation/wx.createAnimation.html)
1443+
- 参数 timingFunction 不支持 step-start 和 step-end
1444+
#### [动画实例 animation](https://developers.weixin.qq.com/miniprogram/dev/api/ui/animation/Animation.html)
1445+
- translateZ() 不支持
1446+
- translate3d() 不支持
1447+
- rotate3d() 不支持
1448+
- rotateZ() 不支持
1449+
- scaleZ() 不支持
1450+
- scale3d() 不支持
1451+
- animation.matrix() 不支持
1452+
- animation.matrix3d() 不支持
1453+
1454+
### CSS transition
1455+
CSS transition 动画至少需要设置动画时长和动画属性,可通过单独属性 transition-property 和 transition-property 设置,也可以通过 transition 缩写设置
1456+
>重要提示:transition 支持设置百分比,如 ```marginTop: 1%;marginTop: 100%;```;要注意的是起始值和结束值需设置为同一类型,同为px或者同为百分比, 支持 ```marginTop: 10px;marginTop: 100px; ```**不支持 ```marginTop: 10px; marginTop: 100%;```**
1457+
1458+
#### [transition](https://developer.mozilla.org/en-US/docs/Web/CSS/transition)
1459+
```css
1460+
/**** 支持 */
1461+
/* property name | duration */
1462+
transition: margin-right 4s;
1463+
/* property name | duration | delay */
1464+
transition: margin-right 4s 1s;
1465+
/* property name | duration | easing function */
1466+
transition: margin-right 4s ease-in-out;
1467+
/* property name | duration | easing function | delay */
1468+
transition: margin-right 4s ease-in-out 1s;
1469+
1470+
/* Apply to 2 properties */
1471+
transition: margin-right 4s, color 1s;
1472+
```
1473+
```css
1474+
/**** 需配合 transition-property 使用*/
1475+
/* transition 未定义 property 时需配合 transition-property 使用,否则仅设置duration、timingFunciton等参数实际动画不生效 */
1476+
transition: 200ms linear 50ms;
1477+
transition: 2s, 1s;
1478+
```
1479+
```css
1480+
/**** 不支持:property 不支持设置为 all */
1481+
transition: all 0.5s ease-out
1482+
```
1483+
#### [transition-property](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-property)
1484+
不支持设置为 all,不支持自定义
1485+
> 支持的 property 合集有:
1486+
> rotateX rotateY rotateZ scaleX scaleY skewX skewY translateX translateY opacity backgroundColor width height top right bottom left color borderColor borderBottomColor borderLeftColor borderRightColor borderTopColor borderTopLeftRadius borderTopRightRadius borderBottomLeftRadius borderBottomRightRadius borderRadius borderBottomWidth borderLeftWidth borderRightWidth borderTopWidth borderWidth margin marginBottom marginLeft marginRight marginTop maxHeight maxWidth minHeight minWidth padding paddingBottom paddingLeft paddingRight paddingTop
1487+
```css
1488+
/**** 支持 */
1489+
transition-property: height;
1490+
transition-property: height, color;
1491+
```
1492+
```css
1493+
/**** 不支持 */
1494+
transition-property: all;
1495+
/* <custom-ident> values */
1496+
transition-property: test_05;
1497+
transition-property: -specific;
1498+
transition-property: sliding-vertically;
1499+
transition-property: test1, animation4;
1500+
transition-property: all, -moz-specific, sliding;
1501+
transition-property: inherit;
1502+
transition-property: initial;
1503+
transition-property: revert;
1504+
transition-property: revert-layer;
1505+
transition-property: unset;
1506+
```
1507+
#### [transition-duration](https://developer.mozilla.org/zh-CN/docs/Web/CSS/transition-duration)
1508+
```css
1509+
/**** 支持 */
1510+
transition-duration: 6s;
1511+
transition-duration: 120ms;
1512+
transition-duration: 1s, 15s;
1513+
transition-duration: 10s, 30s, 230ms;
1514+
```
1515+
#### [transition-delay](https://developer.mozilla.org/zh-CN/docs/Web/CSS/transition-delay)
1516+
```css
1517+
/**** 支持 */
1518+
transition-delay: 3s;
1519+
transition-delay: 2s, 4ms;
1520+
```
1521+
#### [transition-behavior](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-behavior)
1522+
不支持
1523+
#### [transition-timing-function](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-timing-function)
1524+
仅支持 ease、ease-inease-outease-in-out、linear、cubic-bezier(),不支持 step-startstep-end、steps()
1525+
1526+
### CSS animation
1527+
暂不支持
1528+
1529+
### 动画监听事件
1530+
#### transitionend
1531+
- CSS transition 结束或 wx.createAnimation 结束一个阶段时触发
1532+
- 不属于冒泡事件,需要绑定在真正发生了动画的节点上才会生效
1533+
#### animationstart
1534+
暂不支持
1535+
#### animationiteration
1536+
暂不支持
1537+
#### animationend
1538+
暂不支持

packages/api-proxy/@types/index.d.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,36 @@ export const offError: WechatMiniprogram.Wx['offError']
4545
export const createInnerAudioContext: WechatMiniprogram.Wx['createInnerAudioContext']
4646
export const base64ToArrayBuffer: WechatMiniprogram.Wx['base64ToArrayBuffer']
4747
export const arrayBufferToBase64: WechatMiniprogram.Wx['arrayBufferToBase64']
48+
export const openBluetoothAdapter: WechatMiniprogram.Wx['openBluetoothAdapter']
49+
export const closeBluetoothAdapter: WechatMiniprogram.Wx['closeBluetoothAdapter']
50+
export const startBluetoothDevicesDiscovery: WechatMiniprogram.Wx['startBluetoothDevicesDiscovery']
51+
export const stopBluetoothDevicesDiscovery: WechatMiniprogram.Wx['stopBluetoothDevicesDiscovery']
52+
export const onBluetoothDeviceFound: WechatMiniprogram.Wx['onBluetoothDeviceFound']
53+
export const offBluetoothDeviceFound: WechatMiniprogram.Wx['offBluetoothDeviceFound']
54+
export const getConnectedBluetoothDevices: WechatMiniprogram.Wx['getConnectedBluetoothDevices']
55+
export const getBluetoothAdapterState: WechatMiniprogram.Wx['getBluetoothAdapterState']
56+
export const onBluetoothAdapterStateChange: WechatMiniprogram.Wx['onBluetoothAdapterStateChange']
57+
export const offBluetoothAdapterStateChange: WechatMiniprogram.Wx['offBluetoothAdapterStateChange']
58+
export const getBluetoothDevices: WechatMiniprogram.Wx['getBluetoothDevices']
59+
export const writeBLECharacteristicValue: WechatMiniprogram.Wx['writeBLECharacteristicValue']
60+
export const readBLECharacteristicValue: WechatMiniprogram.Wx['readBLECharacteristicValue']
61+
export const notifyBLECharacteristicValueChange: WechatMiniprogram.Wx['notifyBLECharacteristicValueChange']
62+
export const onBLECharacteristicValueChange: WechatMiniprogram.Wx['onBLECharacteristicValueChange']
63+
export const offBLECharacteristicValueChange: WechatMiniprogram.Wx['offBLECharacteristicValueChange']
64+
export const setBLEMTU: WechatMiniprogram.Wx['setBLEMTU']
65+
export const getBLEDeviceRSSI: WechatMiniprogram.Wx['getBLEDeviceRSSI']
66+
export const getBLEDeviceServices: WechatMiniprogram.Wx['getBLEDeviceServices']
67+
export const getBLEDeviceCharacteristics: WechatMiniprogram.Wx['getBLEDeviceCharacteristics']
4868
export const closeBLEConnection: WechatMiniprogram.Wx['closeBLEConnection']
4969
export const createBLEConnection: WechatMiniprogram.Wx['createBLEConnection']
5070
export const onBLEConnectionStateChange: WechatMiniprogram.Wx['onBLEConnectionStateChange']
71+
export const offBLEConnectionStateChange: WechatMiniprogram.Wx['offBLEConnectionStateChange']
72+
export const startWifi: WechatMiniprogram.Wx['startWifi']
73+
export const stopWifi: WechatMiniprogram.Wx['stopWifi']
74+
export const getWifiList: WechatMiniprogram.Wx['getWifiList']
75+
export const onGetWifiList: WechatMiniprogram.Wx['onGetWifiList']
76+
export const offGetWifiList: WechatMiniprogram.Wx['offGetWifiList']
77+
export const getConnectedWifi: WechatMiniprogram.Wx['getConnectedWifi']
5178
export const createCanvasContext: WechatMiniprogram.Wx['createCanvasContext']
5279
export const canvasToTempFilePath: WechatMiniprogram.Wx['canvasToTempFilePath']
5380
export const canvasGetImageData: WechatMiniprogram.Wx['canvasGetImageData']
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// 测试 RN 环境下的 canIUse 函数
2+
import { canIUse } from '../../src/platform/api/base/rnCanIUse'
3+
4+
describe('canIUse for RN', () => {
5+
test('should support basic APIs', () => {
6+
expect(canIUse('navigateTo')).toBe(true)
7+
expect(canIUse('showToast')).toBe(true)
8+
expect(canIUse('request')).toBe(true)
9+
expect(canIUse('getSystemInfo')).toBe(true)
10+
expect(canIUse('vibrateShort')).toBe(true)
11+
expect(canIUse('getStorage')).toBe(true)
12+
})
13+
14+
test('should return false for unsupported APIs', () => {
15+
expect(canIUse('setClipboardData')).toBe(false)
16+
expect(canIUse('getClipboardData')).toBe(false)
17+
expect(canIUse('someUnsupportedApi')).toBe(false)
18+
expect(canIUse('wx.someMethod')).toBe(false)
19+
expect(canIUse('nonExistentApi')).toBe(false)
20+
expect(canIUse('undefinedMethod')).toBe(false)
21+
})
22+
23+
test('should support API with methods', () => {
24+
expect(canIUse('request.success')).toBe(true)
25+
expect(canIUse('showModal.success.confirm')).toBe(true)
26+
})
27+
28+
test('should support object methods', () => {
29+
expect(canIUse('SelectorQuery')).toBe(true)
30+
expect(canIUse('SelectorQuery.select')).toBe(true)
31+
expect(canIUse('Animation.rotate')).toBe(true)
32+
33+
// 测试 Task 类的方法
34+
expect(canIUse('SocketTask')).toBe(true)
35+
expect(canIUse('SocketTask.send')).toBe(true)
36+
expect(canIUse('SocketTask.onMessage')).toBe(true)
37+
expect(canIUse('RequestTask')).toBe(true)
38+
expect(canIUse('RequestTask.abort')).toBe(true)
39+
})
40+
41+
test('should handle invalid input', () => {
42+
expect(canIUse(null)).toBe(false)
43+
expect(canIUse(undefined)).toBe(false)
44+
expect(canIUse(123)).toBe(false)
45+
})
46+
47+
test('should handle ${} syntax', () => {
48+
expect(canIUse('$' + '{navigateTo}')).toBe(false)
49+
expect(canIUse('$' + '{showToast}')).toBe(false)
50+
})
51+
52+
test('should dynamically detect APIs from platform exports', () => {
53+
// 测试一些从 platform 导出的 API
54+
expect(canIUse('base64ToArrayBuffer')).toBe(true)
55+
expect(canIUse('arrayBufferToBase64')).toBe(true)
56+
57+
// 测试 create* 函数
58+
expect(canIUse('createAnimation')).toBe(true)
59+
expect(canIUse('createSelectorQuery')).toBe(true)
60+
expect(canIUse('createIntersectionObserver')).toBe(true)
61+
})
62+
63+
test('canIUse should be lightweight and fast', () => {
64+
const { canIUse } = require('../../src/platform/api/base/rnCanIUse')
65+
66+
const start = Date.now()
67+
68+
// 执行 1000 次 canIUse 调用
69+
for (let i = 0; i < 1000; i++) {
70+
canIUse('getStorage')
71+
canIUse('request')
72+
canIUse('SelectorQuery.select')
73+
}
74+
75+
const duration = Date.now() - start
76+
77+
// 应该非常快(< 100ms)
78+
expect(duration).toBeLessThan(100)
79+
80+
console.log(`1000 次 canIUse 调用耗时: ${duration}ms`)
81+
})
82+
})

packages/api-proxy/package.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@
4646
"react-native-device-info": "*",
4747
"react-native-get-location": "*",
4848
"react-native-haptic-feedback": "*",
49-
"react-native-safe-area-context": "*"
49+
"react-native-safe-area-context": "*",
50+
"react-native-ble-manager": "*",
51+
"react-native-wifi-reborn": "*"
5052
},
5153
"peerDependenciesMeta": {
5254
"@react-native-async-storage/async-storage": {
@@ -66,6 +68,12 @@
6668
},
6769
"react-native-haptic-feedback": {
6870
"optional": true
71+
},
72+
"react-native-ble-manager": {
73+
"optional": true
74+
},
75+
"react-native-wifi-reborn": {
76+
"optional": true
6977
}
7078
}
7179
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './index.web'
2+
export { canIUse } from './rnCanIUse'

packages/api-proxy/src/platform/api/base/index.web.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import { fromByteArray, toByteArray } from './base64'
22

33
function base64ToArrayBuffer (base64) {
4-
if (__mpx_mode__ === 'web') {
5-
return toByteArray(base64)?.buffer
6-
}
7-
return toByteArray(base64)
4+
return toByteArray(base64)?.buffer // 判断了一下,RN下也是要.buffer才是buffer类型
85
}
96

107
function arrayBufferToBase64 (arrayBuffer) {

0 commit comments

Comments
 (0)