@mpxjs/webpack-plugin 2.9.69-beta.1 → 2.9.69-beta.11

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 (51) hide show
  1. package/lib/config.js +3 -1
  2. package/lib/platform/template/wx/index.js +3 -1
  3. package/lib/react/processScript.js +6 -4
  4. package/lib/runtime/components/react/context.ts +17 -0
  5. package/lib/runtime/components/react/dist/context.js +2 -0
  6. package/lib/runtime/components/react/dist/getInnerListeners.js +2 -2
  7. package/lib/runtime/components/react/dist/locale-provider.jsx +15 -0
  8. package/lib/runtime/components/react/dist/mpx-button.jsx +16 -44
  9. package/lib/runtime/components/react/dist/mpx-image.jsx +13 -9
  10. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +2 -1
  11. package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +2 -2
  12. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +65 -61
  13. package/lib/runtime/components/react/dist/mpx-portal/portal-consumer.jsx +23 -0
  14. package/lib/runtime/components/react/dist/mpx-portal/portal-host.jsx +93 -0
  15. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +40 -0
  16. package/lib/runtime/components/react/dist/mpx-portal.jsx +17 -0
  17. package/lib/runtime/components/react/dist/mpx-provider.jsx +31 -0
  18. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +5 -3
  19. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +9 -5
  20. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +13 -7
  21. package/lib/runtime/components/react/dist/mpx-swiper.jsx +384 -321
  22. package/lib/runtime/components/react/dist/mpx-view.jsx +16 -20
  23. package/lib/runtime/components/react/dist/mpx-web-view.jsx +129 -53
  24. package/lib/runtime/components/react/dist/pickerFaces.js +2 -7
  25. package/lib/runtime/components/react/dist/useAnimationHooks.js +30 -13
  26. package/lib/runtime/components/react/dist/utils.jsx +60 -2
  27. package/lib/runtime/components/react/getInnerListeners.ts +2 -2
  28. package/lib/runtime/components/react/locale-provider.tsx +83 -0
  29. package/lib/runtime/components/react/mpx-button.tsx +20 -57
  30. package/lib/runtime/components/react/mpx-image.tsx +41 -25
  31. package/lib/runtime/components/react/mpx-picker/time.tsx +2 -1
  32. package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +3 -3
  33. package/lib/runtime/components/react/mpx-picker-view-column.tsx +70 -69
  34. package/lib/runtime/components/react/mpx-portal/portal-consumer.tsx +32 -0
  35. package/lib/runtime/components/react/mpx-portal/portal-host.tsx +127 -0
  36. package/lib/runtime/components/react/mpx-portal/portal-manager.tsx +64 -0
  37. package/lib/runtime/components/react/mpx-portal.tsx +35 -0
  38. package/lib/runtime/components/react/mpx-provider.tsx +51 -0
  39. package/lib/runtime/components/react/mpx-root-portal.tsx +5 -3
  40. package/lib/runtime/components/react/mpx-scroll-view.tsx +10 -8
  41. package/lib/runtime/components/react/mpx-swiper-item.tsx +13 -7
  42. package/lib/runtime/components/react/mpx-swiper.tsx +378 -325
  43. package/lib/runtime/components/react/mpx-view.tsx +19 -22
  44. package/lib/runtime/components/react/mpx-web-view.tsx +170 -62
  45. package/lib/runtime/components/react/pickerFaces.ts +2 -7
  46. package/lib/runtime/components/react/types/global.d.ts +7 -0
  47. package/lib/runtime/components/react/useAnimationHooks.ts +34 -14
  48. package/lib/runtime/components/react/utils.tsx +67 -2
  49. package/lib/template-compiler/compiler.js +1 -1
  50. package/lib/wxss/loader.js +15 -2
  51. package/package.json +1 -1
