@mpxjs/webpack-plugin 2.9.64 → 2.9.66

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/config.js +38 -10
  2. package/lib/index.js +5 -1
  3. package/lib/platform/style/wx/index.js +66 -60
  4. package/lib/platform/template/wx/index.js +12 -8
  5. package/lib/react/processTemplate.js +4 -2
  6. package/lib/react/style-helper.js +2 -5
  7. package/lib/runtime/components/react/context.ts +8 -0
  8. package/lib/runtime/components/react/dist/context.js +1 -0
  9. package/lib/runtime/components/react/dist/mpx-button.jsx +2 -1
  10. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +2 -1
  11. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +3 -2
  12. package/lib/runtime/components/react/dist/mpx-form.jsx +2 -1
  13. package/lib/runtime/components/react/dist/mpx-icon.jsx +3 -2
  14. package/lib/runtime/components/react/dist/mpx-image/index.jsx +2 -1
  15. package/lib/runtime/components/react/dist/mpx-input.jsx +2 -1
  16. package/lib/runtime/components/react/dist/mpx-label.jsx +2 -1
  17. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +3 -2
  18. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +2 -1
  19. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +2 -1
  20. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +2 -1
  21. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +2 -1
  22. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +2 -1
  23. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +2 -1
  24. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +4 -2
  25. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +3 -2
  26. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +2 -1
  27. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +2 -1
  28. package/lib/runtime/components/react/dist/mpx-radio.jsx +3 -2
  29. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +13 -3
  30. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +78 -77
  31. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +2 -1
  32. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +3 -2
  33. package/lib/runtime/components/react/dist/mpx-switch.jsx +3 -2
  34. package/lib/runtime/components/react/dist/mpx-text.jsx +2 -1
  35. package/lib/runtime/components/react/dist/mpx-view.jsx +45 -15
  36. package/lib/runtime/components/react/dist/mpx-web-view.jsx +4 -3
  37. package/lib/runtime/components/react/dist/useAnimationHooks.js +215 -0
  38. package/lib/runtime/components/react/dist/useNodesRef.js +1 -5
  39. package/lib/runtime/components/react/dist/utils.jsx +50 -37
  40. package/lib/runtime/components/react/mpx-button.tsx +3 -1
  41. package/lib/runtime/components/react/mpx-checkbox-group.tsx +3 -1
  42. package/lib/runtime/components/react/mpx-checkbox.tsx +4 -1
  43. package/lib/runtime/components/react/mpx-form.tsx +2 -1
  44. package/lib/runtime/components/react/mpx-icon.tsx +3 -2
  45. package/lib/runtime/components/react/mpx-image/index.tsx +2 -1
  46. package/lib/runtime/components/react/mpx-input.tsx +2 -1
  47. package/lib/runtime/components/react/mpx-label.tsx +2 -1
  48. package/lib/runtime/components/react/mpx-movable-area.tsx +3 -2
  49. package/lib/runtime/components/react/mpx-movable-view.tsx +2 -1
  50. package/lib/runtime/components/react/mpx-picker/date.tsx +2 -1
  51. package/lib/runtime/components/react/mpx-picker/index.tsx +2 -1
  52. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +2 -1
  53. package/lib/runtime/components/react/mpx-picker/region.tsx +2 -1
  54. package/lib/runtime/components/react/mpx-picker/selector.tsx +2 -1
  55. package/lib/runtime/components/react/mpx-picker/time.tsx +4 -2
  56. package/lib/runtime/components/react/mpx-picker-view-column.tsx +3 -2
  57. package/lib/runtime/components/react/mpx-picker-view.tsx +2 -1
  58. package/lib/runtime/components/react/mpx-radio-group.tsx +2 -1
  59. package/lib/runtime/components/react/mpx-radio.tsx +3 -2
  60. package/lib/runtime/components/react/mpx-scroll-view.tsx +14 -2
  61. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +77 -75
  62. package/lib/runtime/components/react/mpx-swiper/index.tsx +4 -1
  63. package/lib/runtime/components/react/mpx-swiper-item.tsx +2 -1
  64. package/lib/runtime/components/react/mpx-switch.tsx +2 -1
  65. package/lib/runtime/components/react/mpx-text.tsx +2 -1
  66. package/lib/runtime/components/react/mpx-view.tsx +55 -23
  67. package/lib/runtime/components/react/mpx-web-view.tsx +4 -3
  68. package/lib/runtime/components/react/types/common.ts +8 -2
  69. package/lib/runtime/components/react/types/global.d.ts +11 -1
  70. package/lib/runtime/components/react/useAnimationHooks.ts +248 -0
  71. package/lib/runtime/components/react/useNodesRef.ts +1 -6
  72. package/lib/runtime/components/react/utils.tsx +71 -50
  73. package/lib/runtime/components/web/mpx-scroll-view.vue +25 -5
  74. package/lib/style-compiler/index.js +5 -4
  75. package/lib/template-compiler/compiler.js +127 -158
  76. package/lib/utils/const.js +2 -1
  77. package/lib/web/processStyles.js +6 -2
  78. package/lib/web/processTemplate.js +2 -3
  79. package/lib/wxml/loader.js +1 -1
  80. package/package.json +6 -4
