@mpxjs/webpack-plugin 2.9.67 → 2.9.69-beta.0

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 (140) hide show
  1. package/lib/index.js +13 -8
  2. package/lib/platform/json/wx/index.js +21 -8
  3. package/lib/platform/style/wx/index.js +35 -38
  4. package/lib/platform/template/wx/component-config/canvas.js +8 -0
  5. package/lib/platform/template/wx/component-config/fix-component-name.js +15 -12
  6. package/lib/platform/template/wx/component-config/index.js +1 -1
  7. package/lib/platform/template/wx/component-config/input.js +1 -1
  8. package/lib/platform/template/wx/component-config/rich-text.js +8 -0
  9. package/lib/platform/template/wx/component-config/swiper.js +1 -1
  10. package/lib/platform/template/wx/component-config/textarea.js +1 -1
  11. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  12. package/lib/react/processStyles.js +14 -4
  13. package/lib/react/processTemplate.js +3 -0
  14. package/lib/resolver/AddModePlugin.js +8 -8
  15. package/lib/runtime/components/react/context.ts +6 -0
  16. package/lib/runtime/components/react/dist/context.js +2 -0
  17. package/lib/runtime/components/react/dist/event.config.js +24 -24
  18. package/lib/runtime/components/react/dist/getInnerListeners.js +183 -174
  19. package/lib/runtime/components/react/dist/mpx-button.jsx +77 -49
  20. package/lib/runtime/components/react/dist/mpx-canvas/Bus.js +60 -0
  21. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.js +15 -0
  22. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.js +84 -0
  23. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +87 -0
  24. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.js +15 -0
  25. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.js +28 -0
  26. package/lib/runtime/components/react/dist/mpx-canvas/html.js +343 -0
  27. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +232 -0
  28. package/lib/runtime/components/react/dist/mpx-canvas/utils.jsx +89 -0
  29. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +13 -19
  30. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +29 -38
  31. package/lib/runtime/components/react/dist/mpx-form.jsx +16 -19
  32. package/lib/runtime/components/react/dist/mpx-icon.jsx +8 -16
  33. package/lib/runtime/components/react/dist/mpx-image.jsx +291 -0
  34. package/lib/runtime/components/react/dist/mpx-input.jsx +54 -27
  35. package/lib/runtime/components/react/dist/mpx-label.jsx +15 -22
  36. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +13 -16
  37. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +13 -13
  38. package/lib/runtime/components/react/dist/mpx-navigator.jsx +2 -4
  39. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +6 -2
  40. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +5 -3
  41. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +6 -2
  42. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +6 -2
  43. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +6 -2
  44. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +10 -15
  45. package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +39 -0
  46. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +160 -88
  47. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +80 -121
  48. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +11 -19
  49. package/lib/runtime/components/react/dist/mpx-radio.jsx +27 -42
  50. package/lib/runtime/components/react/dist/mpx-rich-text/html.js +39 -0
  51. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +63 -0
  52. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +6 -4
  53. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +47 -41
  54. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +11 -0
  55. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +4 -2
  56. package/lib/runtime/components/react/dist/mpx-swiper.jsx +606 -0
  57. package/lib/runtime/components/react/dist/mpx-switch.jsx +20 -10
  58. package/lib/runtime/components/react/dist/mpx-text.jsx +11 -10
  59. package/lib/runtime/components/react/dist/mpx-textarea.jsx +8 -3
  60. package/lib/runtime/components/react/dist/mpx-view.jsx +65 -61
  61. package/lib/runtime/components/react/dist/mpx-web-view.jsx +112 -35
  62. package/lib/runtime/components/react/dist/pickerFaces.js +81 -0
  63. package/lib/runtime/components/react/dist/pickerVIewContext.js +9 -0
  64. package/lib/runtime/components/react/dist/pickerViewMask.jsx +18 -0
  65. package/lib/runtime/components/react/dist/pickerViewOverlay.jsx +23 -0
  66. package/lib/runtime/components/react/dist/useAnimationHooks.js +35 -9
  67. package/lib/runtime/components/react/dist/utils.jsx +70 -23
  68. package/lib/runtime/components/react/event.config.ts +25 -26
  69. package/lib/runtime/components/react/getInnerListeners.ts +237 -199
  70. package/lib/runtime/components/react/mpx-button.tsx +104 -57
  71. package/lib/runtime/components/react/mpx-canvas/Bus.ts +70 -0
  72. package/lib/runtime/components/react/mpx-canvas/CanvasGradient.ts +18 -0
  73. package/lib/runtime/components/react/mpx-canvas/CanvasRenderingContext2D.ts +87 -0
  74. package/lib/runtime/components/react/mpx-canvas/Image.ts +102 -0
  75. package/lib/runtime/components/react/mpx-canvas/ImageData.ts +23 -0
  76. package/lib/runtime/components/react/mpx-canvas/constructorsRegistry.ts +38 -0
  77. package/lib/runtime/components/react/mpx-canvas/html.ts +343 -0
  78. package/lib/runtime/components/react/mpx-canvas/index.tsx +296 -0
  79. package/lib/runtime/components/react/mpx-canvas/utils.tsx +150 -0
  80. package/lib/runtime/components/react/mpx-checkbox-group.tsx +28 -25
  81. package/lib/runtime/components/react/mpx-checkbox.tsx +48 -49
  82. package/lib/runtime/components/react/mpx-form.tsx +25 -28
  83. package/lib/runtime/components/react/mpx-icon.tsx +12 -17
  84. package/lib/runtime/components/react/mpx-image.tsx +436 -0
  85. package/lib/runtime/components/react/mpx-input.tsx +77 -57
  86. package/lib/runtime/components/react/mpx-label.tsx +26 -27
  87. package/lib/runtime/components/react/mpx-movable-area.tsx +18 -23
  88. package/lib/runtime/components/react/mpx-movable-view.tsx +21 -25
  89. package/lib/runtime/components/react/mpx-navigator.tsx +2 -8
  90. package/lib/runtime/components/react/mpx-picker/date.tsx +5 -2
  91. package/lib/runtime/components/react/mpx-picker/index.tsx +3 -2
  92. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +5 -2
  93. package/lib/runtime/components/react/mpx-picker/region.tsx +5 -2
  94. package/lib/runtime/components/react/mpx-picker/selector.tsx +5 -2
  95. package/lib/runtime/components/react/mpx-picker/time.tsx +10 -15
  96. package/lib/runtime/components/react/mpx-picker/type.ts +48 -43
  97. package/lib/runtime/components/react/mpx-picker-view-column.tsx +236 -104
  98. package/lib/runtime/components/react/mpx-picker-view.tsx +132 -122
  99. package/lib/runtime/components/react/mpx-radio-group.tsx +24 -27
  100. package/lib/runtime/components/react/mpx-radio.tsx +45 -54
  101. package/lib/runtime/components/react/mpx-rich-text/html.ts +40 -0
  102. package/lib/runtime/components/react/mpx-rich-text/index.tsx +121 -0
  103. package/lib/runtime/components/react/mpx-root-portal.tsx +3 -5
  104. package/lib/runtime/components/react/mpx-scroll-view.tsx +72 -71
  105. package/lib/runtime/components/react/mpx-simple-text.tsx +18 -0
  106. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +4 -2
  107. package/lib/runtime/components/react/mpx-swiper-item.tsx +3 -2
  108. package/lib/runtime/components/react/mpx-switch.tsx +29 -23
  109. package/lib/runtime/components/react/mpx-text.tsx +14 -18
  110. package/lib/runtime/components/react/mpx-textarea.tsx +11 -10
  111. package/lib/runtime/components/react/mpx-view.tsx +92 -76
  112. package/lib/runtime/components/react/mpx-web-view.tsx +116 -54
  113. package/lib/runtime/components/react/pickerFaces.ts +104 -0
  114. package/lib/runtime/components/react/pickerOverlay.tsx +32 -0
  115. package/lib/runtime/components/react/types/common.ts +2 -0
  116. package/lib/runtime/components/react/types/global.d.ts +5 -17
  117. package/lib/runtime/components/react/useAnimationHooks.ts +36 -11
  118. package/lib/runtime/components/react/utils.tsx +99 -28
  119. package/lib/runtime/components/web/getInnerListeners.js +6 -6
  120. package/lib/runtime/components/web/mpx-movable-view.vue +334 -344
  121. package/lib/runtime/components/web/mpx-picker-view-column.vue +75 -75
  122. package/lib/runtime/components/web/mpx-picker.vue +382 -385
  123. package/lib/runtime/components/web/mpx-web-view.vue +175 -161
  124. package/lib/runtime/optionProcessor.js +7 -38
  125. package/lib/runtime/utils.js +2 -0
  126. package/lib/style-compiler/plugins/scope-id.js +30 -2
  127. package/lib/template-compiler/bind-this.js +7 -2
  128. package/lib/template-compiler/compiler.js +79 -47
  129. package/lib/template-compiler/gen-node-react.js +3 -3
  130. package/lib/utils/pre-process-json.js +9 -5
  131. package/package.json +6 -4
  132. package/LICENSE +0 -433
  133. package/lib/runtime/components/react/dist/mpx-image/index.jsx +0 -226
  134. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -7
  135. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +0 -478
  136. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +0 -68
  137. package/lib/runtime/components/react/dist/mpx-swiper/type.js +0 -1
  138. package/lib/runtime/components/react/mpx-image/index.tsx +0 -345
  139. package/lib/runtime/components/react/mpx-image/svg.tsx +0 -22
  140. package/lib/runtime/components/web/event.js +0 -105
