@mpxjs/webpack-plugin 2.9.65 → 2.9.67

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 (80) hide show
  1. package/lib/dependencies/RecordGlobalComponentsDependency.js +11 -12
  2. package/lib/dependencies/RecordRuntimeInfoDependency.js +1 -1
  3. package/lib/index.js +28 -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 +32 -56
  9. package/lib/react/index.js +4 -3
  10. package/lib/react/processJSON.js +5 -13
  11. package/lib/react/processMainScript.js +7 -3
  12. package/lib/react/processScript.js +3 -4
  13. package/lib/react/processTemplate.js +6 -4
  14. package/lib/resolver/AddModePlugin.js +17 -4
  15. package/lib/runtime/components/react/context.ts +8 -0
  16. package/lib/runtime/components/react/dist/context.js +1 -0
  17. package/lib/runtime/components/react/dist/mpx-button.jsx +1 -1
  18. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +30 -17
  19. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +1 -1
  20. package/lib/runtime/components/react/dist/mpx-form.jsx +33 -24
  21. package/lib/runtime/components/react/dist/mpx-icon.jsx +1 -1
  22. package/lib/runtime/components/react/dist/mpx-image/index.jsx +1 -1
  23. package/lib/runtime/components/react/dist/mpx-input.jsx +44 -38
  24. package/lib/runtime/components/react/dist/mpx-label.jsx +10 -7
  25. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +10 -17
  26. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +378 -294
  27. package/lib/runtime/components/react/dist/mpx-navigator.jsx +1 -1
  28. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +30 -17
  29. package/lib/runtime/components/react/dist/mpx-radio.jsx +1 -1
  30. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +1 -1
  31. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +58 -30
  32. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +77 -77
  33. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +1 -1
  34. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +1 -1
  35. package/lib/runtime/components/react/dist/mpx-switch.jsx +8 -1
  36. package/lib/runtime/components/react/dist/mpx-text.jsx +1 -1
  37. package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
  38. package/lib/runtime/components/react/dist/mpx-view.jsx +31 -12
  39. package/lib/runtime/components/react/dist/mpx-web-view.jsx +2 -2
  40. package/lib/runtime/components/react/dist/useAnimationHooks.js +303 -0
  41. package/lib/runtime/components/react/dist/utils.jsx +13 -3
  42. package/lib/runtime/components/react/getInnerListeners.ts +1 -0
  43. package/lib/runtime/components/react/mpx-button.tsx +1 -1
  44. package/lib/runtime/components/react/mpx-checkbox-group.tsx +52 -29
  45. package/lib/runtime/components/react/mpx-checkbox.tsx +1 -1
  46. package/lib/runtime/components/react/mpx-form.tsx +42 -34
  47. package/lib/runtime/components/react/mpx-icon.tsx +1 -1
  48. package/lib/runtime/components/react/mpx-image/index.tsx +2 -3
  49. package/lib/runtime/components/react/mpx-input.tsx +68 -66
  50. package/lib/runtime/components/react/mpx-label.tsx +11 -8
  51. package/lib/runtime/components/react/mpx-movable-area.tsx +11 -19
  52. package/lib/runtime/components/react/mpx-movable-view.tsx +456 -334
  53. package/lib/runtime/components/react/mpx-navigator.tsx +1 -1
  54. package/lib/runtime/components/react/mpx-radio-group.tsx +55 -29
  55. package/lib/runtime/components/react/mpx-radio.tsx +1 -1
  56. package/lib/runtime/components/react/mpx-root-portal.tsx +1 -1
  57. package/lib/runtime/components/react/mpx-scroll-view.tsx +92 -37
  58. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +77 -76
  59. package/lib/runtime/components/react/mpx-swiper/index.tsx +2 -1
  60. package/lib/runtime/components/react/mpx-swiper-item.tsx +1 -1
  61. package/lib/runtime/components/react/mpx-switch.tsx +10 -2
  62. package/lib/runtime/components/react/mpx-text.tsx +1 -1
  63. package/lib/runtime/components/react/mpx-textarea.tsx +1 -1
  64. package/lib/runtime/components/react/mpx-view.tsx +40 -20
  65. package/lib/runtime/components/react/mpx-web-view.tsx +2 -2
  66. package/lib/runtime/components/react/types/common.ts +8 -2
  67. package/lib/runtime/components/react/useAnimationHooks.ts +332 -0
  68. package/lib/runtime/components/react/useNodesRef.ts +1 -0
  69. package/lib/runtime/components/react/utils.tsx +23 -6
  70. package/lib/runtime/optionProcessorReact.js +0 -15
  71. package/lib/runtime/swanHelper.wxs +1 -1
  72. package/lib/style-compiler/index.js +1 -1
  73. package/lib/style-compiler/plugins/scope-id.js +1 -0
  74. package/lib/template-compiler/compiler.js +68 -33
  75. package/lib/template-compiler/index.js +4 -4
  76. package/lib/utils/pre-process-json.js +113 -0
  77. package/lib/web/index.js +5 -4
  78. package/lib/web/processJSON.js +5 -13
  79. package/lib/web/processTemplate.js +2 -2
  80. package/package.json +5 -4