@@ -1,8 +1,10 @@
1
- import { useEffect, useRef, ReactNode, ReactElement, FunctionComponent, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement } from 'react'
2
- import { Dimensions, StyleSheet, LayoutChangeEvent, TextStyle } from 'react-native'
3
- import { isObject, hasOwn, diffAndCloneA, error, warn } from '@mpxjs/utils'
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'
4
4
  import { VarContext } from './context'
5
5
  import { ExpressionParser, parseFunc, ReplaceSource } from './parser'
6
+ import { initialWindowMetrics } from 'react-native-safe-area-context'
7
+ import type { ExtendedFunctionComponent } from './types/common'
6
8
 
7
9
  export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/
8
10
  export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/
@@ -14,19 +16,26 @@ export const DEFAULT_UNLAY_STYLE = {
14
16
  opacity: 0
15
17
  }
16
18
 
17
- export function rpx (value: number) {
18
- const { width } = Dimensions.get('screen')
19
- // rn 单位 dp = 1(css)px = 1 物理像素 * pixelRatio(像素比)
20
- // px = rpx * (750 / 屏幕宽度)
21
- return value * width / 750
22
- }
23
-
24
- const rpxRegExp = /^\s*(-?\d+(\.\d+)?)rpx\s*$/
25
- const pxRegExp = /^\s*(-?\d+(\.\d+)?)(px)?\s*$/
26
- const hairlineRegExp = /^\s*hairlineWidth\s*$/
27
19
  const varDecRegExp = /^--.*/