@@ -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
@@ -1,21 +1,7 @@
1
- declare module 'react-native-svg/css' {
2
- import type { ImageSourcePropType, StyleProp, ImageStyle } from 'react-native'
3
- import type { SvgProps as SvgCssUriProps } from 'react-native-svg'
4
-
5
- export const SvgCssUri: React.ComponentType<SvgCssUriProps & { uri?: string }>
6
-
7
- export interface WithLocalSvgProps {
8
- asset: ImageSourcePropType
9
- style?: StyleProp<ImageStyle>
10
- width?: string | number
11
- height?: string | number
12
- }
13
-
14
- export const WithLocalSvg: React.ComponentType<WithLocalSvgProps>
15
- }
16
-
17
1
  declare module '@mpxjs/utils' {
18
2
  export function isEmptyObject (obj: Object): boolean
3
+ export function isFunction (fn: unknown): boolean
4
+ export function isNumber (num: unknown): boolean
19
5
  export function hasOwn (obj: Object, key: string): boolean
20
6
  export function noop (...arg: any): void
21
7
  export function diffAndCloneA<A, B> (a: A, b?: B): {
@@ -26,13 +12,15 @@ declare module '@mpxjs/utils' {
26
12
  export function isObject (value): value is Object
27
13
  export function error (msg: string, location?: string, e?: any): void
28
14
  export function warn (msg: string, location?: string, e?: any): void
15
+ export function collectDataset (props: Record<string, any>, needParse?: boolean): Record<string, any>
29
16
  export function getFocusedNavigation (): {
30
17
  insets: {
31
18
  top: number
32
19
  bottom: number
33
20
  left: number
34
21
  right: number
35
- }
22
+ },
23
+ setOptions: (params: Record<string, any>) => void
36
24
  } | undefined
37
25
  }
38
26
 
@@ -83,9 +83,31 @@ const InitialValue: ExtendedViewStyle = Object.assign({
83
83
  const TransformOrigin = 'transformOrigin'
84
84
  // transform
85
85
  const isTransform = (key: string) => Object.keys(TransformInitial).includes(key)
86
+ // 多value解析
87
+ const parseValues = (str: string, char = ' ') => {
88
+ let stack = 0
89
+ let temp = ''
90
+ const result = []
91
+ for (let i = 0; i < str.length; i++) {
92
+ if (str[i] === '(') {
93
+ stack++
94
+ } else if (str[i] === ')') {
95
+ stack--
96
+ }
97
+ // 非括号内 或者 非分隔字符且非空
98
+ if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
99
+ temp += str[i]
100
+ }
101
+ if ((stack === 0 && str[i] === char) || i === str.length - 1) {
102
+ result.push(temp)
103
+ temp = ''
104
+ }
105
+ }
106
+ return result
107
+ }
86
108
  // parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
87
109
  const parseTransform = (transformStr: string) => {
88
- const values = transformStr.trim().split(/\s+/)
110
+ const values = parseValues(transformStr)
89
111
  const transform: {[propName: string]: string|number|number[]}[] = []
90
112
  values.forEach(item => {
91
113
  const match = item.match(/([/\w]+)\(([^)]+)\)/)
@@ -109,7 +131,7 @@ const parseTransform = (transformStr: string) => {
109
131
  break
110
132
  case 'matrix':
111
133
  case 'matrix3d':
112
- transform.push({ [key]: val.split(',').map(val => +val) })
134
+ transform.push({ [key]: parseValues(val, ',').map(val => +val) })
113
135
  break
114
136
  case 'translate':
115
137
  case 'scale':
@@ -120,8 +142,8 @@ const parseTransform = (transformStr: string) => {
120
142
  {
121
143
  // 2 个以上的值处理
122
144
  key = key.replace('3d', '')
123
- const vals = val.split(',', key === 'rotate' ? 4 : 3)
124
- // scale(.5) === scaleX(.5) scaleY(.5) 这里处理一下
145
+ const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3)
146
+ // scale(.5) === scaleX(.5) scaleY(.5)
125
147
  if (vals.length === 1 && key === 'scale') {
126
148
  vals.push(vals[0])
127
149
  }
@@ -218,12 +240,15 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
218
240
  }
219
241
  // 添加每个key的多次step动画
220
242
  animatedKeys.forEach(key => {
221
- let toVal = (rules.get(key) || transform.get(key))
222
243
  // 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)
244
+ const toVal = rules.get(key) !== undefined
245
+ ? rules.get(key)
246
+ : transform.get(key) !== undefined
247
+ ? transform.get(key)
248
+ : index > 0
249
+ ? lastValueMap[key]
250
+ : shareValMap[key].value
251
+ const animation = getAnimation({ key, value: toVal! }, { delay, duration, easing }, needSetCallback ? setTransformOrigin : undefined)
227
252
  needSetCallback = false
228
253
  if (!sequence[key]) {
229
254
  sequence[key] = [animation]
@@ -231,7 +256,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
231
256
  sequence[key].push(animation)
232
257
  }
233
258
  // 更新一下 lastValueMap
234
- lastValueMap[key] = toVal
259
+ lastValueMap[key] = toVal!
235
260
  })
236
261
  // 赋值驱动动画
237
262
  animatedKeys.forEach((key) => {
@@ -327,6 +352,6 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
327
352
  styles[key] = shareValMap[key].value
328
353
  }
329
354
  return styles
330
- }, Object.assign({}, originalStyle) as ExtendedViewStyle)
355
+ }, {} as ExtendedViewStyle)
331
356
  })
