@mpxjs/webpack-plugin 2.9.18 → 2.9.19-react.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 (57) hide show
  1. package/lib/config.js +59 -97
  2. package/lib/dependencies/ResolveDependency.js +2 -2
  3. package/lib/helpers.js +5 -1
  4. package/lib/index.js +21 -18
  5. package/lib/loader.js +44 -97
  6. package/lib/native-loader.js +1 -1
  7. package/lib/platform/index.js +3 -0
  8. package/lib/platform/style/wx/index.js +413 -0
  9. package/lib/platform/template/wx/component-config/button.js +36 -0
  10. package/lib/platform/template/wx/component-config/image.js +15 -0
  11. package/lib/platform/template/wx/component-config/input.js +36 -0
  12. package/lib/platform/template/wx/component-config/scroll-view.js +27 -1
  13. package/lib/platform/template/wx/component-config/swiper-item.js +13 -1
  14. package/lib/platform/template/wx/component-config/swiper.js +25 -1
  15. package/lib/platform/template/wx/component-config/text.js +15 -0
  16. package/lib/platform/template/wx/component-config/textarea.js +39 -0
  17. package/lib/platform/template/wx/component-config/unsupported.js +18 -0
  18. package/lib/platform/template/wx/component-config/view.js +14 -0
  19. package/lib/platform/template/wx/index.js +88 -4
  20. package/lib/react/index.js +92 -0
  21. package/lib/react/processJSON.js +362 -0
  22. package/lib/react/processScript.js +40 -0
  23. package/lib/react/processStyles.js +63 -0
  24. package/lib/react/processTemplate.js +151 -0
  25. package/lib/react/script-helper.js +79 -0
  26. package/lib/react/style-helper.js +91 -0
  27. package/lib/runtime/components/react/event.config.ts +32 -0
  28. package/lib/runtime/components/react/getInnerListeners.ts +289 -0
  29. package/lib/runtime/components/react/getInnerListeners.type.ts +68 -0
  30. package/lib/runtime/components/react/mpx-button.tsx +402 -0
  31. package/lib/runtime/components/react/mpx-image/index.tsx +351 -0
  32. package/lib/runtime/components/react/mpx-image/svg.tsx +21 -0
  33. package/lib/runtime/components/react/mpx-input.tsx +389 -0
  34. package/lib/runtime/components/react/mpx-scroll-view.tsx +412 -0
  35. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +407 -0
  36. package/lib/runtime/components/react/mpx-swiper/index.tsx +68 -0
  37. package/lib/runtime/components/react/mpx-swiper/type.ts +69 -0
  38. package/lib/runtime/components/react/mpx-swiper-item.tsx +42 -0
  39. package/lib/runtime/components/react/mpx-text.tsx +106 -0
  40. package/lib/runtime/components/react/mpx-textarea.tsx +46 -0
  41. package/lib/runtime/components/react/mpx-view.tsx +397 -0
  42. package/lib/runtime/components/react/utils.ts +92 -0
  43. package/lib/runtime/stringify.wxs +3 -7
  44. package/lib/runtime/useNodesRef.ts +39 -0
  45. package/lib/style-compiler/index.js +2 -1
  46. package/lib/template-compiler/compiler.js +539 -287
  47. package/lib/template-compiler/gen-node-react.js +95 -0
  48. package/lib/template-compiler/index.js +19 -31
  49. package/lib/utils/env.js +17 -0
  50. package/lib/utils/make-map.js +1 -1
  51. package/lib/utils/shallow-stringify.js +17 -0
  52. package/lib/web/index.js +122 -0
  53. package/lib/web/processMainScript.js +3 -4
  54. package/lib/web/processScript.js +9 -5
  55. package/lib/web/processTemplate.js +14 -14
  56. package/lib/web/script-helper.js +11 -19
  57. package/package.json +7 -3