@@ -0,0 +1,127 @@
1
+ import { useEffect, useRef, ReactNode } from 'react'
2
+ import {
3
+ View,
4
+ DeviceEventEmitter,
5
+ EventSubscription,
6
+ NativeEventEmitter,
7
+ StyleSheet
8
+ } from 'react-native'
9
+ import PortalManager from './portal-manager'
10
+ import { getFocusedNavigation } from '@mpxjs/utils'
11
+ import { PortalManagerContextValue, PortalContext } from '../context'
12
+
13
+ export type PortalHostProps = {
14
+ children: ReactNode
15
+ }
16
+
17
+ type addIdsMapsType = {
18
+ [key: number]: number[]
19
+ }
20
+
21
+ export type Operation =
22
+ | { type: 'mount'; key: number; children: ReactNode }
23
+ | { type: 'update'; key: number; children: ReactNode }
24
+ | { type: 'unmount'; key: number }
25
+
26
+ // events
27
+ const addType = 'MPX_RN_ADD_PORTAL'
28
+ const removeType = 'MPX_RN_REMOVE_PORTAL'
29
+ const updateType = 'MPX_RN_UPDATE_PORTAL'
30
+ // fix react native web does not support DeviceEventEmitter
31
+ const TopViewEventEmitter = DeviceEventEmitter || new NativeEventEmitter()
32
+
33
+ const styles = StyleSheet.create({
34
+ container: {
35
+ flex: 1
36
+ }
37
+ })
38
+
39
+ class PortalGuard {
40
+ private nextKey = 10000
41
+ add = (e: ReactNode) => {
42
+ const key = this.nextKey++
43
+ TopViewEventEmitter.emit(addType, e, key)
44
+ return key
45
+ }
46
+
47
+ remove = (key: number) => {
48
+ TopViewEventEmitter.emit(removeType, key)
49
+ }
50
+
51
+ update = (key: number, e: ReactNode) => {
52
+ TopViewEventEmitter.emit(updateType, key, e)
53
+ }
54
+ }
55
+ /**
56
+ * portal
57
+ */
58
+ export const portal = new PortalGuard()
59
+
60
+ const PortalHost = ({ children } :PortalHostProps): JSX.Element => {
61
+ const _nextKey = useRef(0)
62
+ const _queue = useRef<Operation[]>([])
63
+ const _addType = useRef<EventSubscription | null>(null)
64
+ const _removeType = useRef<EventSubscription | null>(null)
65
+ const _updateType = useRef<EventSubscription | null>(null)
66
+ const manager = useRef<PortalManagerContextValue | null>(null)
67
+ let currentPageId: number | undefined
68
+ const _mount = (children: ReactNode, _key?: number, curPageId?: number) => {
69
+ const navigation = getFocusedNavigation()
70
+ const pageId = navigation?.pageId
71
+ if (pageId !== (curPageId ?? currentPageId)) {
72
+ return
73
+ }
74
+ const key = _key || _nextKey.current++
75
+ if (manager.current) {
76
+ manager.current.mount(key, children)
77
+ }
78
+ return key
79
+ }
80
+
81
+ const _unmount = (key: number) => {
82
+ if (manager.current) {
83
+ manager.current.unmount(key)
84
+ }
85
+ }
86
+
87
+ const _update = (key: number, children?: ReactNode, curPageId?: number) => {
88
+ const navigation = getFocusedNavigation()
89
+ const pageId = navigation?.pageId
90
+ if (pageId !== (curPageId ?? currentPageId)) {
91
+ return
92
+ }
93
+ if (manager.current) {
94
+ manager.current.update(key, children)
95
+ }
96
+ }
97
+
98
+ useEffect(() => {
99
+ const navigation = getFocusedNavigation()
100
+ currentPageId = navigation?.pageId
101
+ _addType.current = TopViewEventEmitter.addListener(addType, _mount)
102
+ _removeType.current = TopViewEventEmitter.addListener(removeType, _unmount)
103
+ _updateType.current = TopViewEventEmitter.addListener(updateType, _update)
104
+
105
+ return () => {
106
+ _addType.current?.remove()
107
+ _removeType.current?.remove()
108
+ _updateType.current?.remove()
109
+ }
110
+ }, [])
111
+ return (
112
+ <PortalContext.Provider
113
+ value={{
114
+ mount: _mount,
115
+ update: _update,
116
+ unmount: _unmount
117
+ }}
118
+ >
119
+ <View style={styles.container} collapsable={false}>
120
+ {children}
121
+ </View>
122
+ <PortalManager ref={manager} />
123
+ </PortalContext.Provider>
124
+ )
125
+ }
126
+
127
+ export default PortalHost
@@ -0,0 +1,64 @@
1
+ import { useState, useCallback, forwardRef, ForwardedRef, useImperativeHandle, ReactNode, ReactElement } from 'react'
2
+ import { View, StyleSheet } from 'react-native'
3
+
4
+ export type State = {
5
+ portals: Array<{
6
+ key: number
7
+ children: ReactNode
8
+ }>
9
+ }
10
+
11
+ type PortalManagerProps = {
12
+ }
13
+
14
+ const _PortalManager = forwardRef((props: PortalManagerProps, ref:ForwardedRef<unknown>): ReactElement => {
15
+ const [state, setState] = useState<State>({
16
+ portals: []
17
+ })
18
+
19
+ const mount = useCallback((key: number, children: ReactNode) => {
20
+ setState((prevState) => ({
21
+ portals: [...prevState.portals, { key, children }]
22
+ }))
23
+ }, [state])
24
+
25
+ const update = useCallback((key: number, children: ReactNode) => {
26
+ setState((prevState) => ({
27
+ portals: prevState.portals.map((item) => {
28
+ if (item.key === key) {
29
+ return { ...item, children }
30
+ }
31
+ return item
32
+ })
33
+ }))
34
+ }, [state])
35
+
36
+ const unmount = useCallback((key: number) => {
37
+ setState((prevState) => ({
38
+ portals: prevState.portals.filter((item) => item.key !== key)
39
+ }))
40
+ }, [])
41
+
42
+ useImperativeHandle(ref, () => ({
43
+ mount,
44
+ update,
45
+ unmount,
46
+ portals: state.portals
47
+ }))
48
+
49
+ return (
50
+ <>
51
+ {state.portals.map(({ key, children }, i) => (
52
+ <View
53
+ key={key}
54
+ collapsable={false} // Need collapsable=false here to clip the elevations
55
+ pointerEvents="box-none"
56
+ style={[StyleSheet.absoluteFill, { zIndex: 1000 + i }]}>
57
+ {children}
58
+ </View>
59
+ ))}
60
+ </>
61
+ )
62
+ })
63
+
64
+ export default _PortalManager
@@ -0,0 +1,35 @@
1
+ import { ReactNode } from 'react'
2
+ import { PortalContext, PortalContextValue, VarContext } from './context'
3
+ import PortalConsumer from './mpx-portal/portal-consumer'
4
+ import PortalHost, { portal } from './mpx-portal/portal-host'
5
+
6
+ export type PortalProps = {
7
+ /**
8
+ * Content of the `Portal`.
9
+ */
10
+ children?: ReactNode
11
+ key?: string
12
+ manager?: PortalContextValue,
13
+ varContext?: Record<string, any> | undefined
14
+ }
15
+
16
+ const Portal = ({ children, varContext }:PortalProps): JSX.Element => {
17
+ const hasVarContext = varContext && Object.keys(varContext).length
18
+ if (hasVarContext) {
19
+ children = (<VarContext.Provider value={varContext} key='varContextWrap'>{children}</VarContext.Provider>)
20
+ }
21
+ return (
22
+ <PortalContext.Consumer>
23
+ {(manager) => (
24
+ <PortalConsumer manager={manager}>{children}</PortalConsumer>
25
+ )}
26
+ </PortalContext.Consumer>
27
+ )
28
+ }
29
+
30
+ Portal.Host = PortalHost
31
+ Portal.add = portal.add
32
+ Portal.remove = portal.remove
33
+ Portal.update = portal.update
34
+
35
+ export default Portal
@@ -0,0 +1,51 @@
1
+ import { ReactNode, createContext, useMemo } from 'react'
2
+ import LocaleProvider, { LocaleContextProps } from './locale-provider'
3
+ import Portal from './mpx-portal'
4
+ import { extendObject } from './utils'
5
+
6
+ export type Theme = typeof defaultTheme & { [key: string]: any }
7
+
8
+ export interface ProviderProps {
9
+ locale?: LocaleContextProps
10
+ theme?: Partial<Theme>
11
+ children: ReactNode
12
+ }
13
+ const defaultTheme = {
14
+ color_text_base: '#000000', // 基本
15
+ color_text_base_inverse: '#ffffff', // 基本 _ 反色
16
+ color_text_secondary: '#a4a9b0', // 辅助色
17
+ color_text_placeholder: '#bbbbbb', // 文本框提示
18
+ color_text_disabled: '#bbbbbb', // 失效
19
+ color_text_caption: '#888888', // 辅助描述
20
+ color_text_paragraph: '#333333', // 段落
21
+ color_error: '#ff4d4f', // 错误(form validate)
22
+ color_warning: '#faad14', // 警告
23
+ color_success: '#52c41a',
24
+ color_primary: '#1677ff'
25
+ }
26
+ export const ThemeContext = createContext(defaultTheme)
27
+
28
+ export type PartialTheme = Partial<Theme>
29
+
30
+ export interface ThemeProviderProps {
31
+ value?: PartialTheme
32
+ children?: React.ReactNode
33
+ }
34
+
35
+ const ThemeProvider = (props: ThemeProviderProps) => {
36
+ const { value, children } = props
37
+ const theme = useMemo(() => (extendObject({}, defaultTheme, value)), [value])
38
+ return <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
39
+ }
40
+
41
+ const Provider = ({ locale, theme, children }:ProviderProps): JSX.Element => {
42
+ return (
43
+ <LocaleProvider locale={locale}>
44
+ <ThemeProvider value={theme}>
45
+ <Portal.Host>{children}</Portal.Host>
46
+ </ThemeProvider>
47
+ </LocaleProvider>
48
+ )
49
+ }
50
+
51
+ export default Provider
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * ✔ enable
3
3
  */