28
20
  const varUseRegExp = /var\(/
29
21
  const calcUseRegExp = /calc\(/
22
+ const envUseRegExp = /env\(/
23
+
24
+ const safeAreaInsetMap: Record<string, 'top' | 'right' | 'bottom' | 'left'> = {
25
+ 'safe-area-inset-top': 'top',
26
+ 'safe-area-inset-right': 'right',
27
+ 'safe-area-inset-bottom': 'bottom',
28
+ 'safe-area-inset-left': 'left'
29
+ }
30
+
31
+ function getSafeAreaInset (name: string) {
32
+ const navigation = getFocusedNavigation()
33
+ const insets = {
34
+ ...initialWindowMetrics?.insets,
35
+ ...navigation?.insets
36
+ }
37
+ return insets[safeAreaInsetMap[name]]
38
+ }
30
39
 
31
40
  export function omit<T, K extends string> (obj: T, fields: K[]): Omit<T, K> {
32
41
  const shallowCopy: any = Object.assign({}, obj)
@@ -88,15 +97,16 @@ export const getRestProps = (transferProps: any = {}, originProps: any = {}, del
88
97
 
89
98
  export function isText (ele: ReactNode): ele is ReactElement {
90
99
  if (isValidElement(ele)) {
91
- const displayName = (ele.type as FunctionComponent)?.displayName
92
- 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 === 'mpx-text' || displayName === 'Text' || !!isCustomText
93
103
  }
94
104
  return false
95
105
  }
96
106
 
97
107
  export function isEmbedded (ele: ReactNode): ele is ReactElement {
98
108
  if (isValidElement(ele)) {
99
- const displayName = (ele.type as FunctionComponent)?.displayName || ''
109
+ const displayName = (ele.type as ExtendedFunctionComponent)?.displayName || ''
100
110
  return ['mpx-checkbox', 'mpx-radio', 'mpx-switch'].includes(displayName)
101
111
  }
102
112
  return false
@@ -122,9 +132,9 @@ export function groupBy<T extends Record<string, any>> (
122
132
  }
123
133
 
124
134
  export function splitStyle<T extends Record<string, any>> (styleObj: T): {
125
- textStyle?: Partial<T>;
126
- backgroundStyle?: Partial<T>;
127
- innerStyle?: Partial<T>;
135
+ textStyle?: Partial<T>
136
+ backgroundStyle?: Partial<T>
137
+ innerStyle?: Partial<T>
128
138
  } {
129
139
  return groupBy(styleObj, (key) => {
130
140
  if (TEXT_STYLE_REGEX.test(key)) {
@@ -135,9 +145,9 @@ export function splitStyle<T extends Record<string, any>> (styleObj: T): {
135
145
  return 'innerStyle'
136
146
  }
137
147
  }) as {
138
- textStyle: Partial<T>;
139
- backgroundStyle: Partial<T>;
140
- innerStyle: Partial<T>;
148
+ textStyle: Partial<T>
149
+ backgroundStyle: Partial<T>
150
+ innerStyle: Partial<T>
141
151
  }
142
152
  }
143
153
 
@@ -157,19 +167,6 @@ const parentHeightPercentRule: Record<string, boolean> = {
157
167
  bottom: true
158
168
  }
159
169
 
160
- // todo calc时处理角度和时间等单位
161
- function formatValue (value: string) {
162
- let matched
163
- if ((matched = pxRegExp.exec(value))) {
164
- return +matched[1]
165
- } else if ((matched = rpxRegExp.exec(value))) {
166
- return rpx(+matched[1])
167
- } else if (hairlineRegExp.test(value)) {
168
- return StyleSheet.hairlineWidth
169
- }
170
- return value
171
- }
172
-
173
170
  interface PercentConfig {
174
171
  fontSize?: number | string
175
172
  width?: number
@@ -226,11 +223,11 @@ function resolveVar (input: string, varContext: Record<string, any>) {
226
223
  if (varUseRegExp.test(varValue)) {
227
224
  varValue = '' + resolveVar(varValue, varContext)
228
225
  } else {
229
- varValue = '' + formatValue(varValue)
226
+ varValue = '' + global.__formatValue(varValue)
230
227
  }
231
228
  replaced.replace(start, end - 1, varValue)
232
229
  })
233
- return formatValue(replaced.source())
230
+ return global.__formatValue(replaced.source())
234
231
  }
235
232
 
236
233
  function transformVar (styleObj: Record<string, any>, varKeyPaths: Array<Array<string>>, varContext: Record<string, any>) {
@@ -241,6 +238,22 @@ function transformVar (styleObj: Record<string, any>, varKeyPaths: Array<Array<s
241
238
  })
242
239
  }
243
240
 
241
+ function transformEnv (styleObj: Record<string, any>, envKeyPaths: Array<Array<string>>) {
242
+ envKeyPaths.forEach((envKeyPath) => {
243
+ setStyle(styleObj, envKeyPath, ({ target, key, value }) => {
244
+ const parsed = parseFunc(value, 'env')
245
+ const replaced = new ReplaceSource(value)
246
+ parsed.forEach(({ start, end, args }) => {
247
+ const name = args[0]
248
+ const fallback = args[1] || ''
249
+ const value = '' + (getSafeAreaInset(name) ?? global.__formatValue(fallback))
250
+ replaced.replace(start, end - 1, value)
251
+ })
252
+ target[key] = global.__formatValue(replaced.source())
253
+ })
254
+ })
255
+ }
256
+
244
257
  function transformCalc (styleObj: Record<string, any>, calcKeyPaths: Array<Array<string>>, formatter: (value: string, key: string) => number) {
245
258
  calcKeyPaths.forEach((calcKeyPath) => {
246
259
  setStyle(styleObj, calcKeyPath, ({ target, key, value }) => {
@@ -257,7 +270,7 @@ function transformCalc (styleObj: Record<string, any>, calcKeyPaths: Array<Array
257
270
  error(`calc(${exp}) parse error.`, undefined, e)
258
271
  }
259
272
  })
260
- target[key] = formatValue(replaced.source())
273
+ target[key] = global.__formatValue(replaced.source())
261
274
  })
262
275
  })
263
276
  }
@@ -279,6 +292,7 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
279
292
  const varKeyPaths: Array<Array<string>> = []
280
293
  const percentKeyPaths: Array<Array<string>> = []
281
294
  const calcKeyPaths: Array<Array<string>> = []
295
+ const envKeyPaths: Array<Array<string>> = []
282
296
  const [width, setWidth] = useState(0)
283
297
  const [height, setHeight] = useState(0)
284
298
 
@@ -298,6 +312,7 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
298
312
  varKeyPaths.push(keyPath.slice())
299
313
  }
300
314
  }
315
+
301
316
  // traverse var
302
317
  traverseStyle(styleObj, [varVisitor])
303
318
  hasVarDec = hasVarDec || !!externalVarContext
@@ -318,6 +333,12 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
318
333
  transformVar(normalStyle, varKeyPaths, varContextRef.current)
319
334
  }