332
357
  }
@@ -1,16 +1,18 @@
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, isNumber, 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*$/
11
12
  export const URL_REGEX = /^\s*url\(["']?(.*?)["']?\)\s*$/
13
+ export const SVG_REGEXP = /https?:\/\/.*\.(?:svg)/i
12
14
  export const BACKGROUND_REGEX = /^background(Image|Size|Repeat|Position)$/
13
- export const TEXT_PROPS_REGEX = /ellipsizeMode|numberOfLines/
15
+ export const TEXT_PROPS_REGEX = /ellipsizeMode|numberOfLines|allowFontScaling/
14
16
  export const DEFAULT_FONT_SIZE = 16
15
17
  export const HIDDEN_STYLE = {
16
18
  opacity: 0
@@ -30,10 +32,7 @@ const safeAreaInsetMap: Record<string, 'top' | 'right' | 'bottom' | 'left'> = {
30
32
 
31
33
  function getSafeAreaInset (name: string) {
32
34
  const navigation = getFocusedNavigation()
33
- const insets = {
34
- ...initialWindowMetrics?.insets,
35
- ...navigation?.insets
36
- }
35
+ const insets = extendObject({}, initialWindowMetrics?.insets, navigation?.insets)
37
36
  return insets[safeAreaInsetMap[name]]
38
37
  }
39
38
 
@@ -78,7 +77,7 @@ export const parseInlineStyle = (inlineStyle = ''): Record<string, string> => {
78
77
  const [k, v, ...rest] = style.split(':')
79
78
  if (rest.length || !v || !k) return styleObj
80
79
  const key = k.trim().replace(/-./g, c => c.substring(1).toUpperCase())
81
- return Object.assign(styleObj, { [key]: v.trim() })
80
+ return Object.assign(styleObj, { [key]: global.__formatValue(v.trim()) })
82
81
  }, {})
83
82
  }
84
83
 
@@ -89,25 +88,18 @@ export const parseUrl = (cssUrl = '') => {
89
88
  }
90
89
 
91
90
  export const getRestProps = (transferProps: any = {}, originProps: any = {}, deletePropsKey: any = []) => {
92
- return {
93
- ...transferProps,
94
- ...omit(originProps, deletePropsKey)
95
- }
91
+ return extendObject(
92
+ {},
93
+ transferProps,
94
+ omit(originProps, deletePropsKey)
95
+ )
96
96
  }
97
97
 
98
98
  export function isText (ele: ReactNode): ele is ReactElement {
99
99
  if (isValidElement(ele)) {
100
100
  const displayName = (ele.type as ExtendedFunctionComponent)?.displayName
101
101
  const isCustomText = (ele.type as ExtendedFunctionComponent)?.isCustomText
102
- return displayName === 'MpxText' || displayName === 'Text' || !!isCustomText
103
- }
104
- return false
105
- }
106
-
107
- export function isEmbedded (ele: ReactNode): ele is ReactElement {
108
- if (isValidElement(ele)) {
109
- const displayName = (ele.type as ExtendedFunctionComponent)?.displayName || ''
110
- return ['mpx-checkbox', 'mpx-radio', 'mpx-switch'].includes(displayName)
102
+ return displayName === 'MpxText' || displayName === 'MpxSimpleText' || displayName === 'Text' || !!isCustomText
111
103
  }
112
104
  return false
113
105
  }
@@ -275,6 +267,15 @@ function transformCalc (styleObj: Record<string, any>, calcKeyPaths: Array<Array
275
267
  })
276
268
  }