4
- import { ReactNode, createElement, Fragment } from 'react'
5
- import { Portal } from '@ant-design/react-native'
4
+ import { ReactNode, createElement, Fragment, useContext } from 'react'
5
+ import Portal from './mpx-portal'
6
6
  import { warn } from '@mpxjs/utils'
7
+ import { VarContext } from './context'
7
8
  interface RootPortalProps {
8
9
  enable?: boolean
9
10
  children: ReactNode
@@ -15,8 +16,9 @@ const _RootPortal = (props: RootPortalProps) => {
15
16
  if (props.style) {
16
17
  warn('The root-portal component does not support the style prop.')
17
18
  }
19
+ const varContext = useContext(VarContext)
18
20
  return enable
19
- ? createElement(Portal, null, children)
21
+ ? createElement(Portal, { varContext }, children)
20
22
  : createElement(Fragment, null, children)
21
23
  }
22
24
 
@@ -32,7 +32,7 @@
32
32
  * ✔ bindscroll
33
33
  */
34
34
  import { ScrollView } from 'react-native-gesture-handler'
35
- import { View, RefreshControl, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent, ViewStyle } from 'react-native'
35
+ import { View, RefreshControl, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent, ViewStyle, Platform } from 'react-native'
36
36
  import { JSX, ReactNode, RefObject, useRef, useState, useEffect, forwardRef, useContext, createElement, useMemo } from 'react'
37
37
  import { useAnimatedRef } from 'react-native-reanimated'
38
38
  import { warn } from '@mpxjs/utils'
@@ -40,7 +40,6 @@ import useInnerProps, { getCustomEvent } from './getInnerListeners'
40
40
  import useNodesRef, { HandlerRef } from './useNodesRef'
41
41
  import { splitProps, splitStyle, useTransformStyle, useLayout, wrapChildren, extendObject, flatGesture, GestureHandler } from './utils'
42
42
  import { IntersectionObserverContext, ScrollViewContext } from './context'
43
-
44
43
  interface ScrollViewProps {
45
44
  children?: ReactNode;
46
45
  enhanced?: boolean;
@@ -338,11 +337,6 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
338
337
  }, props)