320
335
 
336
+ function envVisitor ({ value, keyPath }: VisitorArg) {
337
+ if (envUseRegExp.test(value)) {
338
+ envKeyPaths.push(keyPath.slice())
339
+ }
340
+ }
341
+
321
342
  function calcVisitor ({ value, keyPath }: VisitorArg) {
322
343
  if (calcUseRegExp.test(value)) {
323
344
  calcKeyPaths.push(keyPath.slice())
@@ -328,13 +349,13 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
328
349
  if (hasOwn(selfPercentRule, key) && PERCENT_REGEX.test(value)) {
329
350
  hasSelfPercent = true
330
351
  percentKeyPaths.push(keyPath.slice())
331
- } else if (key === 'fontSize' || key === 'lineHeight') {
352
+ } else if ((key === 'fontSize' || key === 'lineHeight') && PERCENT_REGEX.test(value)) {
332
353
  percentKeyPaths.push(keyPath.slice())
333
354
  }
334
355
  }
335
356
 
336
- // traverse calc & percent
337
- traverseStyle(normalStyle, [percentVisitor, calcVisitor])
357
+ // traverse env & calc & percent
358
+ traverseStyle(normalStyle, [envVisitor, percentVisitor, calcVisitor])
338
359
 
339
360
  const percentConfig = {
340
361
  width,
@@ -345,6 +366,8 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
345
366
  parentFontSize
346
367
  }
347
368
 
369
+ // apply env
370
+ transformEnv(normalStyle, envKeyPaths)
348
371
  // apply percent
349
372
  transformPercent(normalStyle, percentKeyPaths, percentConfig)
350
373
  // apply calc
@@ -353,7 +376,7 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
353
376
  const resolved = resolvePercent(value, key, percentConfig)
354
377
  return typeof resolved === 'number' ? resolved : 0
355
378
  } else {
356
- const formatted = formatValue(value)
379
+ const formatted = global.__formatValue(value)
357
380
  if (typeof formatted === 'number') {
358
381
  return formatted
359
382
  } else {
@@ -409,11 +432,9 @@ export function traverseStyle (styleObj: Record<string, any>, visitors: Array<(a
409
432
  traverse(styleObj)
410
433
  }
411
434
 
412
- export function setStyle (styleObj: Record<string, any>, keyPath: Array<string>, setter: (arg: VisitorArg) => void, needClone = false) {
435
+ export function setStyle (styleObj: Record<string, any>, keyPath: Array<string>, setter: (arg: VisitorArg) => void) {
413
436
  let target = styleObj
414
- const firstKey = keyPath[0]
415
437
  const lastKey = keyPath[keyPath.length - 1]
416
- if (needClone) target[firstKey] = diffAndCloneA(target[firstKey]).clone
417
438
  for (let i = 0; i < keyPath.length - 1; i++) {
418
439
  target = target[keyPath[i]]
419
440
  if (!target) return
@@ -427,8 +448,8 @@ export function setStyle (styleObj: Record<string, any>, keyPath: Array<string>,
427
448
  }
428
449
 
429
450
  export function splitProps<T extends Record<string, any>> (props: T): {
430
- textProps?: Partial<T>;
431
- innerProps?: Partial<T>;
451
+ textProps?: Partial<T>
452
+ innerProps?: Partial<T>
432
453
  } {
433
454
  return groupBy(props, (key) => {
434
455
  if (TEXT_PROPS_REGEX.test(key)) {
@@ -437,8 +458,8 @@ export function splitProps<T extends Record<string, any>> (props: T): {
437
458
  return 'innerProps'
438
459
  }
439
460
  }) as {
440
- textProps: Partial<T>;
441
- innerProps: Partial<T>;
461
+ textProps: Partial<T>
462
+ innerProps: Partial<T>
442
463
  }
443
464
  }
444
465
 
@@ -450,7 +471,7 @@ interface LayoutConfig {
450
471
  onLayout?: (event?: LayoutChangeEvent) => void
451
472
  nodeRef: React.RefObject<any>
452
473
  }
453
- export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout, nodeRef }:LayoutConfig) => {
474
+ export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout, nodeRef }: LayoutConfig) => {
454
475
  const layoutRef = useRef({})
455
476
  const hasLayoutRef = useRef(false)
456
477
  const layoutStyle: Record<string, any> = !hasLayoutRef.current && hasSelfPercent ? DEFAULT_UNLAY_STYLE : {}
@@ -9,6 +9,7 @@
9
9
  BScroll.use(PullDown)
10
10
 
11
11
  let mutationObserver = null
12
+ let resizeObserver = null
12
13
 
13
14
  export default {
14
15
  name: 'mpx-scroll-view',
@@ -357,11 +358,15 @@
357
358
  let minTop
358
359
  let maxBottom
359
360
  childrenArr.forEach(item => {
360
- const temp = item.getBoundingClientRect()
361
- minLeft = getMinLength(minLeft, temp.left)
362
- minTop = getMinLength(minTop, temp.top)
363
- maxRight = getMaxLength(maxRight, temp.right)
364
- maxBottom = getMaxLength(maxBottom, temp.bottom)
361
+ const left = item.offsetLeft
362
+ const top = item.offsetTop
363
+ const width = item.offsetWidth
364
+ const height = item.offsetHeight
365
+
366
+ minLeft = getMinLength(minLeft, left)
367
+ minTop = getMinLength(minTop, top)
368
+ maxRight = getMaxLength(maxRight, left + width)
369
+ maxBottom = getMaxLength(maxBottom, top + height)
365
370
  })
366
371
  const width = maxRight - minLeft || 0
367
372
  const height = maxBottom - minTop || 0
@@ -399,6 +404,17 @@
399
404
  const config = { attributes: true, childList: true, subtree: true }
400
405
  mutationObserver.observe(this.$refs.wrapper, config)
401
406
  }
407
+ if (typeof ResizeObserver !== 'undefined') {
408
+ let isFirstResize = true
409
+ resizeObserver = new ResizeObserver(() => {
410
+ if (isFirstResize) {
411
+ isFirstResize = false
412
+ return
413
+ }
414
+ this.debounceRefresh()
415
+ })
416
+ resizeObserver.observe(this.$refs.wrapper)
417
+ }
402
418
  },
403
419
  mutationObserverHandler (mutations) {
404
420
  let needRefresh = false
@@ -428,6 +444,10 @@
428
444
  mutationObserver.disconnect()
429
445
  mutationObserver = null
430
446
  }
447
+ if (resizeObserver) {
448
+ resizeObserver.disconnect()
449
+ resizeObserver = null
450
+ }
431
451
  }
432
452
  },
433
453
  render (createElement) {
@@ -18,7 +18,8 @@ module.exports = function (css, map) {
18
18
  const cb = this.async()
19
19
  const { resourcePath, queryObj } = parseRequest(this.resource)
20
20
  const mpx = this.getMpx()
21
- const id = queryObj.moduleId || queryObj.mid || '_' + mpx.pathHash(resourcePath)
21
+ const mpxStyleOptions = (queryObj.mpxStyleOptions && JSON.parse(queryObj.mpxStyleOptions)) || {}
22
+ const id = queryObj.moduleId || mpxStyleOptions.mid || '_' + mpx.pathHash(resourcePath)
22
23
  const appInfo = mpx.appInfo
23
24
  const defs = mpx.defs
24
25
  const mode = mpx.mode
@@ -46,14 +47,14 @@ module.exports = function (css, map) {
46
47
  config.options
47
48
  )
48
49
  // ali平台下处理scoped和host选择器
49
- if (mode === 'ali') {
50
- if (queryObj.scoped) {
50
+ if (mode === 'ali' || mode === 'web') {
51
+ if (queryObj.scoped || mpxStyleOptions.scoped) {
51
52
  plugins.push(scopeId({ id }))
52
53
  }
53
54
  plugins.push(transSpecial({ id }))
54
55
  }
55
56
 
56
- if (mode === 'web' || isReact(mode)) {
57
+ if (isReact(mode)) {
57
58
  plugins.push(transSpecial({ id }))
58
59
  }
59
60