277
269
 
270
+ const stringifyProps = ['fontWeight']
271
+ function transformStringify (styleObj: Record<string, any>) {
272
+ stringifyProps.forEach((prop) => {
273
+ if (isNumber(styleObj[prop])) {
274
+ styleObj[prop] = '' + styleObj[prop]
275
+ }
276
+ })
277
+ }
278
+
278
279
  interface TransformStyleConfig {
279
280
  enableVar?: boolean
280
281
  externalVarContext?: Record<string, any>
@@ -385,6 +386,8 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
385
386
  }
386
387
  }
387
388
  })
389
+ // transform number enum stringify
390
+ transformStringify(normalStyle)
388
391
 
389
392
  return {
390
393
  normalStyle,
@@ -474,7 +477,7 @@ interface LayoutConfig {
474
477
  export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout, nodeRef }: LayoutConfig) => {
475
478
  const layoutRef = useRef({})
476
479
  const hasLayoutRef = useRef(false)
477
- const layoutStyle: Record<string, any> = !hasLayoutRef.current && hasSelfPercent ? HIDDEN_STYLE : {}
480
+ const layoutStyle = useMemo(() => { return !hasLayoutRef.current && hasSelfPercent ? HIDDEN_STYLE : {} }, [hasLayoutRef.current])
478
481
  const layoutProps: Record<string, any> = {}
479
482
  const enableOffset = props['enable-offset']
480
483
  if (hasSelfPercent || onLayout || enableOffset) {
@@ -513,8 +516,8 @@ export function wrapChildren (props: Record<string, any> = {}, { hasVarDec, varC
513
516
  if (textStyle || textProps) {
514
517
  children = Children.map(children, (child) => {
515
518
  if (isText(child)) {
516
- const style = { ...textStyle, ...child.props.style }
517
- return cloneElement(child, { ...textProps, style })
519
+ const style = extendObject({}, textStyle, child.props.style)
520
+ return cloneElement(child, extendObject({}, textProps, { style }))
518
521
  }
519
522
  return child
520
523
  })
@@ -525,9 +528,52 @@ export function wrapChildren (props: Record<string, any> = {}, { hasVarDec, varC
525
528
  return children
526
529
  }
527
530
 
531
+ export const debounce = <T extends AnyFunc> (
532
+ func: T,
533
+ delay: number
534
+ ): ((...args: Parameters<T>) => void) & { clear: () => void } => {
535
+ let timer: any
536
+ const wrapper = (...args: ReadonlyArray<any>) => {
537
+ clearTimeout(timer)
538
+ timer = setTimeout(() => {
539
+ func(...args)
540
+ }, delay)
541
+ }
542
+ wrapper.clear = () => {
543
+ clearTimeout(timer)
544
+ }
545
+ return wrapper
546
+ }
547
+
548
+ export const useDebounceCallback = <T extends AnyFunc> (
549
+ func: T,
550
+ delay: number
551
+ ): ((...args: Parameters<T>) => void) & { clear: () => void } => {
552
+ const debounced = useMemo(() => debounce(func, delay), [func])
553
+ return debounced
554
+ }
555
+
556
+ export const useStableCallback = <T extends AnyFunc | null | undefined> (
557
+ callback: T
558
+ ): T extends AnyFunc ? T : () => void => {
559
+ const ref = useRef<T>(callback)
560
+ ref.current = callback
561
+ return useCallback<any>(
562
+ (...args: any[]) => ref.current?.(...args),
563
+ []
564
+ )
565
+ }
566
+
567
+ export const usePrevious = <T, > (value: T): T | undefined => {
568
+ const ref = useRef<T | undefined>(undefined)
569
+ const prev = ref.current
570
+ ref.current = value
571
+ return prev
572
+ }
573
+
528
574
  export interface GestureHandler {
529
- nodeRefs?: Array<{ getNodeInstance: () => { nodeRef: unknown } }>;
530
- current?: unknown;
575
+ nodeRefs?: Array<{ getNodeInstance: () => { nodeRef: unknown } }>
576
+ current?: unknown
531
577
  }
532
578
 
533
579
  export function flatGesture (gestures: Array<GestureHandler> = []) {
@@ -539,3 +585,28 @@ export function flatGesture (gestures: Array<GestureHandler> = []) {
539
585
  return gesture?.current ? [gesture] : []
540
586
  })) || []
541
587
  }
588
+
589
+ export const extendObject = Object.assign
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
+ }
@@ -1,3 +1,4 @@
1
+ import { extend } from '../../utils'
1
2
  function processModel (listeners, context) {
2
3
  // 该函数只有wx:model的情况下才调用,而且默认e.detail.value有值
3
4
  // 该函数必须在产生merge前执行
@@ -53,7 +54,7 @@ export function extendEvent (e, extendObj = {}) {
53
54
  }
54
55
 
55
56
  export function inheritEvent (type, oe, detail = {}) {
56
- detail = Object.assign({}, oe.detail, detail)
57
+ detail = extend({}, oe.detail, detail)
57
58
  const ne = getCustomEvent(type, detail)
58
59
  extendEvent(ne, {
59
60
  timeStamp: oe.timeStamp,
@@ -68,12 +69,11 @@ export function inheritEvent (type, oe, detail = {}) {
68
69
  export function getCustomEvent (type, detail = {}, target = null) {
69
70
  const targetEl = (target && target.$el) || null
70
71
  const targetInfo = targetEl ? { target: targetEl, currentTarget: targetEl } : {}
71
- return {
72
+ return extend({
72
73
  type,
73
74
  detail,
74
- timeStamp: new Date().valueOf(),
75
- ...targetInfo
76
- }
75
+ timeStamp: new Date().valueOf()
76
+ }, targetInfo)
77
77
  }
78
78
 
79
79
  function noop () {
@@ -82,7 +82,7 @@ function noop () {
82
82
 
83
83
  export default function getInnerListeners (context, options = {}) {
84
84
  let { mergeBefore = {}, mergeAfter = {}, defaultListeners = [], ignoredListeners = [] } = options
85
- const listeners = Object.assign({}, context.$listeners)
85
+ const listeners = extend({}, context.$listeners)
86
86
  defaultListeners.forEach((key) => {
87
87
  if (!listeners[key]) listeners[key] = noop
88
88
  })