339
338
  )
340
339
  updateScrollOptions(e, { scrollLeft, scrollTop })
341
- if (enableTriggerIntersectionObserver && intersectionObservers) {
342
- for (const key in intersectionObservers) {
343
- intersectionObservers[key].throttleMeasure()
344
- }
345
- }
346
340
  }
347
341
 
348
342
  function onScrollEnd (e: NativeSyntheticEvent<NativeScrollEvent>) {
@@ -364,8 +358,15 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
364
358
  updateScrollOptions(e, { scrollLeft, scrollTop })
365
359
  onStartReached(e)
366
360
  onEndReached(e)
361
+ updateIntersection()
362
+ }
363
+ function updateIntersection () {
364
+ if (enableTriggerIntersectionObserver && intersectionObservers) {
365
+ for (const key in intersectionObservers) {
366
+ intersectionObservers[key].throttleMeasure();
367
+ }
368
+ }
367
369
  }
368
-
369
370
  function scrollToOffset (x = 0, y = 0) {
370
371
  if (scrollViewRef.current) {
371
372
  scrollViewRef.current.scrollTo({ x, y, animated: !!scrollWithAnimation })
@@ -435,6 +436,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
435
436
  function onScrollDrag (e: NativeSyntheticEvent<NativeScrollEvent>) {
436
437
  const { x: scrollLeft, y: scrollTop } = e.nativeEvent.contentOffset
437
438
  updateScrollOptions(e, { scrollLeft, scrollTop })
439
+ updateIntersection()
438
440
  }
439
441
 
440
442
  const scrollAdditionalProps: ScrollAdditionalProps = extendObject(
@@ -16,7 +16,7 @@ interface SwiperItemProps {
16
16
  'parent-height'?: number;
17
17
  children?: ReactNode;
18
18
  style?: Object;
19
- customStyle: [];
19
+ customStyle: Object;
20
20
  itemIndex: number;
21
21
  }
22
22
 
@@ -24,6 +24,7 @@ interface ContextType {
24
24
  offset: SharedValue<number>;
25
25
  step: SharedValue<number>;
26
26
  scale: boolean;
27
+ dir: string;
27
28
  }
28
29
 
29
30
  const _SwiperItem = forwardRef<HandlerRef<View, SwiperItemProps>, SwiperItemProps>((props: SwiperItemProps, ref) => {
@@ -39,6 +40,7 @@ const _SwiperItem = forwardRef<HandlerRef<View, SwiperItemProps>, SwiperItemProp
39
40
  const offset = contextValue.offset || 0
40
41
  const step = contextValue.step || 0
41
42
  const scale = contextValue.scale || false
43
+ const dir = contextValue.dir || 'x'
42
44
  const { textProps } = splitProps(props)
43
45
  const nodeRef = useRef(null)
44
46
 
@@ -70,22 +72,26 @@ const _SwiperItem = forwardRef<HandlerRef<View, SwiperItemProps>, SwiperItemProp
70
72
  'enable-offset',
71
73
  'style'
72
74
  ], { layoutRef })
73
-
74
75
  const itemAnimatedStyle = useAnimatedStyle(() => {
75
76
  if (!step.value) return {}
76
77
  const inputRange = [step.value, 0]
77
78
  const outputRange = [0.7, 1]
78
- return {
79
- transform: [{
79
+ // 实现元素的宽度跟随step从0到真实宽度,且不能触发重新渲染整个组件,通过AnimatedStyle的方式实现
80
+ const outerLayoutStyle = dir === 'x' ? { width: step.value, height: '100%' } : { width: '100%', height: step.value }
81
+ const transformStyle = []
82
+ if (scale) {
83
+ transformStyle.push({
80
84
  scale: interpolate(Math.abs(Math.abs(offset.value) - itemIndex * step.value), inputRange, outputRange)
81
- }]
85
+ })
82
86
  }
87
+ return Object.assign(outerLayoutStyle, {
88
+ transform: transformStyle
89
+ })
83
90
  })
84
- const mergeStyle = [innerStyle, layoutStyle, { width: '100%', height: '100%' }, scale ? itemAnimatedStyle : {}].concat(customStyle)
85
91
  return (
86
92
  <Animated.View
87
93
  {...innerProps}
88
- style={mergeStyle}
94
+ style={[innerStyle, layoutStyle, itemAnimatedStyle, customStyle]}
89
95
  data-itemId={props['item-id']}>
90
96
  {
91
97
  wrapChildren(