@@ -0,0 +1,351 @@
1
+ /**
2
+ * ✔ src
3
+ * - mode: Partially, Only SVG format do not support
4
+ * ✘ show-menu-by-longpress
5
+ * ✔ binderror
6
+ * ✔ bindload
7
+ * ✘ fade-in
8
+ * ✔ webp
9
+ * ✘ lazy-load
10
+ * ✔ bindtap
11
+ * ✔ DEFAULT_SIZE
12
+ */
13
+ import React, {
14
+ useCallback,
15
+ useEffect,
16
+ useMemo,
17
+ useState,
18
+ forwardRef,
19
+ useRef,
20
+ } from 'react'
21
+ import {
22
+ Image as RNImage,
23
+ View,
24
+ ImageStyle,
25
+ StyleProp,
26
+ ImageSourcePropType,
27
+ ImageResizeMode,
28
+ StyleSheet,
29
+ NativeSyntheticEvent,
30
+ ImageErrorEventData,
31
+ LayoutChangeEvent,
32
+ DimensionValue,
33
+ ImageLoadEventData,
34
+ } from 'react-native'
35
+ import useInnerProps, { getCustomEvent } from '../getInnerListeners'
36
+ import useNodesRef, { HandlerRef } from '../../../useNodesRef'
37
+
38
+ export type Mode =
39
+ | 'scaleToFill'
40
+ | 'aspectFit'
41
+ | 'aspectFill'
42
+ | 'widthFix'
43
+ | 'heightFix'
44
+ | 'top'
45
+ | 'bottom'
46
+ | 'center'
47
+ | 'left'
48
+ | 'right'
49
+ | 'top left'
50
+ | 'top right'
51
+ | 'bottom left'
52
+ | 'bottom right'
53
+
54
+ export type SvgNumberProp = string | number | undefined
55
+
56
+ export interface ImageProps {
57
+ src?: string
58
+ mode?: Mode
59
+ svg?: boolean
60
+ style?: StyleProp<ImageStyle>
61
+ 'enable-offset'?: boolean;
62
+ bindload?: (evt: NativeSyntheticEvent<ImageLoadEventData> | unknown) => void
63
+ binderror?: (evt: NativeSyntheticEvent<ImageErrorEventData> | unknown) => void
64
+ }
65
+
66
+ const DEFAULT_IMAGE_WIDTH = 320
67
+ const DEFAULT_IMAGE_HEIGHT = 240
68
+ // const REMOTE_SVG_REGEXP = /https?:\/\/.*\.(?:svg)/i
69
+
70
+ // const styls = StyleSheet.create({
71
+ // suspense: {
72
+ // display: 'flex',
73
+ // justifyContent: 'center',
74
+ // alignItems: 'center',
75
+ // width: '100%',
76
+ // height: '100%',
77
+ // },
78
+ // })
79
+
80
+ const cropMode: Mode[] = [
81
+ 'top',
82
+ 'bottom',
83
+ 'center',
84
+ 'right',
85
+ 'left',
86
+ 'top left',
87
+ 'top right',
88
+ 'bottom left',
89
+ 'bottom right',
90
+ ]
91
+
92
+ const ModeMap = new Map<Mode, ImageResizeMode | undefined>([
93
+ ['scaleToFill', 'stretch'],
94
+ ['aspectFit', 'contain'],
95
+ ['aspectFill', 'cover'],
96
+ ['widthFix', 'stretch'],
97
+ ['heightFix', 'stretch'],
98
+ ...cropMode.map<[Mode, ImageResizeMode]>(mode => [mode, 'stretch']),
99
+ ])
100
+
101
+ const isNumber = (value: DimensionValue) => typeof value === 'number'
102
+
103
+ const relativeCenteredSize = (viewSize: number, imageSize: number) => (viewSize - imageSize) / 2
104
+
105
+ // const Svg = lazy(() => import('./svg'))
106
+
107
+ // const Fallback = (
108
+ // <View style={styls.suspense}>
109
+ // <Text>loading ...</Text>
110
+ // </View>
111
+ // )
112
+
113
+ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, ref): React.JSX.Element => {
114
+ const {
115
+ src = '',
116
+ mode = 'scaleToFill',
117
+ // svg = false,
118
+ style = [],
119
+ 'enable-offset': enableOffset,
120
+ bindload,
121
+ binderror
122
+ } = props
123
+
124
+ const { width = DEFAULT_IMAGE_WIDTH, height = DEFAULT_IMAGE_HEIGHT } = StyleSheet.flatten(style)
125
+
126
+ const { nodeRef } = useNodesRef(props, ref, {
127
+ defaultStyle: {
128
+ width: DEFAULT_IMAGE_WIDTH,
129
+ height: DEFAULT_IMAGE_HEIGHT
130
+ }
131
+ })
132
+
133
+ const layoutRef = useRef({})
134
+ const preSrc = useRef<string | undefined>()
135
+
136
+ const resizeMode: ImageResizeMode = ModeMap.get(mode) || 'stretch'
137
+ const isWidthFixMode = mode === 'widthFix'
138
+ const isHeightFixMode = mode === 'heightFix'
139
+ const isCropMode = cropMode.includes(mode)
140
+
141
+ const source: ImageSourcePropType = typeof src === 'string' ? { uri: src } : src
142
+
143
+ const [viewWidth, setViewWidth] = useState(isNumber(width) ? (width as number) : 0)
144
+ const [viewHeight, setViewHeight] = useState(isNumber(height) ? (height as number) : 0)
145
+ const [imageWidth, setImageWidth] = useState(0)
146
+ const [imageHeight, setImageHeight] = useState(0)
147
+ const [ratio, setRatio] = useState(0)
148
+ const [loaded, setLoaded] = useState(false)
149
+
150
+ const fixedHeight = useMemo(() => {
151
+ const fixed = viewWidth * ratio
152
+ return !fixed ? viewHeight : fixed
153
+ }, [ratio, viewWidth, viewHeight])
154
+
155
+ const fixedWidth = useMemo(() => {
156
+ if (!ratio) return viewWidth
157
+ const fixed = viewHeight / ratio
158
+ return !fixed ? viewWidth : fixed
159
+ }, [ratio, viewWidth, viewHeight])
160
+
161
+ const cropModeStyle: ImageStyle = useMemo(() => {
162
+ switch (mode) {
163
+ case 'top':
164
+ return { top: 0, left: relativeCenteredSize(viewWidth, imageWidth) }
165
+ case 'bottom':
166
+ return { top: 'auto', bottom: 0, left: relativeCenteredSize(viewWidth, imageWidth) }
167
+ case 'center':
168
+ return { top: relativeCenteredSize(viewHeight, imageHeight), left: relativeCenteredSize(viewWidth, imageWidth) }
169
+ case 'left':
170
+ return { top: relativeCenteredSize(viewHeight, imageHeight), left: 0 }
171
+ case 'right':
172
+ return { top: relativeCenteredSize(viewHeight, imageHeight), left: 'auto', right: 0 }
173
+ case 'top left':
174
+ return { top: 0, left: 0 }
175
+ case 'top right':
176
+ return { top: 0, left: 'auto', right: 0 }
177
+ case 'bottom left':
178
+ return { top: 'auto', bottom: 0, left: 0 }
179
+ case 'bottom right':
180
+ return { top: 'auto', bottom: 0, left: 'auto', right: 0 }
181
+ default:
182
+ return {}
183
+ }
184
+ }, [mode, viewWidth, viewHeight, imageWidth, imageHeight])
185
+
186
+ const onImageLoad = (evt: NativeSyntheticEvent<ImageLoadEventData>) => {
187
+ if (!bindload) return
188
+ if (typeof src === 'string') {
189
+ RNImage.getSize(src, (width: number, height: number) => {
190
+ bindload(
191
+ getCustomEvent(
192
+ 'load',
193
+ evt,
194
+ {
195
+ detail: { width, height },
196
+ layoutRef
197
+ },
198
+ props
199
+ )
200
+ )
201
+ })
202
+ } else {
203
+ const { width = 0, height = 0 } = RNImage.resolveAssetSource(src) || {}
204
+ bindload(
205
+ getCustomEvent(
206
+ 'load',
207
+ evt,
208
+ {
209
+ detail: { width, height },
210
+ layoutRef
211
+ },
212
+ props
213
+ )
214
+ )
215
+ }
216
+ }
217
+
218
+ const onImageError = (evt: NativeSyntheticEvent<ImageErrorEventData>) => {
219
+ binderror &&
220
+ binderror(
221
+ getCustomEvent(
222
+ 'error',
223
+ evt,
224
+ {
225
+ detail: { errMsg: evt.nativeEvent.error },
226
+ layoutRef
227
+ },
228
+ props
229
+ )
230
+ )
231
+ }
232
+
233
+ const onViewLayout = ({
234
+ nativeEvent: {
235
+ layout: { width, height },
236
+ },
237
+ }: LayoutChangeEvent) => {
238
+ setViewWidth(width)
239
+ setViewHeight(height)
240
+ }
241
+
242
+ const onImageLayout = () => {
243
+ nodeRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
244
+ layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
245
+ })
246
+ }
247
+
248
+ useEffect(() => {
249
+ if (!isWidthFixMode && !isHeightFixMode && !isCropMode) {
250
+ setLoaded(true)
251
+ return
252
+ }
253
+
254
+ const changed = preSrc.current !== src
255
+ preSrc.current = src
256
+ changed && setLoaded(false)
257
+
258
+ if (typeof src === 'string') {
259
+ RNImage.getSize(src, (width: number, height: number) => {
260
+ if (isWidthFixMode || isHeightFixMode) {
261
+ setRatio(width === 0 ? 0 : height / width)
262
+ }
263
+ if (isCropMode) {
264
+ setImageWidth(width)
265
+ setImageHeight(height)
266
+ }
267
+ changed && setLoaded(true)
268
+ })
269
+ } else {
270
+ const { width = 0, height = 0 } = RNImage.resolveAssetSource(src) || {}
271
+ if (isWidthFixMode || isHeightFixMode) {
272
+ setRatio(width === 0 ? 0 : height / width)
273
+ }
274
+ if (isCropMode) {
275
+ setImageWidth(width)
276
+ setImageHeight(height)
277
+ }
278
+ changed && setLoaded(true)
279
+ }
280
+ }, [isWidthFixMode, isHeightFixMode, isCropMode, src])
281
+
282
+ const innerProps = useInnerProps(props, {
283
+ ref: nodeRef,
284
+ ...(enableOffset ? { onLayout: onImageLayout } : {})
285
+ },
286
+ [
287
+ 'enable-offset'
288
+ ],
289
+ {
290
+ layoutRef
291
+ }
292
+ )
293
+
294
+ // if (typeof src === 'string' && REMOTE_SVG_REGEXP.test(src)) {
295
+ // return (
296
+ // <Suspense fallback={Fallback} {...innerProps}>
297
+ // <View {...innerProps}>
298
+ // <Svg src={src} style={style} width={width as SvgNumberProp} height={height as SvgNumberProp} />
299
+ // </View>
300
+ // </Suspense>
301
+ // )
302
+ // }
303
+
304
+ // if (svg) {
305
+ // return (
306
+ // <Suspense fallback={Fallback}>
307
+ // <View {...innerProps}>
308
+ // <Svg local src={src} style={style} width={width as SvgNumberProp} height={height as SvgNumberProp} />
309
+ // </View>
310
+ // </Suspense>
311
+ // )
312
+ // }
313
+
314
+ return (
315
+ <View
316
+ style={[
317
+ { width, height },
318
+ style,
319
+ {
320
+ ...(isHeightFixMode && { width: fixedWidth }),
321
+ ...(isWidthFixMode && { height: fixedHeight }),
322
+ },
323
+ { overflow: 'hidden' },
324
+ ]}
325
+ onLayout={onViewLayout}>
326
+ {
327
+ loaded && <RNImage
328
+ {...innerProps}
329
+ source={source}
330
+ resizeMode={resizeMode}
331
+ onLoad={onImageLoad}
332
+ onError={onImageError}
333
+ style={[
334
+ StyleSheet.absoluteFill,
335
+ {
336
+ width: !isCropMode ? '100%' : imageWidth,
337
+ height: !isCropMode ? '100%' : imageHeight,
338
+ },
339
+ {
340
+ ...(isCropMode && cropModeStyle),
341
+ },
342
+ ]}
343
+ />
344
+ }
345
+ </View>
346
+ )
347
+ })
348
+
349
+ Image.displayName = 'mpx-image'
350
+
351
+ export default Image
@@ -0,0 +1,21 @@
1
+ import React from 'react'
2
+ import type { ImageSourcePropType, ImageStyle, StyleProp } from 'react-native'
3
+ import { SvgCssUri, WithLocalSvg } from 'react-native-svg/css'
4
+
5
+ interface SvgProps {
6
+ local?: boolean
7
+ src: string | ImageSourcePropType
8
+ style?: StyleProp<ImageStyle>
9
+ width?: string | number
10
+ height?: string | number
11
+ }
12
+
13
+ const Svg = ({ local = false, src, style, width, height }: SvgProps): React.JSX.Element => {
14
+ return local ? (
15
+ <WithLocalSvg style={style} asset={src as ImageSourcePropType} width={width} height={height} />
16
+ ) : (
17
+ <SvgCssUri style={style} uri={src as string} width={width} height={height} />
18
+ )
19
+ }
20
+
21
+ export default Svg