@mpxjs/webpack-plugin 2.10.1 → 2.10.3
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/lib/dependencies/RecordPageConfigsMapDependency.js +45 -0
- package/lib/index.js +23 -1
- package/lib/platform/style/wx/index.js +6 -4
- package/lib/platform/template/wx/component-config/input.js +1 -1
- package/lib/platform/template/wx/component-config/textarea.js +1 -1
- package/lib/platform/template/wx/component-config/view.js +12 -2
- package/lib/react/index.js +0 -1
- package/lib/react/processJSON.js +13 -2
- package/lib/react/processScript.js +7 -4
- package/lib/react/processTemplate.js +18 -3
- package/lib/react/script-helper.js +18 -4
- package/lib/runtime/components/react/context.ts +3 -4
- package/lib/runtime/components/react/dist/mpx-image.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-input.jsx +54 -54
- package/lib/runtime/components/react/dist/{KeyboardAvoidingView.jsx → mpx-keyboard-avoiding-view.jsx} +23 -12
- package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +1 -2
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +16 -8
- package/lib/runtime/components/react/dist/mpx-simple-view.jsx +22 -0
- package/lib/runtime/components/react/dist/mpx-textarea.jsx +6 -6
- package/lib/runtime/components/react/dist/mpx-view.jsx +10 -5
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +6 -5
- package/lib/runtime/components/react/dist/useAnimationHooks.js +46 -48
- package/lib/runtime/components/react/dist/utils.jsx +17 -21
- package/lib/runtime/components/react/mpx-image.tsx +2 -2
- package/lib/runtime/components/react/mpx-input.tsx +66 -72
- package/lib/runtime/components/react/{KeyboardAvoidingView.tsx → mpx-keyboard-avoiding-view.tsx} +32 -18
- package/lib/runtime/components/react/mpx-portal/portal-manager.tsx +1 -2
- package/lib/runtime/components/react/mpx-scroll-view.tsx +21 -8
- package/lib/runtime/components/react/mpx-simple-view.tsx +32 -0
- package/lib/runtime/components/react/mpx-textarea.tsx +10 -6
- package/lib/runtime/components/react/mpx-view.tsx +17 -10
- package/lib/runtime/components/react/mpx-web-view.tsx +12 -10
- package/lib/runtime/components/react/types/getInnerListeners.d.ts +1 -1
- package/lib/runtime/components/react/useAnimationHooks.ts +46 -48
- package/lib/runtime/components/react/utils.tsx +21 -24
- package/lib/runtime/optionProcessor.js +3 -2
- package/lib/style-compiler/index.js +8 -6
- package/lib/template-compiler/compiler.js +22 -14
- package/lib/utils/match-condition.js +14 -8
- package/lib/web/processJSON.js +1 -3
- package/package.json +4 -4
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* ✔ password
|
|
5
5
|
* ✔ placeholder
|
|
6
6
|
* - placeholder-style: Only support color.
|
|
7
|
-
*
|
|
7
|
+
* - placeholder-class: Only support color.
|
|
8
8
|
* ✔ disabled
|
|
9
9
|
* ✔ maxlength
|
|
10
10
|
* ✔ cursor-spacing
|
|
@@ -54,7 +54,7 @@ import {
|
|
|
54
54
|
TextInputSubmitEditingEventData
|
|
55
55
|
} from 'react-native'
|
|
56
56
|
import { warn } from '@mpxjs/utils'
|
|
57
|
-
import {
|
|
57
|
+
import { useUpdateEffect, useTransformStyle, useLayout, extendObject } from './utils'
|
|
58
58
|
import useInnerProps, { getCustomEvent } from './getInnerListeners'
|
|
59
59
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
60
60
|
import { FormContext, FormFieldValue, KeyboardAvoidContext } from './context'
|
|
@@ -73,6 +73,8 @@ type InputStyle = Omit<
|
|
|
73
73
|
|
|
74
74
|
type Type = 'text' | 'number' | 'idcard' | 'digit'
|
|
75
75
|
|
|
76
|
+
type ConfirmType = 'done' | 'send' | 'search' | 'next' | 'go' | 'return'
|
|
77
|
+
|
|
76
78
|
export interface InputProps {
|
|
77
79
|
name?: string
|
|
78
80
|
style?: InputStyle & Record<string, any>
|
|
@@ -85,13 +87,13 @@ export interface InputProps {
|
|
|
85
87
|
maxlength?: number
|
|
86
88
|
'auto-focus'?: boolean
|
|
87
89
|
focus?: boolean
|
|
88
|
-
'confirm-type'?:
|
|
90
|
+
'confirm-type'?: ConfirmType
|
|
89
91
|
'confirm-hold'?: boolean
|
|
90
92
|
cursor?: number
|
|
91
93
|
'cursor-color'?: string
|
|
92
94
|
'selection-start'?: number
|
|
93
95
|
'selection-end'?: number
|
|
94
|
-
'placeholder-style'?: string
|
|
96
|
+
'placeholder-style'?: { color?: string }
|
|
95
97
|
'enable-offset'?: boolean,
|
|
96
98
|
'enable-var'?: boolean
|
|
97
99
|
'external-var-context'?: Record<string, any>
|
|
@@ -133,7 +135,7 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
|
|
|
133
135
|
type = 'text',
|
|
134
136
|
value,
|
|
135
137
|
password,
|
|
136
|
-
'placeholder-style': placeholderStyle,
|
|
138
|
+
'placeholder-style': placeholderStyle = {},
|
|
137
139
|
disabled,
|
|
138
140
|
maxlength = 140,
|
|
139
141
|
'cursor-spacing': cursorSpacing = 0,
|
|
@@ -185,10 +187,9 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
|
|
|
185
187
|
|
|
186
188
|
const keyboardType = keyboardTypeMap[type]
|
|
187
189
|
const defaultValue = parseValue(value)
|
|
188
|
-
const placeholderTextColor = parseInlineStyle(placeholderStyle)?.color
|
|
189
190
|
const textAlignVertical = multiline ? 'top' : 'auto'
|
|
190
191
|
|
|
191
|
-
const tmpValue = useRef<string
|
|
192
|
+
const tmpValue = useRef<string>(defaultValue)
|
|
192
193
|
const cursorIndex = useRef<number>(0)
|
|
193
194
|
const lineCount = useRef<number>(0)
|
|
194
195
|
|
|
@@ -200,7 +201,7 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
|
|
|
200
201
|
{ padding: 0, backgroundColor: '#fff' },
|
|
201
202
|
style,
|
|
202
203
|
multiline && autoHeight
|
|
203
|
-
? { minHeight: Math.max((style as any)?.minHeight || 35, contentHeight) }
|
|
204
|
+
? { height: 'auto', minHeight: Math.max((style as any)?.minHeight || 35, contentHeight) }
|
|
204
205
|
: {}
|
|
205
206
|
)
|
|
206
207
|
|
|
@@ -232,55 +233,64 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
|
|
|
232
233
|
}
|
|
233
234
|
}, [cursor, selectionStart, selectionEnd])
|
|
234
235
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
236
|
+
// have not selection on the Android platformg
|
|
237
|
+
const getCursorIndex = (
|
|
238
|
+
changedSelection: TextInputSelectionChangeEventData['selection'] | undefined,
|
|
239
|
+
prevValue: string,
|
|
240
|
+
curValue: string
|
|
241
|
+
) => {
|
|
242
|
+
if (changedSelection) return changedSelection.end
|
|
243
|
+
if (!prevValue || !curValue || prevValue.length === curValue.length) return curValue.length
|
|
244
|
+
const prevStr = prevValue.substring(cursorIndex.current)
|
|
245
|
+
const curStr = curValue.substring(cursorIndex.current)
|
|
246
|
+
return cursorIndex.current + curStr.length - prevStr.length
|
|
242
247
|
}
|
|
243
248
|
|
|
244
|
-
const onChange = (evt: NativeSyntheticEvent<TextInputChangeEventData>) => {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
249
|
+
const onChange = (evt: NativeSyntheticEvent<TextInputChangeEventData & TextInputSelectionChangeEventData>) => {
|
|
250
|
+
const { text, selection } = evt.nativeEvent
|
|
251
|
+
// will trigger twice on the Android platformg, prevent the second trigger
|
|
252
|
+
if (tmpValue.current === text) return
|
|
253
|
+
const index = getCursorIndex(selection, tmpValue.current, text)
|
|
254
|
+
tmpValue.current = text
|
|
255
|
+
cursorIndex.current = index
|
|
256
|
+
if (bindinput) {
|
|
257
|
+
const result = bindinput(
|
|
258
|
+
getCustomEvent(
|
|
259
|
+
'input',
|
|
260
|
+
evt,
|
|
261
|
+
{
|
|
262
|
+
detail: {
|
|
263
|
+
value: tmpValue.current,
|
|
264
|
+
cursor: cursorIndex.current
|
|
265
|
+
},
|
|
266
|
+
layoutRef
|
|
255
267
|
},
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
props
|
|
268
|
+
props
|
|
269
|
+
)
|
|
259
270
|
)
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
271
|
+
if (typeof result === 'string') {
|
|
272
|
+
tmpValue.current = result
|
|
273
|
+
setInputValue(result)
|
|
274
|
+
} else {
|
|
275
|
+
setInputValue(tmpValue.current)
|
|
276
|
+
}
|
|
264
277
|
} else {
|
|
265
278
|
setInputValue(tmpValue.current)
|
|
266
279
|
}
|
|
267
280
|
}
|
|
268
281
|
|
|
269
282
|
const setKeyboardAvoidContext = () => {
|
|
270
|
-
if (adjustPosition && keyboardAvoid
|
|
271
|
-
|
|
272
|
-
cursorSpacing,
|
|
273
|
-
ref: nodeRef
|
|
274
|
-
})
|
|
283
|
+
if (adjustPosition && keyboardAvoid) {
|
|
284
|
+
keyboardAvoid.current = { cursorSpacing, ref: nodeRef }
|
|
275
285
|
}
|
|
276
286
|
}
|
|
277
287
|
|
|
278
|
-
const
|
|
288
|
+
const onTouchStart = () => {
|
|
279
289
|
// sometimes the focus event occurs later than the keyboardWillShow event
|
|
280
290
|
setKeyboardAvoidContext()
|
|
281
291
|
}
|
|
282
292
|
|
|
283
|
-
const
|
|
293
|
+
const onFocus = (evt: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
|
284
294
|
setKeyboardAvoidContext()
|
|
285
295
|
bindfocus && bindfocus(
|
|
286
296
|
getCustomEvent(
|
|
@@ -297,7 +307,7 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
|
|
|
297
307
|
)
|
|
298
308
|
}
|
|
299
309
|
|
|
300
|
-
const
|
|
310
|
+
const onBlur = (evt: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
|
301
311
|
bindblur && bindblur(
|
|
302
312
|
getCustomEvent(
|
|
303
313
|
'blur',
|
|
@@ -314,23 +324,6 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
|
|
|
314
324
|
)
|
|
315
325
|
}
|
|
316
326
|
|
|
317
|
-
const onKeyPress = (evt: NativeSyntheticEvent<TextInputKeyPressEventData>) => {
|
|
318
|
-
evt.nativeEvent.key === 'Enter' &&
|
|
319
|
-
bindconfirm!(
|
|
320
|
-
getCustomEvent(
|
|
321
|
-
'confirm',
|
|
322
|
-
evt,
|
|
323
|
-
{
|
|
324
|
-
detail: {
|
|
325
|
-
value: tmpValue.current || ''
|
|
326
|
-
},
|
|
327
|
-
layoutRef
|
|
328
|
-
},
|
|
329
|
-
props
|
|
330
|
-
)
|
|
331
|
-
)
|
|
332
|
-
}
|
|
333
|
-
|
|
334
327
|
const onSubmitEditing = (evt: NativeSyntheticEvent<TextInputSubmitEditingEventData>) => {
|
|
335
328
|
bindconfirm!(
|
|
336
329
|
getCustomEvent(
|
|
@@ -348,15 +341,18 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
|
|
|
348
341
|
}
|
|
349
342
|
|
|
350
343
|
const onSelectionChange = (evt: NativeSyntheticEvent<TextInputSelectionChangeEventData>) => {
|
|
351
|
-
|
|
344
|
+
const { selection } = evt.nativeEvent
|
|
345
|
+
const { start, end } = selection
|
|
346
|
+
cursorIndex.current = start
|
|
347
|
+
setSelection(selection)
|
|
352
348
|
bindselectionchange && bindselectionchange(
|
|
353
349
|
getCustomEvent(
|
|
354
350
|
'selectionchange',
|
|
355
351
|
evt,
|
|
356
352
|
{
|
|
357
353
|
detail: {
|
|
358
|
-
selectionStart:
|
|
359
|
-
selectionEnd:
|
|
354
|
+
selectionStart: start,
|
|
355
|
+
selectionEnd: end
|
|
360
356
|
},
|
|
361
357
|
layoutRef
|
|
362
358
|
},
|
|
@@ -444,26 +440,24 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
|
|
|
444
440
|
maxLength: maxlength === -1 ? undefined : maxlength,
|
|
445
441
|
editable: !disabled,
|
|
446
442
|
autoFocus: !!autoFocus || !!focus,
|
|
447
|
-
returnKeyType: confirmType,
|
|
448
443
|
selection: selection,
|
|
449
444
|
selectionColor: cursorColor,
|
|
450
445
|
blurOnSubmit: !multiline && !confirmHold,
|
|
451
446
|
underlineColorAndroid: 'rgba(0,0,0,0)',
|
|
452
447
|
textAlignVertical: textAlignVertical,
|
|
453
|
-
placeholderTextColor:
|
|
448
|
+
placeholderTextColor: placeholderStyle?.color,
|
|
454
449
|
multiline: !!multiline
|
|
455
450
|
},
|
|
451
|
+
!!multiline && confirmType === 'return' ? {} : { enterKeyHint: confirmType },
|
|
456
452
|
layoutProps,
|
|
457
453
|
{
|
|
458
|
-
onTouchStart
|
|
459
|
-
onFocus
|
|
460
|
-
onBlur
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
onChange: onChange,
|
|
466
|
-
onContentSizeChange: onContentSizeChange
|
|
454
|
+
onTouchStart,
|
|
455
|
+
onFocus,
|
|
456
|
+
onBlur,
|
|
457
|
+
onChange,
|
|
458
|
+
onSelectionChange,
|
|
459
|
+
onContentSizeChange,
|
|
460
|
+
onSubmitEditing: bindconfirm && !multiline && onSubmitEditing
|
|
467
461
|
}
|
|
468
462
|
),
|
|
469
463
|
[
|
package/lib/runtime/components/react/{KeyboardAvoidingView.tsx → mpx-keyboard-avoiding-view.tsx}
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import React, { ReactNode, useContext, useEffect } from 'react'
|
|
1
|
+
import React, { ReactNode, useContext, useEffect, useMemo } from 'react'
|
|
2
2
|
import { DimensionValue, EmitterSubscription, Keyboard, Platform, View, ViewStyle } from 'react-native'
|
|
3
|
-
import Animated, { useSharedValue, useAnimatedStyle, withTiming, Easing } from 'react-native-reanimated'
|
|
3
|
+
import Animated, { useSharedValue, useAnimatedStyle, withTiming, Easing, runOnJS } from 'react-native-reanimated'
|
|
4
|
+
import { GestureDetector, Gesture } from 'react-native-gesture-handler'
|
|
4
5
|
import { KeyboardAvoidContext } from './context'
|
|
5
|
-
import { extendObject } from './utils'
|
|
6
6
|
|
|
7
7
|
type KeyboardAvoidViewProps = {
|
|
8
8
|
children?: ReactNode
|
|
@@ -19,6 +19,17 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
|
|
|
19
19
|
const basic = useSharedValue('auto')
|
|
20
20
|
const keyboardAvoid = useContext(KeyboardAvoidContext)
|
|
21
21
|
|
|
22
|
+
const dismiss = () => {
|
|
23
|
+
Keyboard.isVisible() && Keyboard.dismiss()
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const gesture = useMemo(() => {
|
|
27
|
+
return Gesture.Tap()
|
|
28
|
+
.onEnd(() => {
|
|
29
|
+
dismiss()
|
|
30
|
+
}).runOnJS(true)
|
|
31
|
+
}, [])
|
|
32
|
+
|
|
22
33
|
const animatedStyle = useAnimatedStyle(() => {
|
|
23
34
|
return Object.assign(
|
|
24
35
|
{
|
|
@@ -29,10 +40,9 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
|
|
|
29
40
|
})
|
|
30
41
|
|
|
31
42
|
const resetKeyboard = () => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
})
|
|
43
|
+
if (keyboardAvoid?.current) {
|
|
44
|
+
keyboardAvoid.current = null
|
|
45
|
+
}
|
|
36
46
|
offset.value = withTiming(0, { duration, easing })
|
|
37
47
|
basic.value = 'auto'
|
|
38
48
|
}
|
|
@@ -48,7 +58,7 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
|
|
|
48
58
|
const { ref, cursorSpacing = 0 } = keyboardAvoid.current
|
|
49
59
|
setTimeout(() => {
|
|
50
60
|
ref?.current?.measure((x: number, y: number, width: number, height: number, pageX: number, pageY: number) => {
|
|
51
|
-
const aboveOffset =
|
|
61
|
+
const aboveOffset = pageY + height - endCoordinates.screenY
|
|
52
62
|
const aboveValue = -aboveOffset >= cursorSpacing ? 0 : aboveOffset + cursorSpacing
|
|
53
63
|
const belowValue = Math.min(endCoordinates.height, aboveOffset + cursorSpacing)
|
|
54
64
|
const value = aboveOffset > 0 ? belowValue : aboveValue
|
|
@@ -92,17 +102,21 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
|
|
|
92
102
|
}, [keyboardAvoid])
|
|
93
103
|
|
|
94
104
|
return (
|
|
95
|
-
<
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
+
<GestureDetector gesture={gesture}>
|
|
106
|
+
<View style={style}>
|
|
107
|
+
<Animated.View
|
|
108
|
+
style={[
|
|
109
|
+
contentContainerStyle,
|
|
110
|
+
animatedStyle
|
|
111
|
+
]}
|
|
112
|
+
>
|
|
113
|
+
{children}
|
|
114
|
+
</Animated.View>
|
|
115
|
+
</View>
|
|
116
|
+
</GestureDetector>
|
|
105
117
|
)
|
|
106
118
|
}
|
|
107
119
|
|
|
120
|
+
KeyboardAvoidingView.displayName = 'MpxKeyboardAvoidingView'
|
|
121
|
+
|
|
108
122
|
export default KeyboardAvoidingView
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { useState, useCallback, forwardRef, ForwardedRef, useImperativeHandle, ReactNode, ReactElement } from 'react'
|
|
2
2
|
import { View, StyleSheet } from 'react-native'
|
|
3
|
-
import { extendObject } from '../utils'
|
|
4
3
|
|
|
5
4
|
export type State = {
|
|
6
5
|
portals: Array<{
|
|
@@ -27,7 +26,7 @@ const _PortalManager = forwardRef((props: PortalManagerProps, ref:ForwardedRef<u
|
|
|
27
26
|
setState((prevState) => ({
|
|
28
27
|
portals: prevState.portals.map((item) => {
|
|
29
28
|
if (item.key === key) {
|
|
30
|
-
return
|
|
29
|
+
return Object.assign({}, item, { children })
|
|
31
30
|
}
|
|
32
31
|
return item
|
|
33
32
|
})
|
|
@@ -70,6 +70,7 @@ interface ScrollViewProps {
|
|
|
70
70
|
'parent-height'?: number;
|
|
71
71
|
'wait-for'?: Array<GestureHandler>;
|
|
72
72
|
'simultaneous-handlers'?: Array<GestureHandler>;
|
|
73
|
+
'scroll-event-throttle'?:number;
|
|
73
74
|
bindscrolltoupper?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
|
|
74
75
|
bindscrolltolower?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
|
|
75
76
|
bindscroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
|
|
@@ -124,7 +125,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
124
125
|
'paging-enabled': pagingEnabled = false,
|
|
125
126
|
'upper-threshold': upperThreshold = 50,
|
|
126
127
|
'lower-threshold': lowerThreshold = 50,
|
|
127
|
-
'scroll-with-animation': scrollWithAnimation,
|
|
128
|
+
'scroll-with-animation': scrollWithAnimation = false,
|
|
128
129
|
'refresher-enabled': refresherEnabled,
|
|
129
130
|
'refresher-default-style': refresherDefaultStyle,
|
|
130
131
|
'refresher-background': refresherBackground,
|
|
@@ -140,6 +141,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
140
141
|
'parent-height': parentHeight,
|
|
141
142
|
'simultaneous-handlers': originSimultaneousHandlers,
|
|
142
143
|
'wait-for': waitFor,
|
|
144
|
+
'scroll-event-throttle': scrollEventThrottle = 0,
|
|
143
145
|
__selectRef
|
|
144
146
|
} = props
|
|
145
147
|
|
|
@@ -159,7 +161,6 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
159
161
|
visibleLength: 0
|
|
160
162
|
})
|
|
161
163
|
|
|
162
|
-
const scrollEventThrottle = 50
|
|
163
164
|
const hasCallScrollToUpper = useRef(true)
|
|
164
165
|
const hasCallScrollToLower = useRef(false)
|
|
165
166
|
const initialTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
@@ -189,7 +190,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
189
190
|
pagingEnabled,
|
|
190
191
|
fastDeceleration: false,
|
|
191
192
|
decelerationDisabled: false,
|
|
192
|
-
scrollTo
|
|
193
|
+
scrollTo
|
|
193
194
|
},
|
|
194
195
|
gestureRef: scrollViewRef
|
|
195
196
|
})
|
|
@@ -202,6 +203,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
202
203
|
|
|
203
204
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout })
|
|
204
205
|
|
|
206
|
+
const lastOffset = useRef(0)
|
|
207
|
+
|
|
205
208
|
if (scrollX && scrollY) {
|
|
206
209
|
warn('scroll-x and scroll-y cannot be set to true at the same time, Mpx will use the value of scroll-y as the criterion')
|
|
207
210
|
}
|
|
@@ -236,6 +239,10 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
236
239
|
firstScrollIntoViewChange.current = true
|
|
237
240
|
}, [scrollIntoView])
|
|
238
241
|
|
|
242
|
+
function scrollTo ({ top = 0, left = 0, animated = false } : { top?: number; left?: number; animated?: boolean }) {
|
|
243
|
+
scrollToOffset(left, top, animated)
|
|
244
|
+
}
|
|
245
|
+
|
|
239
246
|
function handleScrollIntoView () {
|
|
240
247
|
const refs = __selectRef!(`#${scrollIntoView}`, 'node')
|
|
241
248
|
if (!refs) return
|
|
@@ -259,7 +266,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
259
266
|
function onStartReached (e: NativeSyntheticEvent<NativeScrollEvent>) {
|
|
260
267
|
const { bindscrolltoupper } = props
|
|
261
268
|
const { offset } = scrollOptions.current
|
|
262
|
-
|
|
269
|
+
const isScrollingBackward = offset < lastOffset.current
|
|
270
|
+
if (bindscrolltoupper && (offset <= upperThreshold) && isScrollingBackward) {
|
|
263
271
|
if (!hasCallScrollToUpper.current) {
|
|
264
272
|
bindscrolltoupper(
|
|
265
273
|
getCustomEvent('scrolltoupper', e, {
|
|
@@ -280,13 +288,15 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
280
288
|
const { bindscrolltolower } = props
|
|
281
289
|
const { contentLength, visibleLength, offset } = scrollOptions.current
|
|
282
290
|
const distanceFromEnd = contentLength - visibleLength - offset
|
|
283
|
-
|
|
291
|
+
const isScrollingForward = offset > lastOffset.current
|
|
292
|
+
|
|
293
|
+
if (bindscrolltolower && (distanceFromEnd < lowerThreshold) && isScrollingForward) {
|
|
284
294
|
if (!hasCallScrollToLower.current) {
|
|
285
295
|
hasCallScrollToLower.current = true
|
|
286
296
|
bindscrolltolower(
|
|
287
297
|
getCustomEvent('scrolltolower', e, {
|
|
288
298
|
detail: {
|
|
289
|
-
direction: scrollX ? 'right' : '
|
|
299
|
+
direction: scrollX ? 'right' : 'bottom'
|
|
290
300
|
},
|
|
291
301
|
layoutRef
|
|
292
302
|
}, props)
|
|
@@ -341,6 +351,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
341
351
|
onStartReached(e)
|
|
342
352
|
onEndReached(e)
|
|
343
353
|
updateIntersection()
|
|
354
|
+
// 在 onStartReached、onEndReached 执行完后更新 lastOffset
|
|
355
|
+
lastOffset.current = scrollOptions.current.offset
|
|
344
356
|
}
|
|
345
357
|
|
|
346
358
|
function onScrollEnd (e: NativeSyntheticEvent<NativeScrollEvent>) {
|
|
@@ -363,6 +375,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
363
375
|
onStartReached(e)
|
|
364
376
|
onEndReached(e)
|
|
365
377
|
updateIntersection()
|
|
378
|
+
lastOffset.current = scrollOptions.current.offset
|
|
366
379
|
}
|
|
367
380
|
function updateIntersection () {
|
|
368
381
|
if (enableTriggerIntersectionObserver && intersectionObservers) {
|
|
@@ -371,9 +384,9 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
|
|
|
371
384
|
}
|
|
372
385
|
}
|
|
373
386
|
}
|
|
374
|
-
function scrollToOffset (x = 0, y = 0) {
|
|
387
|
+
function scrollToOffset (x = 0, y = 0, animated = scrollWithAnimation) {
|
|
375
388
|
if (scrollViewRef.current) {
|
|
376
|
-
scrollViewRef.current.scrollTo({ x, y, animated
|
|
389
|
+
scrollViewRef.current.scrollTo({ x, y, animated })
|
|
377
390
|
scrollOptions.current.scrollLeft = x
|
|
378
391
|
scrollOptions.current.scrollTop = y
|
|
379
392
|
snapScrollLeft.current = x
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { View, ViewProps, TextStyle } from 'react-native'
|
|
2
|
+
import { createElement, forwardRef, useRef } from 'react'
|
|
3
|
+
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
4
|
+
import { extendObject, splitProps, splitStyle, wrapChildren } from './utils'
|
|
5
|
+
|
|
6
|
+
const _View2 = forwardRef<HandlerRef<View, ViewProps>, ViewProps>((simpleViewProps: ViewProps, ref) => {
|
|
7
|
+
const nodeRef = useRef(null)
|
|
8
|
+
|
|
9
|
+
const { textProps, innerProps: props = {} } = splitProps(simpleViewProps)
|
|
10
|
+
|
|
11
|
+
const { textStyle, innerStyle = {} } = splitStyle(props.style || {})
|
|
12
|
+
|
|
13
|
+
useNodesRef(props, ref, nodeRef, {
|
|
14
|
+
style: innerStyle || {}
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
return createElement(View, extendObject({}, props, {
|
|
18
|
+
style: innerStyle,
|
|
19
|
+
ref: nodeRef
|
|
20
|
+
}), wrapChildren(
|
|
21
|
+
props,
|
|
22
|
+
{
|
|
23
|
+
hasVarDec: false,
|
|
24
|
+
textStyle: textStyle as TextStyle,
|
|
25
|
+
textProps
|
|
26
|
+
}
|
|
27
|
+
))
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
_View2.displayName = 'MpxSimpleView'
|
|
31
|
+
|
|
32
|
+
export default _View2
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
* Subtraction:
|
|
4
4
|
* type, password, confirm-hold
|
|
5
5
|
* Addition:
|
|
6
|
-
*
|
|
6
|
+
* ✔ confirm-type
|
|
7
7
|
* ✔ auto-height
|
|
8
8
|
* ✘ fixed
|
|
9
9
|
* ✘ show-confirm-bar
|
|
10
10
|
* ✔ bindlinechange: No `heightRpx` info.
|
|
11
11
|
*/
|
|
12
12
|
import { JSX, forwardRef, createElement } from 'react'
|
|
13
|
-
import {
|
|
13
|
+
import { TextInput } from 'react-native'
|
|
14
14
|
import Input, { InputProps, PrivateInputProps } from './mpx-input'
|
|
15
15
|
import { omit, extendObject } from './utils'
|
|
16
16
|
import { HandlerRef } from './useNodesRef'
|
|
@@ -25,7 +25,10 @@ const DEFAULT_TEXTAREA_HEIGHT = 150
|
|
|
25
25
|
|
|
26
26
|
const Textarea = forwardRef<HandlerRef<TextInput, TextareProps>, TextareProps>(
|
|
27
27
|
(props, ref): JSX.Element => {
|
|
28
|
-
const {
|
|
28
|
+
const {
|
|
29
|
+
style = {},
|
|
30
|
+
'confirm-type': confirmType = 'return'
|
|
31
|
+
} = props
|
|
29
32
|
|
|
30
33
|
const restProps = omit(props, [
|
|
31
34
|
'ref',
|
|
@@ -33,16 +36,17 @@ const Textarea = forwardRef<HandlerRef<TextInput, TextareProps>, TextareProps>(
|
|
|
33
36
|
'style',
|
|
34
37
|
'password',
|
|
35
38
|
'multiline',
|
|
39
|
+
'confirm-type',
|
|
36
40
|
'confirm-hold'
|
|
37
41
|
])
|
|
38
42
|
|
|
39
43
|
return createElement(
|
|
40
44
|
Input,
|
|
41
45
|
extendObject(restProps, {
|
|
42
|
-
ref
|
|
46
|
+
ref,
|
|
47
|
+
confirmType,
|
|
43
48
|
multiline: true,
|
|
44
|
-
|
|
45
|
-
bindblur: () => Keyboard.dismiss(),
|
|
49
|
+
'confirm-type': confirmType,
|
|
46
50
|
style: extendObject({
|
|
47
51
|
width: DEFAULT_TEXTAREA_WIDTH,
|
|
48
52
|
height: DEFAULT_TEXTAREA_HEIGHT
|
|
@@ -16,6 +16,7 @@ import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wra
|
|
|
16
16
|
import { error } from '@mpxjs/utils'
|
|
17
17
|
import LinearGradient from 'react-native-linear-gradient'
|
|
18
18
|
import { GestureDetector, PanGesture } from 'react-native-gesture-handler'
|
|
19
|
+
import Portal from './mpx-portal'
|
|
19
20
|
|
|
20
21
|
export interface _ViewProps extends ViewProps {
|
|
21
22
|
style?: ExtendedViewStyle
|
|
@@ -79,7 +80,7 @@ type PreImageInfo = {
|
|
|
79
80
|
type ImageProps = {
|
|
80
81
|
style: ImageStyle,
|
|
81
82
|
src?: string,
|
|
82
|
-
source?: {uri: string },
|
|
83
|
+
source?: { uri: string },
|
|
83
84
|
colors: Array<string>,
|
|
84
85
|
locations?: Array<number>
|
|
85
86
|
angle?: number
|
|
@@ -483,8 +484,8 @@ function parseLinearGradient (text: string): LinearInfo | undefined {
|
|
|
483
484
|
}
|
|
484
485
|
|
|
485
486
|
function parseBgImage (text: string): {
|
|
486
|
-
linearInfo?: LinearInfo
|
|
487
|
-
direction?: string
|
|
487
|
+
linearInfo?: LinearInfo
|
|
488
|
+
direction?: string
|
|
488
489
|
type?: 'image' | 'linear'
|
|
489
490
|
src?: string
|
|
490
491
|
} {
|
|
@@ -578,7 +579,7 @@ function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record<strin
|
|
|
578
579
|
if (!src) {
|
|
579
580
|
setShow(false)
|
|
580
581
|
return
|
|
581
|
-
|
|
582
|
+
// 一开始未出现,数据改变时出现
|
|
582
583
|
} else if (!(needLayout || needImageSize)) {
|
|
583
584
|
setShow(true)
|
|
584
585
|
return
|
|
@@ -602,7 +603,7 @@ function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record<strin
|
|
|
602
603
|
}
|
|
603
604
|
})
|
|
604
605
|
}
|
|
605
|
-
|
|
606
|
+
// type 添加type 处理无渐变 有渐变的场景
|
|
606
607
|
}, [src, type])
|
|
607
608
|
|
|
608
609
|
if (!type) return null
|
|
@@ -636,7 +637,7 @@ function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record<strin
|
|
|
636
637
|
}
|
|
637
638
|
|
|
638
639
|
return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...inheritStyle(innerStyle), ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
|
|
639
|
-
{show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} />
|
|
640
|
+
{show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} />}
|
|
640
641
|
{show && type === 'image' && (renderImage(imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size), enableFastImage))}
|
|
641
642
|
</View>
|
|
642
643
|
}
|
|
@@ -703,6 +704,7 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
|
|
|
703
704
|
const {
|
|
704
705
|
normalStyle,
|
|
705
706
|
hasSelfPercent,
|
|
707
|
+
hasPositionFixed,
|
|
706
708
|
hasVarDec,
|
|
707
709
|
varContextRef,
|
|
708
710
|
setWidth,
|
|
@@ -769,13 +771,18 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
|
|
|
769
771
|
enableFastImage
|
|
770
772
|
})
|
|
771
773
|
|
|
772
|
-
|
|
774
|
+
let finalComponent: JSX.Element = enableStyleAnimation
|
|
773
775
|
? createElement(Animated.View, innerProps, childNode)
|
|
774
776
|
: createElement(View, innerProps, childNode)
|
|
775
777
|
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
778
|
+
if (enableHover) {
|
|
779
|
+
finalComponent = createElement(GestureDetector, { gesture: gesture as PanGesture }, finalComponent)
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
if (hasPositionFixed) {
|
|
783
|
+
finalComponent = createElement(Portal, null, finalComponent)
|
|
784
|
+
}
|
|
785
|
+
return finalComponent
|
|
779
786
|
})
|
|
780
787
|
|
|
781
788
|
_View.displayName = 'MpxView'
|