@mpxjs/webpack-plugin 2.9.70-alpha.0 → 2.9.71
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.
- package/LICENSE +433 -0
- package/README.md +1 -1
- package/lib/config.js +0 -14
- package/lib/dependencies/ResolveDependency.js +0 -5
- package/lib/index.js +7 -38
- package/lib/json-compiler/helper.js +3 -3
- package/lib/loader.js +0 -53
- package/lib/parser.js +1 -1
- package/lib/platform/json/wx/index.js +21 -8
- package/lib/platform/style/wx/index.js +51 -54
- package/lib/platform/template/wx/component-config/button.js +2 -14
- package/lib/platform/template/wx/component-config/fix-component-name.js +15 -12
- package/lib/platform/template/wx/component-config/image.js +0 -4
- package/lib/platform/template/wx/component-config/index.js +1 -1
- package/lib/platform/template/wx/component-config/input.js +0 -4
- package/lib/platform/template/wx/component-config/movable-view.js +8 -1
- package/lib/platform/template/wx/component-config/picker-view.js +1 -5
- package/lib/platform/template/wx/component-config/rich-text.js +6 -2
- package/lib/platform/template/wx/component-config/scroll-view.js +1 -5
- package/lib/platform/template/wx/component-config/switch.js +0 -4
- package/lib/platform/template/wx/component-config/text.js +0 -4
- package/lib/platform/template/wx/component-config/textarea.js +0 -5
- package/lib/platform/template/wx/component-config/unsupported.js +1 -1
- package/lib/platform/template/wx/component-config/view.js +0 -4
- package/lib/platform/template/wx/index.js +1 -131
- package/lib/resolve-loader.js +1 -4
- package/lib/runtime/components/react/context.ts +8 -0
- package/lib/runtime/components/react/dist/context.js +2 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +39 -37
- package/lib/runtime/components/react/dist/mpx-button.jsx +16 -44
- package/lib/runtime/components/react/dist/mpx-canvas/html.js +2 -4
- package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +5 -1
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +93 -58
- package/lib/runtime/components/react/dist/mpx-navigator.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +10 -14
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +94 -81
- package/lib/runtime/components/react/dist/mpx-picker-view.jsx +19 -16
- package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +10 -11
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +11 -4
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +31 -8
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +435 -371
- package/lib/runtime/components/react/dist/mpx-view.jsx +18 -53
- package/lib/runtime/components/react/dist/pickerFaces.js +3 -8
- package/lib/runtime/components/react/dist/pickerVIewContext.js +5 -0
- package/lib/runtime/components/react/dist/{pickerViewOverlay.jsx → pickerViewIndicator.jsx} +6 -6
- package/lib/runtime/components/react/dist/pickerViewMask.jsx +2 -2
- package/lib/runtime/components/react/dist/useAnimationHooks.js +27 -10
- package/lib/runtime/components/react/dist/utils.jsx +162 -70
- package/lib/runtime/components/react/event.config.ts +25 -26
- package/lib/runtime/components/react/getInnerListeners.ts +236 -182
- package/lib/runtime/components/react/mpx-button.tsx +27 -69
- package/lib/runtime/components/react/mpx-canvas/html.ts +2 -4
- package/lib/runtime/components/react/mpx-canvas/index.tsx +44 -46
- package/lib/runtime/components/react/mpx-checkbox-group.tsx +15 -13
- package/lib/runtime/components/react/mpx-checkbox.tsx +20 -21
- package/lib/runtime/components/react/mpx-form.tsx +15 -20
- package/lib/runtime/components/react/mpx-icon.tsx +2 -2
- package/lib/runtime/components/react/mpx-image.tsx +87 -47
- package/lib/runtime/components/react/mpx-input.tsx +24 -32
- package/lib/runtime/components/react/mpx-label.tsx +12 -14
- package/lib/runtime/components/react/mpx-movable-area.tsx +10 -16
- package/lib/runtime/components/react/mpx-movable-view.tsx +133 -92
- package/lib/runtime/components/react/mpx-navigator.tsx +3 -9
- package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +76 -0
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +206 -183
- package/lib/runtime/components/react/mpx-picker-view.tsx +49 -48
- package/lib/runtime/components/react/mpx-radio-group.tsx +13 -15
- package/lib/runtime/components/react/mpx-radio.tsx +19 -25
- package/lib/runtime/components/react/mpx-rich-text/html.ts +40 -0
- package/lib/runtime/components/react/mpx-rich-text/index.tsx +115 -0
- package/lib/runtime/components/react/mpx-root-portal.tsx +3 -5
- package/lib/runtime/components/react/mpx-scroll-view.tsx +53 -43
- package/lib/runtime/components/react/mpx-swiper-item.tsx +45 -11
- package/lib/runtime/components/react/mpx-swiper.tsx +742 -0
- package/lib/runtime/components/react/mpx-switch.tsx +19 -15
- package/lib/runtime/components/react/mpx-text.tsx +8 -16
- package/lib/runtime/components/react/mpx-textarea.tsx +11 -10
- package/lib/runtime/components/react/mpx-view.tsx +28 -77
- package/lib/runtime/components/react/mpx-web-view.tsx +94 -59
- package/lib/runtime/components/react/pickerFaces.ts +10 -7
- package/lib/runtime/components/react/pickerVIewContext.ts +27 -0
- package/lib/runtime/components/react/pickerViewIndicator.tsx +34 -0
- package/lib/runtime/components/react/pickerViewMask.tsx +30 -0
- package/lib/runtime/components/react/types/{getInnerListeners.ts → getInnerListeners.d.ts} +4 -5
- package/lib/runtime/components/react/types/global.d.ts +12 -1
- package/lib/runtime/components/react/useAnimationHooks.ts +60 -15
- package/lib/runtime/components/react/utils.tsx +175 -71
- package/lib/runtime/components/web/mpx-checkbox.vue +1 -1
- package/lib/runtime/components/web/mpx-picker-view-column.vue +9 -4
- package/lib/runtime/components/web/mpx-web-view.vue +34 -20
- package/lib/runtime/optionProcessor.js +0 -22
- package/lib/style-compiler/index.js +1 -1
- package/lib/style-compiler/plugins/scope-id.js +30 -2
- package/lib/template-compiler/compiler.js +91 -39
- package/lib/utils/env.js +1 -6
- package/lib/utils/pre-process-json.js +9 -5
- package/lib/wxss/loader.js +15 -2
- package/package.json +4 -7
- package/lib/dependencies/AddEntryDependency.js +0 -24
- package/lib/runtime/components/react/dist/types/common.js +0 -1
- package/lib/runtime/components/react/dist/types/getInnerListeners.js +0 -1
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +0 -527
- package/lib/runtime/components/react/mpx-swiper/index.tsx +0 -80
- package/lib/runtime/components/react/mpx-swiper/type.ts +0 -87
- package/lib/runtime/components/react/pickerOverlay.tsx +0 -32
- package/lib/runtime/components/tenon/getInnerListeners.js +0 -334
- package/lib/runtime/components/tenon/tenon-button.vue +0 -309
- package/lib/runtime/components/tenon/tenon-image.vue +0 -66
- package/lib/runtime/components/tenon/tenon-input.vue +0 -171
- package/lib/runtime/components/tenon/tenon-rich-text.vue +0 -26
- package/lib/runtime/components/tenon/tenon-scroll-view.vue +0 -127
- package/lib/runtime/components/tenon/tenon-switch.vue +0 -96
- package/lib/runtime/components/tenon/tenon-text.vue +0 -70
- package/lib/runtime/components/tenon/tenon-textarea.vue +0 -86
- package/lib/runtime/components/tenon/tenon-view.vue +0 -93
- package/lib/runtime/components/web/event.js +0 -105
- package/lib/runtime/optionProcessor.tenon.js +0 -84
- package/lib/style-compiler/plugins/hm.js +0 -20
- package/lib/tenon/index.js +0 -117
- package/lib/tenon/processJSON.js +0 -352
- package/lib/tenon/processScript.js +0 -203
- package/lib/tenon/processStyles.js +0 -21
- package/lib/tenon/processTemplate.js +0 -126
- package/lib/tenon/script-helper.js +0 -223
- package/lib/utils/get-relative-path.js +0 -25
- /package/lib/runtime/components/react/types/{common.ts → common.d.ts} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { View } from 'react-native'
|
|
2
|
-
import React, { forwardRef,
|
|
2
|
+
import React, { forwardRef, useRef } from 'react'
|
|
3
3
|
import useInnerProps, { getCustomEvent } from './getInnerListeners'
|
|
4
4
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
5
5
|
import {
|
|
@@ -7,35 +7,33 @@ import {
|
|
|
7
7
|
splitProps,
|
|
8
8
|
splitStyle,
|
|
9
9
|
wrapChildren,
|
|
10
|
-
parseInlineStyle,
|
|
11
10
|
useTransformStyle,
|
|
12
|
-
useDebounceCallback,
|
|
13
|
-
useStableCallback,
|
|
14
11
|
extendObject
|
|
15
12
|
} from './utils'
|
|
13
|
+
import { PickerViewStyleContext } from './pickerVIewContext'
|
|
16
14
|
import type { AnyFunc } from './types/common'
|
|
17
15
|
/**
|
|
18
16
|
* ✔ value
|
|
19
17
|
* ✔ bindchange
|
|
20
18
|
* ✘ bindpickstart
|
|
21
19
|
* ✘ bindpickend
|
|
22
|
-
*
|
|
20
|
+
* ✔ mask-class
|
|
23
21
|
* ✔ indicator-style: 优先级indicator-style.height > pick-view-column中的子元素设置的height
|
|
24
|
-
*
|
|
25
|
-
*
|
|
22
|
+
* WebView Only:
|
|
23
|
+
* ✔ indicator-class
|
|
24
|
+
* ✔ mask-style
|
|
26
25
|
* ✘ immediate-change
|
|
27
26
|
*/
|
|
28
27
|
|
|
29
28
|
interface PickerViewProps {
|
|
30
29
|
children: React.ReactNode
|
|
31
|
-
// 初始的defaultValue数组中的数字依次表示 picker-view 内的 picker-view-column 选择的第几项(下标从 0 开始),
|
|
32
|
-
// 数字大于 picker-view-column 可选项长度时,选择最后一项。
|
|
33
30
|
value?: Array<number>
|
|
34
31
|
bindchange?: AnyFunc
|
|
35
32
|
style: {
|
|
36
33
|
[key: string]: any
|
|
37
34
|
}
|
|
38
|
-
'indicator-style'?: string
|
|
35
|
+
'indicator-style'?: Record<string, any>,
|
|
36
|
+
'mask-style'?: Record<string, any>,
|
|
39
37
|
'enable-var': boolean
|
|
40
38
|
'external-var-context'?: Record<string, any>,
|
|
41
39
|
'enable-offset': boolean
|
|
@@ -62,25 +60,25 @@ const styles: { [key: string]: Object } = {
|
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
62
|
|
|
63
|
+
const DefaultPickerItemH = 36
|
|
64
|
+
|
|
65
65
|
const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProps>((props: PickerViewProps, ref) => {
|
|
66
66
|
const {
|
|
67
67
|
children,
|
|
68
68
|
value = [],
|
|
69
69
|
bindchange,
|
|
70
70
|
style,
|
|
71
|
+
'indicator-style': indicatorStyle = {},
|
|
72
|
+
'mask-style': pickerMaskStyle = {},
|
|
71
73
|
'enable-var': enableVar,
|
|
72
74
|
'external-var-context': externalVarContext
|
|
73
75
|
} = props
|
|
74
|
-
|
|
75
|
-
// indicatorStyle 需要转换为rn的style
|
|
76
|
-
// 微信设置到pick-view上上设置的normalStyle如border等需要转换成RN的style然后进行透传
|
|
77
|
-
const indicatorStyle = parseInlineStyle(props['indicator-style'])
|
|
78
|
-
const { height: indicatorH, ...pickerOverlayStyle } = indicatorStyle
|
|
79
|
-
const [pickMaxH, setPickMaxH] = useState(0)
|
|
76
|
+
const { height: indicatorH, ...pickerIndicatorStyle } = indicatorStyle
|
|
80
77
|
const nodeRef = useRef(null)
|
|
81
78
|
const cloneRef = useRef(null)
|
|
82
79
|
const activeValueRef = useRef(value)
|
|
83
80
|
activeValueRef.current = value.slice()
|
|
81
|
+
const snapActiveValueRef = useRef<number[] | null>(null)
|
|
84
82
|
|
|
85
83
|
const {
|
|
86
84
|
normalStyle,
|
|
@@ -96,7 +94,6 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
|
|
|
96
94
|
})
|
|
97
95
|
|
|
98
96
|
const {
|
|
99
|
-
// 存储layout布局信息
|
|
100
97
|
layoutRef,
|
|
101
98
|
layoutProps,
|
|
102
99
|
layoutStyle
|
|
@@ -104,33 +101,32 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
|
|
|
104
101
|
const { textProps } = splitProps(props)
|
|
105
102
|
const { textStyle } = splitStyle(normalStyle)
|
|
106
103
|
|
|
107
|
-
const onColumnItemRawHChange = (height: number) => {
|
|
108
|
-
if (height > pickMaxH) {
|
|
109
|
-
setPickMaxH(height)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const bindchangeDebounce = useDebounceCallback(useStableCallback(bindchange), 300)
|
|
114
|
-
|
|
115
104
|
const onSelectChange = (columnIndex: number, selectedIndex: number) => {
|
|
116
|
-
bindchangeDebounce.clear()
|
|
117
105
|
const activeValue = activeValueRef.current
|
|
118
106
|
activeValue[columnIndex] = selectedIndex
|
|
119
107
|
const eventData = getCustomEvent(
|
|
120
108
|
'change',
|
|
121
109
|
{},
|
|
122
|
-
{ detail: { value: activeValue, source: 'change' }, layoutRef }
|
|
110
|
+
{ detail: { value: activeValue.slice(), source: 'change' }, layoutRef }
|
|
123
111
|
)
|
|
124
|
-
|
|
112
|
+
bindchange?.(eventData)
|
|
113
|
+
snapActiveValueRef.current = activeValueRef.current
|
|
125
114
|
}
|
|
126
115
|
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
)
|
|
133
|
-
|
|
116
|
+
const hasDiff = (a: number[] = [], b: number[]) => {
|
|
117
|
+
return a.some((v, i) => v !== b[i])
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const onInitialChange = (isInvalid: boolean, value: number[]) => {
|
|
121
|
+
if (isInvalid || !snapActiveValueRef.current || hasDiff(snapActiveValueRef.current, value)) {
|
|
122
|
+
const eventData = getCustomEvent(
|
|
123
|
+
'change',
|
|
124
|
+
{},
|
|
125
|
+
{ detail: { value: value.slice(), source: 'change' }, layoutRef }
|
|
126
|
+
)
|
|
127
|
+
bindchange?.(eventData)
|
|
128
|
+
snapActiveValueRef.current = value.slice()
|
|
129
|
+
}
|
|
134
130
|
}
|
|
135
131
|
|
|
136
132
|
const innerProps = useInnerProps(
|
|
@@ -148,12 +144,17 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
|
|
|
148
144
|
),
|
|
149
145
|
layoutProps
|
|
150
146
|
}),
|
|
151
|
-
[
|
|
147
|
+
[
|
|
148
|
+
'enable-offset',
|
|
149
|
+
'indicator-style',
|
|
150
|
+
'indicator-class',
|
|
151
|
+
'mask-style',
|
|
152
|
+
'mask-class'
|
|
153
|
+
],
|
|
152
154
|
{ layoutRef }
|
|
153
155
|
)
|
|
154
156
|
|
|
155
157
|
const renderColumn = (child: React.ReactElement, index: number, columnData: React.ReactNode[], initialIndex: number) => {
|
|
156
|
-
const extraProps = {}
|
|
157
158
|
const childProps = child?.props || {}
|
|
158
159
|
const wrappedProps = extendObject(
|
|
159
160
|
{},
|
|
@@ -164,15 +165,14 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
|
|
|
164
165
|
columnIndex: index,
|
|
165
166
|
key: `pick-view-${index}`,
|
|
166
167
|
wrapperStyle: {
|
|
167
|
-
height: normalStyle?.height ||
|
|
168
|
-
itemHeight: indicatorH ||
|
|
168
|
+
height: normalStyle?.height || DefaultPickerItemH,
|
|
169
|
+
itemHeight: indicatorH || DefaultPickerItemH
|
|
169
170
|
},
|
|
170
|
-
onColumnItemRawHChange,
|
|
171
171
|
onSelectChange: onSelectChange.bind(null, index),
|
|
172
172
|
initialIndex,
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
pickerIndicatorStyle,
|
|
174
|
+
pickerMaskStyle
|
|
175
|
+
}
|
|
176
176
|
)
|
|
177
177
|
const realElement = React.cloneElement(child, wrappedProps)
|
|
178
178
|
return wrapChildren(
|
|
@@ -215,17 +215,18 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
|
|
|
215
215
|
validValue.push(validIndex)
|
|
216
216
|
renderColumns.push(renderColumn(item, index, columnData, validIndex))
|
|
217
217
|
})
|
|
218
|
-
isInvalid
|
|
218
|
+
onInitialChange(isInvalid, validValue)
|
|
219
219
|
return renderColumns
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
return (
|
|
223
|
-
<
|
|
224
|
-
<View
|
|
225
|
-
|
|
223
|
+
<PickerViewStyleContext.Provider value={textStyle}>
|
|
224
|
+
<View {...innerProps}>
|
|
225
|
+
<View style={[styles.wrapper]}>{renderPickerColumns()}</View>
|
|
226
|
+
</View>
|
|
227
|
+
</PickerViewStyleContext.Provider>
|
|
226
228
|
)
|
|
227
229
|
})
|
|
228
230
|
|
|
229
231
|
_PickerView.displayName = 'MpxPickerView'
|
|
230
|
-
|
|
231
232
|
export default _PickerView
|
|
@@ -8,7 +8,8 @@ import {
|
|
|
8
8
|
ReactNode,
|
|
9
9
|
useContext,
|
|
10
10
|
useMemo,
|
|
11
|
-
useEffect
|
|
11
|
+
useEffect,
|
|
12
|
+
createElement
|
|
12
13
|
} from 'react'
|
|
13
14
|
import {
|
|
14
15
|
View,
|
|
@@ -154,20 +155,17 @@ const radioGroup = forwardRef<
|
|
|
154
155
|
}
|
|
155
156
|
)
|
|
156
157
|
|
|
157
|
-
return (
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
</RadioGroupContext.Provider>
|
|
170
|
-
</View>
|
|
158
|
+
return createElement(View, innerProps, createElement(
|
|
159
|
+
RadioGroupContext.Provider,
|
|
160
|
+
{ value: contextValue },
|
|
161
|
+
wrapChildren(
|
|
162
|
+
props,
|
|
163
|
+
{
|
|
164
|
+
hasVarDec,
|
|
165
|
+
varContext: varContextRef.current
|
|
166
|
+
}
|
|
167
|
+
)
|
|
168
|
+
)
|
|
171
169
|
)
|
|
172
170
|
})
|
|
173
171
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* ✔ checked
|
|
5
5
|
* ✔ color
|
|
6
6
|
*/
|
|
7
|
-
import { JSX, useRef, useState, forwardRef, useEffect, ReactNode, useContext, Dispatch, SetStateAction } from 'react'
|
|
7
|
+
import { JSX, useRef, useState, forwardRef, useEffect, ReactNode, useContext, Dispatch, SetStateAction, createElement } from 'react'
|
|
8
8
|
import { View, StyleSheet, ViewStyle, NativeSyntheticEvent } from 'react-native'
|
|
9
9
|
import { warn } from '@mpxjs/utils'
|
|
10
10
|
import { LabelContext, RadioGroupContext } from './context'
|
|
@@ -193,32 +193,26 @@ const Radio = forwardRef<HandlerRef<View, RadioProps>, RadioProps>(
|
|
|
193
193
|
}
|
|
194
194
|
}, [checked])
|
|
195
195
|
|
|
196
|
-
return (
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
</View>
|
|
196
|
+
return createElement(View, innerProps,
|
|
197
|
+
createElement(
|
|
198
|
+
View,
|
|
199
|
+
{ style: defaultStyle },
|
|
200
|
+
createElement(Icon, {
|
|
201
|
+
type: 'success',
|
|
202
|
+
size: 24,
|
|
203
|
+
color: disabled ? '#E1E1E1' : color,
|
|
204
|
+
style: extendObject({}, styles.icon, isChecked && styles.iconChecked, disabled && styles.iconDisabled)
|
|
205
|
+
})
|
|
206
|
+
),
|
|
207
|
+
wrapChildren(
|
|
208
|
+
props,
|
|
210
209
|
{
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
varContext: varContextRef.current,
|
|
216
|
-
textStyle,
|
|
217
|
-
textProps
|
|
218
|
-
}
|
|
219
|
-
)
|
|
210
|
+
hasVarDec,
|
|
211
|
+
varContext: varContextRef.current,
|
|
212
|
+
textStyle,
|
|
213
|
+
textProps
|
|
220
214
|
}
|
|
221
|
-
|
|
215
|
+
)
|
|
222
216
|
)
|
|
223
217
|
}
|
|
224
218
|
)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
|
|
2
|
+
export const generateHTML = (html: string) => {
|
|
3
|
+
return `<html><head>
|
|
4
|
+
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scaleable=no" name="viewport">
|
|
5
|
+
<style>
|
|
6
|
+
html {
|
|
7
|
+
-ms-content-zooming: none;
|
|
8
|
+
-ms-touch-action: pan-x pan-y;
|
|
9
|
+
}
|
|
10
|
+
body {
|
|
11
|
+
position: fixed;
|
|
12
|
+
top: 0;
|
|
13
|
+
right: 0;
|
|
14
|
+
bottom: 0;
|
|
15
|
+
left: 0;
|
|
16
|
+
overflow: hidden;
|
|
17
|
+
}
|
|
18
|
+
html,body {
|
|
19
|
+
margin: 0;
|
|
20
|
+
padding: 0;
|
|
21
|
+
}
|
|
22
|
+
* {
|
|
23
|
+
user-select: none;
|
|
24
|
+
-ms-user-select: none;
|
|
25
|
+
-moz-user-select: none;
|
|
26
|
+
-webkit-user-select: none;
|
|
27
|
+
}
|
|
28
|
+
</style>
|
|
29
|
+
</head>
|
|
30
|
+
<body><div id="rich-text">${html}</div>
|
|
31
|
+
<script>
|
|
32
|
+
function sendHeight() {
|
|
33
|
+
const dom = document.getElementById('rich-text')
|
|
34
|
+
window.ReactNativeWebView.postMessage(dom.scrollHeight);
|
|
35
|
+
}
|
|
36
|
+
window.onload = sendHeight;
|
|
37
|
+
</script>
|
|
38
|
+
</body
|
|
39
|
+
></html>`
|
|
40
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* ✔ nodes
|
|
4
|
+
*/
|
|
5
|
+
import { View, ViewProps, ViewStyle } from 'react-native'
|
|
6
|
+
import { useRef, forwardRef, JSX, useState, createElement } from 'react'
|
|
7
|
+
import useInnerProps from '../getInnerListeners'
|
|
8
|
+
import useNodesRef, { HandlerRef } from '../useNodesRef' // 引入辅助函数
|
|
9
|
+
import { useTransformStyle, useLayout, extendObject } from '../utils'
|
|
10
|
+
import { WebView, WebViewMessageEvent } from 'react-native-webview'
|
|
11
|
+
import { generateHTML } from './html'
|
|
12
|
+
|
|
13
|
+
type Node = {
|
|
14
|
+
type: 'node' | 'text'
|
|
15
|
+
name?: string
|
|
16
|
+
attrs?: any
|
|
17
|
+
children?: Array<Node>
|
|
18
|
+
text: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface _RichTextProps extends ViewProps {
|
|
22
|
+
style?: ViewStyle
|
|
23
|
+
nodes: string | Array<Node>
|
|
24
|
+
'enable-var'?: boolean
|
|
25
|
+
'external-var-context'?: Record<string, any>
|
|
26
|
+
'parent-font-size'?: number
|
|
27
|
+
'parent-width'?: number
|
|
28
|
+
'parent-height'?: number
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function jsonToHtmlStr (elements: Array<Node>) {
|
|
32
|
+
let htmlStr = ''
|
|
33
|
+
|
|
34
|
+
for (const element of elements) {
|
|
35
|
+
if (element.type === 'text') {
|
|
36
|
+
htmlStr += element.text
|
|
37
|
+
return htmlStr
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const { name, attrs = {}, children = [] } = element
|
|
41
|
+
|
|
42
|
+
let attrStr = ''
|
|
43
|
+
for (const [key, value] of Object.entries(attrs)) attrStr += ` ${key}="${value}"`
|
|
44
|
+
|
|
45
|
+
let childrenStr = ''
|
|
46
|
+
for (const child of children) childrenStr += jsonToHtmlStr([child])
|
|
47
|
+
|
|
48
|
+
htmlStr += `<${name}${attrStr}>${childrenStr}</${name}>`
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return htmlStr
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const _RichText = forwardRef<HandlerRef<View, _RichTextProps>, _RichTextProps>((props, ref): JSX.Element => {
|
|
55
|
+
const {
|
|
56
|
+
style = {},
|
|
57
|
+
nodes,
|
|
58
|
+
'enable-var': enableVar,
|
|
59
|
+
'external-var-context': externalVarContext,
|
|
60
|
+
'parent-font-size': parentFontSize,
|
|
61
|
+
'parent-width': parentWidth,
|
|
62
|
+
'parent-height': parentHeight
|
|
63
|
+
} = props
|
|
64
|
+
|
|
65
|
+
const nodeRef = useRef(null)
|
|
66
|
+
const [webViewHeight, setWebViewHeight] = useState(0)
|
|
67
|
+
|
|
68
|
+
const {
|
|
69
|
+
normalStyle,
|
|
70
|
+
hasSelfPercent,
|
|
71
|
+
setWidth,
|
|
72
|
+
setHeight
|
|
73
|
+
} = useTransformStyle(Object.assign({
|
|
74
|
+
width: '100%',
|
|
75
|
+
height: webViewHeight
|
|
76
|
+
}, style), {
|
|
77
|
+
enableVar,
|
|
78
|
+
externalVarContext,
|
|
79
|
+
parentFontSize,
|
|
80
|
+
parentWidth,
|
|
81
|
+
parentHeight
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
const {
|
|
85
|
+
layoutRef,
|
|
86
|
+
layoutStyle,
|
|
87
|
+
layoutProps
|
|
88
|
+
} = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })
|
|
89
|
+
|
|
90
|
+
useNodesRef<View, _RichTextProps>(props, ref, nodeRef, {
|
|
91
|
+
layoutRef
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const innerProps = useInnerProps(props, extendObject({
|
|
95
|
+
ref: nodeRef,
|
|
96
|
+
style: extendObject(normalStyle, layoutStyle)
|
|
97
|
+
}, layoutProps), [], {
|
|
98
|
+
layoutRef
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
const html: string = typeof nodes === 'string' ? nodes : jsonToHtmlStr(nodes)
|
|
102
|
+
|
|
103
|
+
return createElement(View, innerProps,
|
|
104
|
+
createElement(WebView, {
|
|
105
|
+
source: { html: generateHTML(html) },
|
|
106
|
+
onMessage: (event: WebViewMessageEvent) => {
|
|
107
|
+
setWebViewHeight(+event.nativeEvent.data)
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
)
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
_RichText.displayName = 'mpx-rich-text'
|
|
114
|
+
|
|
115
|
+
export default _RichText
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ✔ enable
|
|
3
3
|
*/
|
|
4
|
-
import { ReactNode } from 'react'
|
|
4
|
+
import { ReactNode, createElement, Fragment } from 'react'
|
|
5
5
|
import { Portal } from '@ant-design/react-native'
|
|
6
6
|
import { warn } from '@mpxjs/utils'
|
|
7
7
|
interface RootPortalProps {
|
|
@@ -16,10 +16,8 @@ const _RootPortal = (props: RootPortalProps) => {
|
|
|
16
16
|
warn('The root-portal component does not support the style prop.')
|
|
17
17
|
}
|
|
18
18
|
return enable
|
|
19
|
-
?
|
|
20
|
-
|
|
21
|
-
</Portal>
|
|
22
|
-
: <>{children}</>
|
|
19
|
+
? createElement(Portal, null, children)
|
|
20
|
+
: createElement(Fragment, null, children)
|
|
23
21
|
}
|
|
24
22
|
|
|
25
23
|
_RootPortal.displayName = 'MpxRootPortal'
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
*/
|
|
34
34
|
import { ScrollView } from 'react-native-gesture-handler'
|
|
35
35
|
import { View, RefreshControl, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent, ViewStyle } from 'react-native'
|
|
36
|
-
import { JSX, ReactNode, RefObject, useRef, useState, useEffect, forwardRef, useContext } from 'react'
|
|
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'
|
|
39
39
|
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
|
-
import { IntersectionObserverContext } from './context'
|
|
42
|
+
import { IntersectionObserverContext, ScrollViewContext } from './context'
|
|
43
43
|
|
|
44
44
|
interface ScrollViewProps {
|
|
45
45
|
children?: ReactNode;
|
|
@@ -165,7 +165,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
165
165
|
const initialTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
166
166
|
const intersectionObservers = useContext(IntersectionObserverContext)
|
|
167
167
|
|
|
168
|
-
const
|
|
168
|
+
const firstScrollIntoViewChange = useRef<boolean>(false)
|
|
169
169
|
|
|
170
170
|
const {
|
|
171
171
|
normalStyle,
|
|
@@ -194,6 +194,12 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
194
194
|
gestureRef: scrollViewRef
|
|
195
195
|
})
|
|
196
196
|
|
|
197
|
+
const contextValue = useMemo(() => {
|
|
198
|
+
return {
|
|
199
|
+
gestureRef: scrollViewRef
|
|
200
|
+
}
|
|
201
|
+
}, [])
|
|
202
|
+
|
|
197
203
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout })
|
|
198
204
|
|
|
199
205
|
if (scrollX && scrollY) {
|
|
@@ -220,23 +226,28 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
220
226
|
}, [refresherTriggered])
|
|
221
227
|
|
|
222
228
|
useEffect(() => {
|
|
223
|
-
if (scrollIntoView && __selectRef
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
nodeRef.current?.measureLayout(
|
|
230
|
-
scrollViewRef.current,
|
|
231
|
-
(left: number, top:number) => {
|
|
232
|
-
scrollToOffset(left, top)
|
|
233
|
-
}
|
|
234
|
-
)
|
|
235
|
-
}
|
|
236
|
-
})
|
|
229
|
+
if (scrollIntoView && __selectRef) {
|
|
230
|
+
if (!firstScrollIntoViewChange.current) {
|
|
231
|
+
setTimeout(handleScrollIntoView)
|
|
232
|
+
} else {
|
|
233
|
+
handleScrollIntoView()
|
|
234
|
+
}
|
|
237
235
|
}
|
|
236
|
+
firstScrollIntoViewChange.current = true
|
|
238
237
|
}, [scrollIntoView])
|
|
239
238
|
|
|
239
|
+
function handleScrollIntoView () {
|
|
240
|
+
const refs = __selectRef!(`#${scrollIntoView}`, 'node')
|
|
241
|
+
if (!refs) return
|
|
242
|
+
const { nodeRef } = refs.getNodeInstance()
|
|
243
|
+
nodeRef.current?.measureLayout(
|
|
244
|
+
scrollViewRef.current,
|
|
245
|
+
(left: number, top:number) => {
|
|
246
|
+
scrollToOffset(left, top)
|
|
247
|
+
}
|
|
248
|
+
)
|
|
249
|
+
}
|
|
250
|
+
|
|
240
251
|
function selectLength (size: { height: number; width: number }) {
|
|
241
252
|
return !scrollX ? size.height : size.width
|
|
242
253
|
}
|
|
@@ -327,6 +338,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
327
338
|
}, props)
|
|
328
339
|
)
|
|
329
340
|
updateScrollOptions(e, { scrollLeft, scrollTop })
|
|
341
|
+
onStartReached(e)
|
|
342
|
+
onEndReached(e)
|
|
330
343
|
if (enableTriggerIntersectionObserver && intersectionObservers) {
|
|
331
344
|
for (const key in intersectionObservers) {
|
|
332
345
|
intersectionObservers[key].throttleMeasure()
|
|
@@ -491,32 +504,29 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
491
504
|
white: ['#fff']
|
|
492
505
|
}
|
|
493
506
|
|
|
494
|
-
return (
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
refreshControl
|
|
498
|
-
? (
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
)
|
|
518
|
-
}
|
|
519
|
-
</ScrollView>
|
|
507
|
+
return createElement(
|
|
508
|
+
ScrollView,
|
|
509
|
+
extendObject({}, innerProps, {
|
|
510
|
+
refreshControl: refresherEnabled
|
|
511
|
+
? createElement(RefreshControl, extendObject({
|
|
512
|
+
progressBackgroundColor: refresherBackground,
|
|
513
|
+
refreshing: refreshing,
|
|
514
|
+
onRefresh: onRefresh
|
|
515
|
+
}, (refresherDefaultStyle && refresherDefaultStyle !== 'none' ? { colors: refreshColor[refresherDefaultStyle] } : null)))
|
|
516
|
+
: undefined
|
|
517
|
+
}),
|
|
518
|
+
createElement(ScrollViewContext.Provider,
|
|
519
|
+
{ value: contextValue },
|
|
520
|
+
wrapChildren(
|
|
521
|
+
props,
|
|
522
|
+
{
|
|
523
|
+
hasVarDec,
|
|
524
|
+
varContext: varContextRef.current,
|
|
525
|
+
textStyle,
|
|
526
|
+
textProps
|
|
527
|
+
}
|
|
528
|
+
)
|
|
529
|
+
)
|
|
520
530
|
)
|
|
521
531
|
})
|
|
522
532
|
|