@@ -0,0 +1,332 @@
1
+ import { useEffect, useMemo, useRef } from 'react'
2
+ import { TransformsStyle } from 'react-native'
3
+ import {
4
+ Easing,
5
+ useSharedValue,
6
+ withTiming,
7
+ useAnimatedStyle,
8
+ withSequence,
9
+ withDelay,
10
+ makeMutable,
11
+ cancelAnimation,
12
+ SharedValue,
13
+ WithTimingConfig,
14
+ AnimationCallback
15
+ } from 'react-native-reanimated'
16
+ import { ExtendedViewStyle } from './types/common'
17
+ import type { _ViewProps } from './mpx-view'
18
+
19
+ type AnimatedOption = {
20
+ duration: number
21
+ delay: number
22
+ useNativeDriver: boolean
23
+ timingFunction: 'linear' | 'ease' | 'ease-in' | 'ease-in-out'| 'ease-out'
24
+ transformOrigin: string
25
+ }
26
+ type ExtendWithTimingConfig = WithTimingConfig & {
27
+ delay: number
28
+ }
29
+ export type AnimationStepItem = {
30
+ animatedOption: AnimatedOption
31
+ rules: Map<string, number | string>
32
+ transform: Map<string, number>
33
+ }
34
+ export type AnimationProp = {
35
+ id: number,
36
+ actions: AnimationStepItem[]
37
+ }
38
+
39
+ // 微信 timingFunction 和 RN Easing 对应关系
40
+ const EasingKey = {
41
+ linear: Easing.linear,
42
+ ease: Easing.ease,
43
+ 'ease-in': Easing.in(Easing.ease),
44
+ 'ease-in-out': Easing.inOut(Easing.ease),
45
+ 'ease-out': Easing.out(Easing.ease)
46
+ // 'step-start': '',
47
+ // 'step-end': ''
48
+ }
49
+ const TransformInitial: ExtendedViewStyle = {
50
+ // matrix: 0,
51
+ // matrix3d: 0,
52
+ rotate: '0deg',
53
+ rotateX: '0deg',
54
+ rotateY: '0deg',
55
+ rotateZ: '0deg',
56
+ // rotate3d:[0,0,0]
57
+ scale: 1,
58
+ // scale3d: [1, 1, 1],
59
+ scaleX: 1,
60
+ scaleY: 1,
61
+ // scaleZ: 1,
62
+ skew: 0,
63
+ skewX: '0deg',
64
+ skewY: '0deg',
65
+ translate: 0,
66
+ // translate3d: 0,
67
+ translateX: 0,
68
+ translateY: 0
69
+ // translateZ: 0,
70
+ }
71
+ // 动画默认初始值
72
+ const InitialValue: ExtendedViewStyle = Object.assign({
73
+ opacity: 1,
74
+ backgroundColor: 'transparent',
75
+ width: 0,
76
+ height: 0,
77
+ top: 0,
78
+ right: 0,
79
+ bottom: 0,
80
+ left: 0,
81
+ transformOrigin: ['50%', '50%', 0]
82
+ }, TransformInitial)
83
+ const TransformOrigin = 'transformOrigin'
84
+ // transform
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
+ }
146
+
147
+ export default function useAnimationHooks<T, P> (props: _ViewProps) {
148
+ const { style = {}, animation } = props
149
+ const originalStyle = formatStyle(style)
150
+ // id 标识
151
+ const id = animation?.id || -1
152
+ // 有动画样式的 style key
153
+ const animatedStyleKeys = useSharedValue([] as (string|string[])[])
154
+ // 记录动画key的style样式值 没有的话设置为false
155
+ const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: boolean})
156
+ // const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: boolean|number|string})
157
+ // ** 全量 style prop sharedValue
158
+ // 不能做增量的原因:
159
+ // 1 尝试用 useRef,但 useAnimatedStyle 访问后的 ref 不能在增加新的值,被冻结
160
+ // 2 尝试用 useSharedValue,因为实际触发的 style prop 需要是 sharedValue 才能驱动动画,若外层 shareValMap 也是 sharedValue,动画无法驱动。
161
+ const shareValMap = useMemo(() => {
162
+ return Object.keys(InitialValue).reduce((valMap, key) => {
163
+ const defaultVal = getInitialVal(key, isTransform(key))
164
+ valMap[key] = makeMutable(defaultVal)
165
+ return valMap
166
+ }, {} as { [propName: keyof ExtendedViewStyle]: SharedValue<string|number> })
167
+ }, [])
168
+ // ** 获取动画样式prop & 驱动动画
169
+ useEffect(() => {
170
+ if (id === -1) return
171
+ // 更新动画样式 key map
172
+ animatedKeys.current = getAnimatedStyleKeys()
173
+ const keys = Object.keys(animatedKeys.current)
174
+ animatedStyleKeys.value = formatAnimatedKeys([TransformOrigin, ...keys])
175
+ // 驱动动画
176
+ createAnimation(keys)
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])
188
+ // ** 清空动画
189
+ useEffect(() => {
190
+ return () => {
191
+ Object.values(shareValMap).forEach((value) => {
192
+ cancelAnimation(value)
193
+ })
194
+ }
195
+ }, [])
196
+ // 根据 animation action 创建&驱动动画 key => wi
197
+ function createAnimation (animatedKeys: string[] = []) {
198
+ const actions = animation?.actions || []
199
+ const sequence = {} as { [propName: keyof ExtendedViewStyle]: (string|number)[] }
200
+ const lastValueMap = {} as { [propName: keyof ExtendedViewStyle]: string|number }
201
+ actions.forEach(({ animatedOption, rules, transform }, index) => {
202
+ const { delay, duration, timingFunction, transformOrigin } = animatedOption
203
+ const easing = EasingKey[timingFunction] || Easing.inOut(Easing.quad)
204
+ let needSetCallback = true
205
+ const setTransformOrigin: AnimationCallback = (finished: boolean) => {
206
+ 'worklet'
207
+ // 动画结束后设置下一次transformOrigin
208
+ if (finished) {
209
+ if (index < actions.length - 1) {
210
+ const transformOrigin = actions[index + 1].animatedOption?.transformOrigin
211
+ transformOrigin && (shareValMap[TransformOrigin].value = transformOrigin)
212
+ }
213
+ }
214
+ }
215
+ if (index === 0) {
216
+ // 设置当次中心
217
+ shareValMap[TransformOrigin].value = transformOrigin
218
+ }
219
+ // 添加每个key的多次step动画
220
+ animatedKeys.forEach(key => {
221
+ let toVal = (rules.get(key) || transform.get(key))
222
+ // key不存在,第一轮取shareValMap[key]value,非第一轮取上一轮的
223
+ if (toVal === undefined) {
224
+ toVal = index > 0 ? lastValueMap[key] : shareValMap[key].value
225
+ }
226
+ const animation = getAnimation({ key, value: toVal }, { delay, duration, easing }, needSetCallback ? setTransformOrigin : undefined)
227
+ needSetCallback = false
228
+ if (!sequence[key]) {
229
+ sequence[key] = [animation]
230
+ } else {
231
+ sequence[key].push(animation)
232
+ }
233
+ // 更新一下 lastValueMap
234
+ lastValueMap[key] = toVal
235
+ })
236
+ // 赋值驱动动画
237
+ animatedKeys.forEach((key) => {
238
+ const animations = sequence[key]
239
+ shareValMap[key].value = withSequence(...animations)
240
+ })
241
+ })
242
+ }
243
+ // 创建单个animation
244
+ function getAnimation ({ key, value }: { key: string, value: string|number }, { delay, duration, easing }: ExtendWithTimingConfig, callback?: AnimationCallback) {
245
+ const animation = typeof callback === 'function'
246
+ ? withTiming(value, { duration, easing }, callback)
247
+ : withTiming(value, { duration, easing })
248
+ return delay ? withDelay(delay, animation) : animation
249
+ }
250
+ function getInitialVal (key: keyof ExtendedViewStyle, isTransform = false) {
251
+ if (isTransform && Array.isArray(originalStyle.transform)) {
252
+ let initialVal = InitialValue[key]
253
+ // 仅支持 { transform: [{rotateX: '45deg'}, {rotateZ: '0.785398rad'}] } 格式的初始样式
254
+ originalStyle.transform.forEach(item => {
255
+ if (item[key] !== undefined) initialVal = item[key]
256
+ })
257
+ return initialVal
258
+ }
259
+ return originalStyle[key] === undefined ? InitialValue[key] : originalStyle[key]
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
+ // }
278
+ // 循环 animation actions 获取所有有动画的 style prop name
279
+ function getAnimatedStyleKeys () {
280
+ return (animation?.actions || []).reduce((keyMap, action) => {
281
+ const { rules, transform } = action
282
+ const ruleArr = [...rules.keys(), ...transform.keys()]
283
+ ruleArr.forEach(key => {
284
+ // const originalVal = getOriginalStyleVal(key, isTransform(key))
285
+ // if (!keyMap[key]) keyMap[key] = originalVal === undefined ? false : originalVal
286
+ if (!keyMap[key]) keyMap[key] = true
287
+ })
288
+ return keyMap
289
+ }, animatedKeys.current)
290
+ }
291
+ // animated key transform 格式化
292
+ function formatAnimatedKeys (keys: string[] = []) {
293
+ const animatedKeys = [] as (string|string[])[]
294
+ const transforms = [] as string[]
295
+ keys.forEach(key => {
296
+ if (isTransform(key)) {
297
+ transforms.push(key)
298
+ } else {
299
+ animatedKeys.push(key)
300
+ }
301
+ })
302
+ if (transforms.length) animatedKeys.push(transforms)
303
+ return animatedKeys
304
+ }
305
+ // transform 数组转对象
306
+ function getTransformObj () {
307
+ 'worklet'
308
+ const transforms = originalStyle.transform || []
309
+ return transforms.reduce((transformObj, item) => {
310
+ return Object.assign(transformObj, item)
311
+ }, {} as { [propName: string]: string | number })
312
+ }
313
+ // ** 生成动画样式
314
+ return useAnimatedStyle(() => {
315
+ // console.info(`useAnimatedStyle styles=`, originalStyle)
316
+ return animatedStyleKeys.value.reduce((styles, key) => {
317
+ // console.info('getAnimationStyles', key, shareValMap[key].value)
318
+ if (Array.isArray(key)) {
319
+ const transformStyle = getTransformObj()
320
+ key.forEach((transformKey) => {
321
+ transformStyle[transformKey] = shareValMap[transformKey].value
322
+ })
323
+ styles.transform = Object.entries(transformStyle).map(([key, value]) => {
324
+ return { [key]: value }
325
+ }) as Extract<'transform', TransformsStyle>
326
+ } else {
327
+ styles[key] = shareValMap[key].value
328
+ }
329
+ return styles
330
+ }, Object.assign({}, originalStyle) as ExtendedViewStyle)
331
+ })
332
+ }
@@ -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,9 +1,10 @@
1
- import { useEffect, useRef, ReactNode, ReactElement, FunctionComponent, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement } from 'react'
1
+ import { useEffect, useRef, ReactNode, ReactElement, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement } from 'react'
2
2
  import { LayoutChangeEvent, TextStyle } from 'react-native'
