@mpxjs/webpack-plugin 2.9.66 → 2.9.69

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.
Files changed (112) hide show
  1. package/lib/dependencies/RecordGlobalComponentsDependency.js +11 -12
  2. package/lib/dependencies/RecordRuntimeInfoDependency.js +1 -1
  3. package/lib/index.js +29 -8
  4. package/lib/json-compiler/index.js +2 -11
  5. package/lib/loader.js +24 -45
  6. package/lib/native-loader.js +49 -64
  7. package/lib/platform/json/wx/index.js +3 -10
  8. package/lib/platform/style/wx/index.js +15 -10
  9. package/lib/platform/template/wx/component-config/canvas.js +8 -0
  10. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  11. package/lib/react/index.js +4 -3
  12. package/lib/react/processJSON.js +5 -13
  13. package/lib/react/processMainScript.js +7 -3
  14. package/lib/react/processScript.js +3 -4
  15. package/lib/react/processStyles.js +14 -4
  16. package/lib/react/processTemplate.js +2 -2
  17. package/lib/resolver/AddModePlugin.js +20 -7
  18. package/lib/runtime/components/react/context.ts +2 -0
  19. package/lib/runtime/components/react/dist/context.js +1 -0
  20. package/lib/runtime/components/react/dist/getInnerListeners.js +3 -12
  21. package/lib/runtime/components/react/dist/mpx-button.jsx +44 -9
  22. package/lib/runtime/components/react/dist/mpx-canvas/Bus.js +60 -0
  23. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.js +15 -0
  24. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.js +84 -0
  25. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +87 -0
  26. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.js +15 -0
  27. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.js +28 -0
  28. package/lib/runtime/components/react/dist/mpx-canvas/html.js +343 -0
  29. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +214 -0
  30. package/lib/runtime/components/react/dist/mpx-canvas/utils.jsx +89 -0
  31. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +30 -17
  32. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +1 -1
  33. package/lib/runtime/components/react/dist/mpx-form.jsx +33 -24
  34. package/lib/runtime/components/react/dist/mpx-icon.jsx +1 -1
  35. package/lib/runtime/components/react/dist/mpx-image/index.jsx +1 -1
  36. package/lib/runtime/components/react/dist/mpx-input.jsx +44 -38
  37. package/lib/runtime/components/react/dist/mpx-label.jsx +10 -7
  38. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +10 -17
  39. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +378 -294
  40. package/lib/runtime/components/react/dist/mpx-navigator.jsx +1 -1
  41. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +143 -84
  42. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +69 -113
  43. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +30 -17
  44. package/lib/runtime/components/react/dist/mpx-radio.jsx +1 -1
  45. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +1 -1
  46. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +49 -29
  47. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +1 -1
  48. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +1 -1
  49. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +1 -1
  50. package/lib/runtime/components/react/dist/mpx-switch.jsx +8 -1
  51. package/lib/runtime/components/react/dist/mpx-text.jsx +1 -1
  52. package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
  53. package/lib/runtime/components/react/dist/mpx-view.jsx +46 -27
  54. package/lib/runtime/components/react/dist/mpx-web-view.jsx +20 -6
  55. package/lib/runtime/components/react/dist/pickerFaces.js +75 -0
  56. package/lib/runtime/components/react/dist/pickerOverlay.jsx +21 -0
  57. package/lib/runtime/components/react/dist/useAnimationHooks.js +96 -8
  58. package/lib/runtime/components/react/dist/utils.jsx +66 -6
  59. package/lib/runtime/components/react/getInnerListeners.ts +3 -16
  60. package/lib/runtime/components/react/mpx-button.tsx +42 -9
  61. package/lib/runtime/components/react/mpx-canvas/Bus.ts +70 -0
  62. package/lib/runtime/components/react/mpx-canvas/CanvasGradient.ts +18 -0
  63. package/lib/runtime/components/react/mpx-canvas/CanvasRenderingContext2D.ts +87 -0
  64. package/lib/runtime/components/react/mpx-canvas/Image.ts +102 -0
  65. package/lib/runtime/components/react/mpx-canvas/ImageData.ts +23 -0
  66. package/lib/runtime/components/react/mpx-canvas/constructorsRegistry.ts +38 -0
  67. package/lib/runtime/components/react/mpx-canvas/html.ts +343 -0
  68. package/lib/runtime/components/react/mpx-canvas/index.tsx +302 -0
  69. package/lib/runtime/components/react/mpx-canvas/utils.tsx +150 -0
  70. package/lib/runtime/components/react/mpx-checkbox-group.tsx +52 -29
  71. package/lib/runtime/components/react/mpx-checkbox.tsx +1 -1
  72. package/lib/runtime/components/react/mpx-form.tsx +42 -34
  73. package/lib/runtime/components/react/mpx-icon.tsx +1 -1
  74. package/lib/runtime/components/react/mpx-image/index.tsx +2 -3
  75. package/lib/runtime/components/react/mpx-input.tsx +68 -66
  76. package/lib/runtime/components/react/mpx-label.tsx +11 -8
  77. package/lib/runtime/components/react/mpx-movable-area.tsx +11 -19
  78. package/lib/runtime/components/react/mpx-movable-view.tsx +456 -334
  79. package/lib/runtime/components/react/mpx-navigator.tsx +1 -1
  80. package/lib/runtime/components/react/mpx-picker-view-column.tsx +232 -103
  81. package/lib/runtime/components/react/mpx-picker-view.tsx +126 -122
  82. package/lib/runtime/components/react/mpx-radio-group.tsx +55 -29
  83. package/lib/runtime/components/react/mpx-radio.tsx +1 -1
  84. package/lib/runtime/components/react/mpx-root-portal.tsx +1 -1
  85. package/lib/runtime/components/react/mpx-scroll-view.tsx +81 -36
  86. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +2 -2
  87. package/lib/runtime/components/react/mpx-swiper/index.tsx +2 -1
  88. package/lib/runtime/components/react/mpx-swiper-item.tsx +1 -1
  89. package/lib/runtime/components/react/mpx-switch.tsx +10 -2
  90. package/lib/runtime/components/react/mpx-text.tsx +1 -1
  91. package/lib/runtime/components/react/mpx-textarea.tsx +1 -1
  92. package/lib/runtime/components/react/mpx-view.tsx +58 -28
  93. package/lib/runtime/components/react/mpx-web-view.tsx +23 -6
  94. package/lib/runtime/components/react/pickerFaces.ts +104 -0
  95. package/lib/runtime/components/react/pickerOverlay.tsx +32 -0
  96. package/lib/runtime/components/react/types/common.ts +2 -0
  97. package/lib/runtime/components/react/types/global.d.ts +2 -0
  98. package/lib/runtime/components/react/useAnimationHooks.ts +97 -13
  99. package/lib/runtime/components/react/useNodesRef.ts +1 -0
  100. package/lib/runtime/components/react/utils.tsx +94 -8
  101. package/lib/runtime/optionProcessorReact.js +0 -15
  102. package/lib/runtime/swanHelper.wxs +1 -1
  103. package/lib/style-compiler/index.js +1 -1
  104. package/lib/style-compiler/plugins/scope-id.js +1 -0
  105. package/lib/template-compiler/compiler.js +47 -16
  106. package/lib/template-compiler/gen-node-react.js +2 -2
  107. package/lib/template-compiler/index.js +4 -4
  108. package/lib/utils/pre-process-json.js +113 -0
  109. package/lib/web/index.js +5 -4
  110. package/lib/web/processJSON.js +5 -13
  111. package/lib/web/processTemplate.js +2 -2
  112. package/package.json +5 -4
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Borrowed from open-source code: https://github.com/quidone/react-native-wheel-picker
3
+ * Special thanks to the authors for their contribution to the open-source community.
4
+ */
5
+
6
+ export type Faces = {
7
+ index: number
8
+ deg: number
9
+ offsetY: number
10
+ opacity: number
11
+ screenHeight: number
12
+ }
13
+
14
+ export const degToRad = (deg: number) => (Math.PI * deg) / 180
15
+
16
+ // Calculates the height of the element after rotating it relative to the user's screen.
17
+ const calcHeight = (degree: number, itemHeight: number) =>
18
+ itemHeight * Math.cos(degToRad(degree))
19
+
20
+ export const calcPickerHeight = (faces: Faces[], itemHeight: number) => {
21
+ if (faces.length === 7) {
22
+ return itemHeight * 5
23
+ }
24
+ return faces.reduce((r, v) => r + calcHeight(Math.abs(v.deg), itemHeight), 0)
25
+ }
26
+
27
+ export const createFaces = (
28
+ itemHeight: number,
29
+ visibleCount: number
30
+ ): Faces[] => {
31
+ // e.g [30, 60, 90]
32
+ const getDegreesRelativeCenter = () => {
33
+ const maxStep = Math.trunc((visibleCount + 2) / 2) // + 2 because there are 2 more faces at 90 degrees
34
+ const stepDegree = 90 / maxStep
35
+
36
+ const result = []
37
+ for (let i = 1; i <= maxStep; i++) {
38
+ result.push(i * stepDegree)
39
+ }
40
+ return result
41
+ }
42
+
43
+ const getScreenHeightsAndOffsets = <T extends readonly number[]>(
44
+ degrees: T
45
+ ): [T, T] => {
46
+ const screenHeights = degrees.map((deg) =>
47
+ calcHeight(deg, itemHeight)
48
+ ) as unknown as T
49
+ const freeSpaces = screenHeights.map(
50
+ (screenHeight) => itemHeight - screenHeight
51
+ )
52
+ const offsets = freeSpaces.map((freeSpace, index) => {
53
+ let offset = freeSpace / 2
54
+ for (let i = 0; i < index; i++) {
55
+ offset += freeSpaces[i]
56
+ }
57
+ return offset
58
+ }) as unknown as T
59
+ return [screenHeights, offsets]
60
+ }
61
+
62
+ const getOpacity = (index: number) => {
63
+ const map: Record<number, number> = {
64
+ 0: 0,
65
+ 1: 0.2,
66
+ 2: 0.35,
67
+ 3: 0.45,
68
+ 4: 0.5
69
+ }
70
+ return map[index] ?? Math.min(1, map[4] + index * 0.5)
71
+ }
72
+
73
+ const degrees = getDegreesRelativeCenter()
74
+ const [screenHeight, offsets] = getScreenHeightsAndOffsets(degrees)
75
+
76
+ return [
77
+ // top items
78
+ ...degrees
79
+ .map<Faces>((degree, index) => {
80
+ return {
81
+ index: -1 * (index + 1),
82
+ deg: degree,
83
+ opacity: getOpacity(degrees.length - 1 - index),
84
+ offsetY: -1 * offsets[index],
85
+ screenHeight: screenHeight[index]
86
+ }
87
+ })
88
+ .reverse(),
89
+
90
+ // center item
91
+ { index: 0, deg: 0, opacity: 1, offsetY: 0, screenHeight: itemHeight },
92
+
93
+ // bottom items
94
+ ...degrees.map<Faces>((degree, index) => {
95
+ return {
96
+ index: index + 1,
97
+ deg: -1 * degree,
98
+ opacity: getOpacity(degrees.length - 1 - index),
99
+ offsetY: offsets[index],
100
+ screenHeight: screenHeight[index]
101
+ }
102
+ })
103
+ ]
104
+ }
@@ -0,0 +1,32 @@
1
+ import React from 'react'
2
+ import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'
3
+
4
+ type OverlayProps = {
5
+ itemHeight: number
6
+ overlayItemStyle?: StyleProp<ViewStyle>
7
+ overlayContainerStyle?: StyleProp<ViewStyle>
8
+ }
9
+
10
+ const Overlay = ({ itemHeight, overlayItemStyle, overlayContainerStyle }: OverlayProps) => {
11
+ return (
12
+ <View style={[styles.overlayContainer, overlayContainerStyle]} pointerEvents={'none'}>
13
+ <View style={[styles.selection, { height: itemHeight }, overlayItemStyle]} />
14
+ </View>
15
+ )
16
+ }
17
+
18
+ const styles = StyleSheet.create({
19
+ overlayContainer: {
20
+ ...StyleSheet.absoluteFillObject,
21
+ justifyContent: 'center',
22
+ alignItems: 'center'
23
+ },
24
+ selection: {
25
+ borderTopWidth: 1,
26
+ borderBottomWidth: 1,
27
+ borderColor: 'rgba(0, 0, 0, 0.05)',
28
+ alignSelf: 'stretch'
29
+ }
30
+ })
31
+
32
+ export default React.memo(Overlay)
@@ -16,3 +16,5 @@ export type ExtendedViewStyle = ViewStyle & {
16
16
  export type ExtendedFunctionComponent = FunctionComponent & {
17
17
  isCustomText?: boolean
18
18
  }
19
+
20
+ export type AnyFunc = (...args: ReadonlyArray<any>) => any
@@ -16,6 +16,7 @@ declare module 'react-native-svg/css' {
16
16
 
17
17
  declare module '@mpxjs/utils' {
18
18
  export function isEmptyObject (obj: Object): boolean
19
+ export function isFunction (fn: unknown): boolean
19
20
  export function hasOwn (obj: Object, key: string): boolean
20
21
  export function noop (...arg: any): void
21
22
  export function diffAndCloneA<A, B> (a: A, b?: B): {
@@ -26,6 +27,7 @@ declare module '@mpxjs/utils' {
26
27
  export function isObject (value): value is Object
27
28
  export function error (msg: string, location?: string, e?: any): void
28
29
  export function warn (msg: string, location?: string, e?: any): void
30
+ export function collectDataset (props: Record<string, any>, needParse?: boolean): Record<string, any>
29
31
  export function getFocusedNavigation (): {
30
32
  insets: {
31
33
  top: number
@@ -16,9 +16,6 @@ import {
16
16
  import { ExtendedViewStyle } from './types/common'
17
17
  import type { _ViewProps } from './mpx-view'
18
18
 
19
- // type TransformKey = 'translateX' | 'translateY' | 'rotate' | 'rotateX' | 'rotateY' | 'rotateZ' | 'scaleX' | 'scaleY' | 'skewX' | 'skewY'
20
- // type NormalKey = 'opacity' | 'backgroundColor' | 'width' | 'height' | 'top' | 'right' | 'bottom' | 'left' | 'transformOrigin'
21
- // type RuleKey = TransformKey | NormalKey
22
19
  type AnimatedOption = {
23
20
  duration: number
24
21
  delay: number
@@ -84,20 +81,79 @@ const InitialValue: ExtendedViewStyle = Object.assign({
84
81
  transformOrigin: ['50%', '50%', 0]
85
82
  }, TransformInitial)
86
83
  const TransformOrigin = 'transformOrigin'
87
- // deg 角度
88
- // const isDeg = (key: RuleKey) => ['rotateX', 'rotateY', 'rotateZ', 'rotate', 'skewX', 'skewY'].includes(key)
89
- // 背景色
90
- // const isBg = (key: RuleKey) => key === 'backgroundColor'
91
84
  // transform
92
85
  const isTransform = (key: string) => Object.keys(TransformInitial).includes(key)
86
+ // parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
87
+ const parseTransform = (transformStr: string) => {
88
+ const values = transformStr.trim().split(/\s+/)
89
+ const transform: {[propName: string]: string|number|number[]}[] = []
90
+ values.forEach(item => {
91
+ const match = item.match(/([/\w]+)\(([^)]+)\)/)
92
+ if (match && match.length >= 3) {
93
+ let key = match[1]
94
+ const val = match[2]
95
+ switch (key) {
96
+ case 'translateX':
97
+ case 'translateY':
98
+ case 'scaleX':
99
+ case 'scaleY':
100
+ case 'rotateX':
101
+ case 'rotateY':
102
+ case 'rotateZ':
103
+ case 'rotate':
104
+ case 'skewX':
105
+ case 'skewY':
106
+ case 'perspective':
107
+ // 单个值处理
108
+ transform.push({ [key]: global.__formatValue(val) })
109
+ break
110
+ case 'matrix':
111
+ case 'matrix3d':
112
+ transform.push({ [key]: val.split(',').map(val => +val) })
113
+ break
114
+ case 'translate':
115
+ case 'scale':
116
+ case 'skew':
117
+ case 'rotate3d': // x y z angle
118
+ case 'translate3d': // x y 支持 z不支持
119
+ case 'scale3d': // x y 支持 z不支持
120
+ {
121
+ // 2 个以上的值处理
122
+ key = key.replace('3d', '')
123
+ const vals = val.split(',', key === 'rotate' ? 4 : 3)
124
+ // scale(.5) === scaleX(.5) scaleY(.5) 这里处理一下
125
+ if (vals.length === 1 && key === 'scale') {
126
+ vals.push(vals[0])
127
+ }
128
+ const xyz = ['X', 'Y', 'Z']
129
+ transform.push(...vals.map((v, index) => {
130
+ return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) }
131
+ }))
132
+ break
133
+ }
134
+ }
135
+ }
136
+ })
137
+ return transform
138
+ }
139
+ // format style
140
+ const formatStyle = (style: ExtendedViewStyle): ExtendedViewStyle => {
141
+ if (!style.transform || Array.isArray(style.transform)) return style
142
+ return Object.assign({}, style, {
143
+ transform: parseTransform(style.transform)
144
+ })
145
+ }
93
146
 
94
147
  export default function useAnimationHooks<T, P> (props: _ViewProps) {
95
- const { style: originalStyle = {}, animation } = props
148
+ const { style = {}, animation } = props
149
+ const originalStyle = formatStyle(style)
96
150
  // id 标识
97
151
  const id = animation?.id || -1
98
152
  // 有动画样式的 style key
99
153
  const animatedStyleKeys = useSharedValue([] as (string|string[])[])
100
- const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: Boolean})
154
+ // 记录动画key的style样式值 没有的话设置为false
155
+ const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: boolean})
156
+ // const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: boolean|number|string})
101
157
  // ** 全量 style prop sharedValue
102
158
  // 不能做增量的原因:
103
159
  // 1 尝试用 useRef,但 useAnimatedStyle 访问后的 ref 不能在增加新的值,被冻结
@@ -119,6 +175,16 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
119
175
  // 驱动动画
120
176
  createAnimation(keys)
121
177
  }, [id])
178
+ // 同步style更新
179
+ // useEffect(() => {
180
+ // Object.keys(animatedKeys.current).forEach(key => {
181
+ // const originVal = getOriginalStyleVal(key, isTransform(key))
182
+ // if (originVal && animatedKeys.current[key] !== originVal) {
183
+ // animatedKeys.current[key] = originVal
184
+ // shareValMap[key].value = originVal
185
+ // }
186
+ // })
187
+ // }, [style])
122
188
  // ** 清空动画
123
189
  useEffect(() => {
124
190
  return () => {
@@ -152,9 +218,9 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
152
218
  }
153
219
  // 添加每个key的多次step动画
154
220
  animatedKeys.forEach(key => {
155
- let toVal = (rules.get(key) || transform.get(key)) as number|string
221
+ let toVal = (rules.get(key) || transform.get(key))
156
222
  // key不存在,第一轮取shareValMap[key]value,非第一轮取上一轮的
157
- if (!toVal) {
223
+ if (toVal === undefined) {
158
224
  toVal = index > 0 ? lastValueMap[key] : shareValMap[key].value
159
225
  }
160
226
  const animation = getAnimation({ key, value: toVal }, { delay, duration, easing }, needSetCallback ? setTransformOrigin : undefined)
@@ -181,9 +247,8 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
181
247
  : withTiming(value, { duration, easing })
182
248
  return delay ? withDelay(delay, animation) : animation
183
249
  }
184
- // 获取初始值(prop style or 默认值)
185
250
  function getInitialVal (key: keyof ExtendedViewStyle, isTransform = false) {
186
- if (isTransform && originalStyle.transform?.length) {
251
+ if (isTransform && Array.isArray(originalStyle.transform)) {
187
252
  let initialVal = InitialValue[key]
188
253
  // 仅支持 { transform: [{rotateX: '45deg'}, {rotateZ: '0.785398rad'}] } 格式的初始样式
189
254
  originalStyle.transform.forEach(item => {
@@ -193,12 +258,31 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
193
258
  }
194
259
  return originalStyle[key] === undefined ? InitialValue[key] : originalStyle[key]
195
260
  }
261
+ // 从 prop style 中获取样式初始值 没有为undefined
262
+ // function getOriginalStyleVal (key: keyof ExtendedViewStyle, isTransform = false) {
263
+ // if (isTransform && Array.isArray(originalStyle.transform)) {
264
+ // let initialVal = undefined // InitialValue[key]
265
+ // // 仅支持 { transform: [{rotateX: '45deg'}, {rotateZ: '0.785398rad'}] } 格式的初始样式
266
+ // originalStyle.transform.forEach(item => {
267
+ // if (item[key] !== undefined) initialVal = item[key]
268
+ // })
269
+ // return initialVal
270
+ // }
271
+ // return originalStyle[key] // === undefined ? InitialValue[key] : originalStyle[key]
272
+ // }
273
+ // 获取动画shareVal初始值(prop style or 默认值)
274
+ // function getInitialVal (key: keyof ExtendedViewStyle, isTransform = false) {
275
+ // const originalVal = getOriginalStyleVal(key, isTransform)
276
+ // return originalVal === undefined ? InitialValue[key] : originalStyle[key]
277
+ // }
196
278
  // 循环 animation actions 获取所有有动画的 style prop name
197
279
  function getAnimatedStyleKeys () {
198
280
  return (animation?.actions || []).reduce((keyMap, action) => {
199
281
  const { rules, transform } = action
200
282
  const ruleArr = [...rules.keys(), ...transform.keys()]
201
283
  ruleArr.forEach(key => {
284
+ // const originalVal = getOriginalStyleVal(key, isTransform(key))
285
+ // if (!keyMap[key]) keyMap[key] = originalVal === undefined ? false : originalVal
202
286
  if (!keyMap[key]) keyMap[key] = true
203
287
  })
204
288
  return keyMap
@@ -1,4 +1,5 @@
1
1
  import { useRef, useImperativeHandle, RefObject, ForwardedRef } from 'react'
2
+ import { useAnimatedRef } from 'react-native-reanimated'
2
3
 
3
4
  type Obj = Record<string, any>
4
5
 
@@ -1,10 +1,11 @@
1
- import { useEffect, useRef, ReactNode, ReactElement, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement } from 'react'
2
- import { LayoutChangeEvent, TextStyle } from 'react-native'
3
- import { isObject, hasOwn, diffAndCloneA, error, warn, getFocusedNavigation } from '@mpxjs/utils'
1
+ import { useEffect, useCallback, useMemo, useRef, ReactNode, ReactElement, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement } from 'react'
2
+ import { LayoutChangeEvent, TextStyle, ImageProps, Image } from 'react-native'
3
+ import { isObject, isFunction, hasOwn, diffAndCloneA, error, warn, getFocusedNavigation } from '@mpxjs/utils'
4
4
  import { VarContext } from './context'
5
5
  import { ExpressionParser, parseFunc, ReplaceSource } from './parser'
6
6
  import { initialWindowMetrics } from 'react-native-safe-area-context'
7
- import type { ExtendedFunctionComponent } from './types/common'
7
+ import FastImage, { FastImageProps } from '@d11/react-native-fast-image'
8
+ import type { AnyFunc, ExtendedFunctionComponent } from './types/common'
8
9
 
9
10
  export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/
10
11
  export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/
@@ -12,7 +13,7 @@ export const URL_REGEX = /^\s*url\(["']?(.*?)["']?\)\s*$/
12
13
  export const BACKGROUND_REGEX = /^background(Image|Size|Repeat|Position)$/
13
14
  export const TEXT_PROPS_REGEX = /ellipsizeMode|numberOfLines/
14
15
  export const DEFAULT_FONT_SIZE = 16
15
- export const DEFAULT_UNLAY_STYLE = {
16
+ export const HIDDEN_STYLE = {
16
17
  opacity: 0
17
18
  }
18
19
 
@@ -78,7 +79,7 @@ export const parseInlineStyle = (inlineStyle = ''): Record<string, string> => {
78
79
  const [k, v, ...rest] = style.split(':')
79
80
  if (rest.length || !v || !k) return styleObj
80
81
  const key = k.trim().replace(/-./g, c => c.substring(1).toUpperCase())
81
- return Object.assign(styleObj, { [key]: v.trim() })
82
+ return Object.assign(styleObj, { [key]: global.__formatValue(v.trim()) })
82
83
  }, {})
83
84
  }
84
85
 
@@ -99,7 +100,7 @@ export function isText (ele: ReactNode): ele is ReactElement {
99
100
  if (isValidElement(ele)) {
100
101
  const displayName = (ele.type as ExtendedFunctionComponent)?.displayName
101
102
  const isCustomText = (ele.type as ExtendedFunctionComponent)?.isCustomText
102
- return displayName === 'mpx-text' || displayName === 'Text' || !!isCustomText
103
+ return displayName === 'MpxText' || displayName === 'Text' || !!isCustomText
103
104
  }
104
105
  return false
105
106
  }
@@ -474,7 +475,7 @@ interface LayoutConfig {
474
475
  export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout, nodeRef }: LayoutConfig) => {
475
476
  const layoutRef = useRef({})
476
477
  const hasLayoutRef = useRef(false)
477
- const layoutStyle: Record<string, any> = !hasLayoutRef.current && hasSelfPercent ? DEFAULT_UNLAY_STYLE : {}
478
+ const layoutStyle: Record<string, any> = !hasLayoutRef.current && hasSelfPercent ? HIDDEN_STYLE : {}
478
479
  const layoutProps: Record<string, any> = {}
479
480
  const enableOffset = props['enable-offset']
480
481
  if (hasSelfPercent || onLayout || enableOffset) {
@@ -524,3 +525,88 @@ export function wrapChildren (props: Record<string, any> = {}, { hasVarDec, varC
524
525
  }
525
526
  return children
526
527
  }
528
+
529
+ export const debounce = <T extends AnyFunc> (
530
+ func: T,
531
+ delay: number
532
+ ): ((...args: Parameters<T>) => void) & { clear: () => void } => {
533
+ let timer: any
534
+ const wrapper = (...args: ReadonlyArray<any>) => {
535
+ clearTimeout(timer)
536
+ timer = setTimeout(() => {
537
+ func(...args)
538
+ }, delay)
539
+ }
540
+ wrapper.clear = () => {
541
+ clearTimeout(timer)
542
+ }
543
+ return wrapper
544
+ }
545
+
546
+ export const useDebounceCallback = <T extends AnyFunc> (
547
+ func: T,
548
+ delay: number
549
+ ): ((...args: Parameters<T>) => void) & { clear: () => void } => {
550
+ const debounced = useMemo(() => debounce(func, delay), [func])
551
+ return debounced
552
+ }
553
+
554
+ export const useStableCallback = <T extends AnyFunc | null | undefined> (
555
+ callback: T
556
+ ): T extends AnyFunc ? T : () => void => {
557
+ const ref = useRef<T>(callback)
558
+ ref.current = callback
559
+ return useCallback<any>(
560
+ (...args: any[]) => ref.current?.(...args),
561
+ []
562
+ )
563
+ }
564
+
565
+ export const usePrevious = <T, > (value: T): T | undefined => {
566
+ const ref = useRef<T | undefined>(undefined)
567
+ const prev = ref.current
568
+ ref.current = value
569
+ return prev
570
+ }
571
+
572
+ export interface GestureHandler {
573
+ nodeRefs?: Array<{ getNodeInstance: () => { nodeRef: unknown } }>
574
+ current?: unknown
575
+ }
576
+
577
+ export function flatGesture (gestures: Array<GestureHandler> = []) {
578
+ return (gestures && gestures.flatMap((gesture: GestureHandler) => {
579
+ if (gesture && gesture.nodeRefs) {
580
+ return gesture.nodeRefs
581
+ .map((item: { getNodeInstance: () => any }) => item.getNodeInstance()?.instance?.gestureRef || {})
582
+ }
583
+ return gesture?.current ? [gesture] : []
584
+ })) || []
585
+ }
586
+
587
+ export function extendObject (...args: Record<string, any>[]) {
588
+ return Object.assign({}, ...args)
589
+ }
590
+
591
+ export function getCurrentPage (pageId: number | null) {
592
+ if (!global.getCurrentPages) return
593
+ const pages = global.getCurrentPages()
594
+ return pages.find((page: any) => isFunction(page.getPageId) && page.getPageId() === pageId)
595
+ }
596
+
597
+ export function renderImage (
598
+ imageProps: ImageProps | FastImageProps,
599
+ enableFastImage = false
600
+ ) {
601
+ const Component: React.ComponentType<ImageProps | FastImageProps> = enableFastImage ? FastImage : Image
602
+ return <Component {...imageProps} />
603
+ }
604
+
605
+ export function pickStyle (styleObj: Record<string, any> = {}, pickedKeys: Array<string>, callback?: (key: string, val: number | string) => number | string) {
606
+ return pickedKeys.reduce<Record<string, any>>((acc, key) => {
607
+ if (key in styleObj) {
608
+ acc[key] = callback ? callback(key, styleObj[key]) : styleObj[key]
609
+ }
610
+ return acc
611
+ }, {})
612
+ }
@@ -4,18 +4,3 @@ export function getComponent (component, extendOptions) {
4
4
  if (extendOptions) Object.assign(component, extendOptions)
5
5
  return component
6
6
  }
7
-
8
- export function createApp ({
9
- App,
10
- pagesMap,
11
- firstPage,
12
- createElement,
13
- NavigationContainer,
14
- createNativeStackNavigator
15
- }) {
16
- const Stack = createNativeStackNavigator()
17
- const pages = []
18
- return () => {
19
- return createElement(NavigationContainer, null, createElement(Stack.Navigator, null, ...pages))
20
- }
21
- }
@@ -23,7 +23,7 @@ module.exports = {
23
23
  }
24
24
  return list
25
25
  }
26
- if ( typeof value === 'string') {
26
+ if (typeof value === 'string') {
27
27
  return value.split('')
28
28
  }
29
29
  return value
@@ -19,7 +19,7 @@ module.exports = function (css, map) {
19
19
  const { resourcePath, queryObj } = parseRequest(this.resource)
20
20
  const mpx = this.getMpx()
21
21
  const mpxStyleOptions = (queryObj.mpxStyleOptions && JSON.parse(queryObj.mpxStyleOptions)) || {}
22
- const id = queryObj.moduleId || mpxStyleOptions.mid || '_' + mpx.pathHash(resourcePath)
22
+ const id = queryObj.moduleId || mpxStyleOptions.mid || mpx.getModuleId(resourcePath)
23
23
  const appInfo = mpx.appInfo
24
24
  const defs = mpx.defs
25
25
  const mode = mpx.mode
@@ -20,6 +20,7 @@ module.exports = ({ id }) => {
20
20
  }
21
21
  return
22
22
  }
23
+ if (node.selector === ':host') return
23
24
  node.selector = selectorParser(selectors => {
24
25
  selectors.each(selector => {
25
26
  let node = null