3
3
  import { isObject, 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
8
 
8
9
  export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/
9
10
  export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/
@@ -11,7 +12,7 @@ export const URL_REGEX = /^\s*url\(["']?(.*?)["']?\)\s*$/
11
12
  export const BACKGROUND_REGEX = /^background(Image|Size|Repeat|Position)$/
12
13
  export const TEXT_PROPS_REGEX = /ellipsizeMode|numberOfLines/
13
14
  export const DEFAULT_FONT_SIZE = 16
14
- export const DEFAULT_UNLAY_STYLE = {
15
+ export const HIDDEN_STYLE = {
15
16
  opacity: 0
16
17
  }
17
18
 
@@ -96,15 +97,16 @@ export const getRestProps = (transferProps: any = {}, originProps: any = {}, del
96
97
 
97
98
  export function isText (ele: ReactNode): ele is ReactElement {
98
99
  if (isValidElement(ele)) {
99
- const displayName = (ele.type as FunctionComponent)?.displayName
100
- return displayName === 'mpx-text' || displayName === 'Text'
100
+ const displayName = (ele.type as ExtendedFunctionComponent)?.displayName
101
+ const isCustomText = (ele.type as ExtendedFunctionComponent)?.isCustomText
102
+ return displayName === 'MpxText' || displayName === 'Text' || !!isCustomText
101
103
  }
102
104
  return false
103
105
  }
104
106
 
105
107
  export function isEmbedded (ele: ReactNode): ele is ReactElement {
106
108
  if (isValidElement(ele)) {
107
- const displayName = (ele.type as FunctionComponent)?.displayName || ''
109
+ const displayName = (ele.type as ExtendedFunctionComponent)?.displayName || ''
108
110
  return ['mpx-checkbox', 'mpx-radio', 'mpx-switch'].includes(displayName)
109
111
  }
110
112
  return false
@@ -472,7 +474,7 @@ interface LayoutConfig {
472
474
  export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout, nodeRef }: LayoutConfig) => {
473
475
  const layoutRef = useRef({})
474
476
  const hasLayoutRef = useRef(false)
475
- const layoutStyle: Record<string, any> = !hasLayoutRef.current && hasSelfPercent ? DEFAULT_UNLAY_STYLE : {}
477
+ const layoutStyle: Record<string, any> = !hasLayoutRef.current && hasSelfPercent ? HIDDEN_STYLE : {}
476
478
  const layoutProps: Record<string, any> = {}
477
479
  const enableOffset = props['enable-offset']
478
480
  if (hasSelfPercent || onLayout || enableOffset) {
@@ -522,3 +524,18 @@ export function wrapChildren (props: Record<string, any> = {}, { hasVarDec, varC
522
524
  }
523
525
  return children
524
526
  }
527
+
528
+ export interface GestureHandler {
529
+ nodeRefs?: Array<{ getNodeInstance: () => { nodeRef: unknown } }>;
530
+ current?: unknown;
531
+ }
532
+
533
+ export function flatGesture (gestures: Array<GestureHandler> = []) {
534
+ return (gestures && gestures.flatMap((gesture: GestureHandler) => {
535
+ if (gesture && gesture.nodeRefs) {
536
+ return gesture.nodeRefs
537
+ .map((item: { getNodeInstance: () => any }) => item.getNodeInstance()?.instance?.gestureRef || {})
538
+ }
539
+ return gesture?.current ? [gesture] : []
540
+ })) || []
541
+ }
@@ -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