@mpxjs/webpack-plugin 2.9.69-beta.2 → 2.9.69-beta.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/index.js +1 -17
- package/lib/platform/style/wx/index.js +18 -18
- package/lib/platform/template/wx/component-config/movable-view.js +1 -8
- package/lib/platform/template/wx/component-config/scroll-view.js +1 -1
- package/lib/resolver/AddEnvPlugin.js +0 -1
- package/lib/resolver/AddModePlugin.js +0 -1
- package/lib/runtime/components/react/context.ts +0 -8
- package/lib/runtime/components/react/getInnerListeners.ts +5 -3
- package/lib/runtime/components/react/mpx-input.tsx +1 -1
- package/lib/runtime/components/react/mpx-movable-view.tsx +1 -1
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +159 -177
- package/lib/runtime/components/react/mpx-picker-view.tsx +37 -35
- package/lib/runtime/components/react/mpx-rich-text/index.tsx +18 -12
- package/lib/runtime/components/react/mpx-scroll-view.tsx +13 -30
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +527 -0
- package/lib/runtime/components/react/mpx-swiper/index.tsx +80 -0
- package/lib/runtime/components/react/mpx-swiper/type.ts +87 -0
- package/lib/runtime/components/react/mpx-swiper-item.tsx +10 -38
- package/lib/runtime/components/react/mpx-view.tsx +51 -11
- package/lib/runtime/components/react/mpx-web-view.tsx +13 -57
- package/lib/runtime/components/react/pickerFaces.ts +7 -15
- package/lib/runtime/components/react/{pickerViewOverlay.tsx → pickerOverlay.tsx} +3 -5
- package/lib/runtime/components/react/types/global.d.ts +1 -3
- package/lib/runtime/components/react/useAnimationHooks.ts +1 -1
- package/lib/runtime/components/react/utils.tsx +5 -75
- package/lib/style-compiler/index.js +4 -3
- package/lib/template-compiler/compiler.js +14 -9
- package/lib/utils/hump-dash.js +1 -1
- package/lib/utils/pre-process-json.js +9 -5
- package/package.json +1 -1
- package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +0 -88
- package/lib/runtime/components/react/mpx-swiper.tsx +0 -690
- package/lib/runtime/components/react/pickerVIewContext.ts +0 -18
- package/lib/runtime/components/react/pickerViewMask.tsx +0 -30
- package/lib/style-compiler/strip-conditional-loader.js +0 -118
package/lib/index.js
CHANGED
|
@@ -54,13 +54,11 @@ const wxssLoaderPath = normalize.lib('wxss/index')
|
|
|
54
54
|
const wxmlLoaderPath = normalize.lib('wxml/loader')
|
|
55
55
|
const wxsLoaderPath = normalize.lib('wxs/loader')
|
|
56
56
|
const styleCompilerPath = normalize.lib('style-compiler/index')
|
|
57
|
-
const styleStripConditaionalPath = normalize.lib('style-compiler/strip-conditional-loader')
|
|
58
57
|
const templateCompilerPath = normalize.lib('template-compiler/index')
|
|
59
58
|
const jsonCompilerPath = normalize.lib('json-compiler/index')
|
|
60
59
|
const jsonThemeCompilerPath = normalize.lib('json-compiler/theme')
|
|
61
60
|
const jsonPluginCompilerPath = normalize.lib('json-compiler/plugin')
|
|
62
61
|
const extractorPath = normalize.lib('extractor')
|
|
63
|
-
const selectorPath = normalize.lib('selector')
|
|
64
62
|
const async = require('async')
|
|
65
63
|
const { parseQuery } = require('loader-utils')
|
|
66
64
|
const stringifyLoadersAndResource = require('./utils/stringify-loaders-resource')
|
|
@@ -1777,7 +1775,7 @@ try {
|
|
|
1777
1775
|
})
|
|
1778
1776
|
|
|
1779
1777
|
const typeLoaderProcessInfo = {
|
|
1780
|
-
styles: ['node_modules/css-loader', wxssLoaderPath, styleCompilerPath
|
|
1778
|
+
styles: ['node_modules/css-loader', wxssLoaderPath, styleCompilerPath],
|
|
1781
1779
|
template: ['node_modules/html-loader', wxmlLoaderPath, templateCompilerPath]
|
|
1782
1780
|
}
|
|
1783
1781
|
|
|
@@ -1835,20 +1833,6 @@ try {
|
|
|
1835
1833
|
loader: extractorPath
|
|
1836
1834
|
})
|
|
1837
1835
|
}
|
|
1838
|
-
if (type === 'styles') {
|
|
1839
|
-
// 判断最后一个loader是否是 selectorPath, 如果是,则在sectorPath之前插入strip-conditional
|
|
1840
|
-
const lastLoader = loaders[loaders.length - 1]
|
|
1841
|
-
if (lastLoader.loader.includes(selectorPath)) {
|
|
1842
|
-
loaders.splice(loaders.length - 1, 0, {
|
|
1843
|
-
loader: styleStripConditaionalPath
|
|
1844
|
-
})
|
|
1845
|
-
} else {
|
|
1846
|
-
// 在最后一个插入strip-conditional
|
|
1847
|
-
loaders.push({
|
|
1848
|
-
loader: styleStripConditaionalPath
|
|
1849
|
-
})
|
|
1850
|
-
}
|
|
1851
|
-
}
|
|
1852
1836
|
createData.resource = addQuery(createData.resource, { mpx: MPX_PROCESSED_FLAG }, true)
|
|
1853
1837
|
}
|
|
1854
1838
|
// mpxStyleOptions 为 mpx style 文件的标识,避免 Vue 文件插入 styleCompiler 后导致 vue scoped 样式隔离失效
|
|
@@ -374,11 +374,11 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
374
374
|
// transform 转换
|
|
375
375
|
const formatTransform = ({ prop, value, selector }, { mode }) => {
|
|
376
376
|
// css var & 数组直接返回
|
|
377
|
-
if (Array.isArray(value) ||
|
|
377
|
+
if (Array.isArray(value) || calcExp.test(value)) return { prop, value }
|
|
378
378
|
const values = parseValues(value)
|
|
379
379
|
const transform = []
|
|
380
380
|
values.forEach(item => {
|
|
381
|
-
const match = item.match(/([/\w]+)\((
|
|
381
|
+
const match = item.match(/([/\w]+)\(([^)]+)\)/)
|
|
382
382
|
if (match && match.length >= 3) {
|
|
383
383
|
let key = match[1]
|
|
384
384
|
const val = match[2]
|
|
@@ -407,23 +407,23 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
407
407
|
case 'rotate3d': // x y z angle
|
|
408
408
|
case 'translate3d': // x y 支持 z不支持
|
|
409
409
|
case 'scale3d': // x y 支持 z不支持
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
}
|
|
418
|
-
const xyz = ['X', 'Y', 'Z']
|
|
419
|
-
transform.push(...vals.map((v, index) => {
|
|
420
|
-
if (key !== 'rotate' && index > 1) {
|
|
421
|
-
unsupportedPropError({ prop: `${key}Z`, value, selector }, { mode })
|
|
410
|
+
{
|
|
411
|
+
// 2 个以上的值处理
|
|
412
|
+
key = key.replace('3d', '')
|
|
413
|
+
const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3)
|
|
414
|
+
// scale(.5) === scaleX(.5) scaleY(.5)
|
|
415
|
+
if (vals.length === 1 && key === 'scale') {
|
|
416
|
+
vals.push(vals[0])
|
|
422
417
|
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
418
|
+
const xyz = ['X', 'Y', 'Z']
|
|
419
|
+
transform.push(...vals.map((v, index) => {
|
|
420
|
+
if (key !== 'rotate' && index > 1) {
|
|
421
|
+
unsupportedPropError({ prop: `${key}Z`, value, selector }, { mode })
|
|
422
|
+
}
|
|
423
|
+
return { [`${key}${xyz[index] || ''}`]: v.trim() }
|
|
424
|
+
}))
|
|
425
|
+
break
|
|
426
|
+
}
|
|
427
427
|
case 'translateZ':
|
|
428
428
|
case 'scaleZ':
|
|
429
429
|
default:
|
|
@@ -2,8 +2,6 @@ const TAG_NAME = 'movable-view'
|
|
|
2
2
|
|
|
3
3
|
module.exports = function ({ print }) {
|
|
4
4
|
const aliEventLog = print({ platform: 'ali', tag: TAG_NAME, isError: false, type: 'event' })
|
|
5
|
-
const androidEventLog = print({ platform: 'android', tag: TAG_NAME, isError: false, type: 'event' })
|
|
6
|
-
const iosEventLog = print({ platform: 'ios', tag: TAG_NAME, isError: false, type: 'event' })
|
|
7
5
|
const qaPropLog = print({ platform: 'qa', tag: TAG_NAME, isError: false })
|
|
8
6
|
const androidPropLog = print({ platform: 'android', tag: TAG_NAME, isError: false })
|
|
9
7
|
const iosPropLog = print({ platform: 'ios', tag: TAG_NAME, isError: false })
|
|
@@ -29,7 +27,7 @@ module.exports = function ({ print }) {
|
|
|
29
27
|
android: androidPropLog
|
|
30
28
|
},
|
|
31
29
|
{
|
|
32
|
-
test: /^(damping|
|
|
30
|
+
test: /^(inertia|damping|animation)$/,
|
|
33
31
|
ios: iosPropLog,
|
|
34
32
|
android: androidPropLog
|
|
35
33
|
}
|
|
@@ -38,11 +36,6 @@ module.exports = function ({ print }) {
|
|
|
38
36
|
{
|
|
39
37
|
test: /^(htouchmove|vtouchmove)$/,
|
|
40
38
|
ali: aliEventLog
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
test: /^(bindscale)$/,
|
|
44
|
-
ios: iosEventLog,
|
|
45
|
-
android: androidEventLog
|
|
46
39
|
}
|
|
47
40
|
]
|
|
48
41
|
}
|
|
@@ -53,7 +53,7 @@ module.exports = function ({ print }) {
|
|
|
53
53
|
qa: qaPropLog
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
|
-
test: /^(refresher-threshold|enable-passive|scroll-anchoring|using-sticky|fast-deceleration|enable-flex)$/,
|
|
56
|
+
test: /^(scroll-into-view|refresher-threshold|enable-passive|scroll-anchoring|using-sticky|fast-deceleration|enable-flex)$/,
|
|
57
57
|
android: androidPropLog,
|
|
58
58
|
ios: iosPropLog
|
|
59
59
|
},
|
|
@@ -34,7 +34,6 @@ module.exports = class AddEnvPlugin {
|
|
|
34
34
|
if (!extname || !matchCondition(resourcePath, this.fileConditionRules)) return callback()
|
|
35
35
|
const queryObj = parseQuery(request.query || '?')
|
|
36
36
|
queryObj.infix = `${queryObj.infix || ''}.${env}`
|
|
37
|
-
// css | stylus | less | sass 中 import file 过滤query,避免在对应的 loader 中无法读取到文件
|
|
38
37
|
obj.query = stringifyQuery(queryObj)
|
|
39
38
|
obj.path = addInfix(resourcePath, env, extname)
|
|
40
39
|
obj.relativePath = request.relativePath && addInfix(request.relativePath, env, extname)
|
|
@@ -43,7 +43,6 @@ module.exports = class AddModePlugin {
|
|
|
43
43
|
resolver.doResolve(target, Object.assign({}, request, obj), 'add mode: ' + mode, resolveContext, (err, result) => {
|
|
44
44
|
if (defaultMode && !result) {
|
|
45
45
|
queryObj.infix = `${queryInfix || ''}.${defaultMode}`
|
|
46
|
-
// css | stylus | less | sass 中 import file 过滤query,避免在对应的 loader 中无法读取到文件
|
|
47
46
|
obj.query = stringifyQuery(queryObj)
|
|
48
47
|
obj.path = addInfix(resourcePath, defaultMode, extname)
|
|
49
48
|
resolver.doResolve(target, Object.assign({}, request, obj), 'add mode: ' + defaultMode, resolveContext, (err, result) => {
|
|
@@ -33,10 +33,6 @@ export interface IntersectionObserver {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export interface ScrollViewContextValue {
|
|
37
|
-
gestureRef: React.RefObject<any> | null
|
|
38
|
-
}
|
|
39
|
-
|
|
40
36
|
export const MovableAreaContext = createContext({ width: 0, height: 0 })
|
|
41
37
|
|
|
42
38
|
export const FormContext = createContext<FormContextValue | null>(null)
|
|
@@ -55,8 +51,4 @@ export const IntersectionObserverContext = createContext<IntersectionObserver |
|
|
|
55
51
|
|
|
56
52
|
export const RouteContext = createContext<number | null>(null)
|
|
57
53
|
|
|
58
|
-
export const SwiperContext = createContext({})
|
|
59
|
-
|
|
60
54
|
export const KeyboardAvoidContext = createContext<KeyboardAvoidContextValue | null>(null)
|
|
61
|
-
|
|
62
|
-
export const ScrollViewContext = createContext<ScrollViewContextValue>({ gestureRef: null })
|
|
@@ -289,6 +289,7 @@ const useInnerProps = (
|
|
|
289
289
|
const eventConfig: { [key: string]: string[] } = {}
|
|
290
290
|
const config = rawConfig || {
|
|
291
291
|
layoutRef: { current: {} },
|
|
292
|
+
disableTouch: false,
|
|
292
293
|
disableTap: false
|
|
293
294
|
}
|
|
294
295
|
const removeProps = [
|
|
@@ -316,10 +317,11 @@ const useInnerProps = (
|
|
|
316
317
|
}
|
|
317
318
|
}
|
|
318
319
|
|
|
320
|
+
if (!rawEventKeys.length || config.disableTouch) {
|
|
321
|
+
return omit(propsRef.current, removeProps)
|
|
322
|
+
}
|
|
323
|
+
|
|
319
324
|
const events = useMemo(() => {
|
|
320
|
-
if (!rawEventKeys.length) {
|
|
321
|
-
return {}
|
|
322
|
-
}
|
|
323
325
|
const transformedEventKeys = rawEventKeys.reduce((acc: string[], key) => {
|
|
324
326
|
if (propsRef.current[key]) {
|
|
325
327
|
return acc.concat(eventConfig[key])
|
|
@@ -149,7 +149,7 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
|
|
|
149
149
|
'parent-font-size': parentFontSize,
|
|
150
150
|
'parent-width': parentWidth,
|
|
151
151
|
'parent-height': parentHeight,
|
|
152
|
-
'adjust-position': adjustPosition =
|
|
152
|
+
'adjust-position': adjustPosition = true,
|
|
153
153
|
bindinput,
|
|
154
154
|
bindfocus,
|
|
155
155
|
bindblur,
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious
|
|
1
|
+
|
|
2
|
+
import { View, Animated, SafeAreaView, NativeScrollEvent, NativeSyntheticEvent, LayoutChangeEvent, ScrollView } from 'react-native'
|
|
3
|
+
import React, { forwardRef, useRef, useState, useMemo, useCallback, useEffect } from 'react'
|
|
4
|
+
import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout, usePrevious } from './utils'
|
|
5
5
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import MpxPickerVIewColumnItem from './mpx-picker-view-column-item'
|
|
9
|
-
import { PickerViewColumnAnimationContext } from './pickerVIewContext'
|
|
6
|
+
import { createFaces } from './pickerFaces'
|
|
7
|
+
import PickerOverlay from './pickerOverlay'
|
|
10
8
|
|
|
11
9
|
interface ColumnProps {
|
|
12
10
|
children?: React.ReactNode
|
|
13
11
|
columnData: React.ReactNode[]
|
|
14
|
-
columnStyle: Record<string, any>
|
|
15
12
|
initialIndex: number
|
|
13
|
+
onColumnItemRawHChange: Function
|
|
14
|
+
getInnerLayout: Function
|
|
16
15
|
onSelectChange: Function
|
|
17
16
|
style: {
|
|
18
17
|
[key: string]: any
|
|
@@ -23,23 +22,25 @@ interface ColumnProps {
|
|
|
23
22
|
height: number
|
|
24
23
|
itemHeight: number
|
|
25
24
|
}
|
|
26
|
-
pickerMaskStyle: Record<string, any>
|
|
27
25
|
pickerOverlayStyle: Record<string, any>
|
|
28
26
|
columnIndex: number
|
|
29
27
|
}
|
|
30
28
|
|
|
29
|
+
// 默认的单个选项高度
|
|
30
|
+
const DefaultPickerItemH = 36
|
|
31
|
+
// 默认一屏可见选项个数
|
|
31
32
|
const visibleCount = 5
|
|
32
33
|
|
|
33
34
|
const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>, ColumnProps>((props: ColumnProps, ref) => {
|
|
34
35
|
const {
|
|
35
36
|
columnData,
|
|
36
37
|
columnIndex,
|
|
37
|
-
columnStyle,
|
|
38
38
|
initialIndex,
|
|
39
39
|
onSelectChange,
|
|
40
|
+
onColumnItemRawHChange,
|
|
41
|
+
getInnerLayout,
|
|
40
42
|
style,
|
|
41
43
|
wrapperStyle,
|
|
42
|
-
pickerMaskStyle,
|
|
43
44
|
pickerOverlayStyle,
|
|
44
45
|
'enable-var': enableVar,
|
|
45
46
|
'external-var-context': externalVarContext
|
|
@@ -53,42 +54,27 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
53
54
|
setWidth,
|
|
54
55
|
setHeight
|
|
55
56
|
} = useTransformStyle(style, { enableVar, externalVarContext })
|
|
56
|
-
const { textStyle
|
|
57
|
-
const { textStyle = {} } = splitStyle(normalStyle)
|
|
57
|
+
const { textStyle } = splitStyle(normalStyle)
|
|
58
58
|
const { textProps } = splitProps(props)
|
|
59
|
-
const scrollViewRef =
|
|
60
|
-
const offsetYShared = useScrollViewOffset(scrollViewRef as AnimatedRef<Reanimated.ScrollView>)
|
|
59
|
+
const scrollViewRef = useRef<ScrollView>(null)
|
|
61
60
|
|
|
62
|
-
useNodesRef(props, ref, scrollViewRef
|
|
61
|
+
useNodesRef(props, ref, scrollViewRef, {
|
|
63
62
|
style: normalStyle
|
|
64
63
|
})
|
|
65
64
|
|
|
66
|
-
const { height: pickerH, itemHeight } = wrapperStyle
|
|
67
|
-
const [itemRawH, setItemRawH] = useState(
|
|
65
|
+
const { height: pickerH, itemHeight = DefaultPickerItemH } = wrapperStyle
|
|
66
|
+
const [itemRawH, setItemRawH] = useState(0) // 单个选项真实渲染高度
|
|
68
67
|
const maxIndex = useMemo(() => columnData.length - 1, [columnData])
|
|
69
|
-
const prevScrollingInfo = useRef({ index: initialIndex, y: 0 })
|
|
70
68
|
const touching = useRef(false)
|
|
71
69
|
const scrolling = useRef(false)
|
|
72
70
|
const activeIndex = useRef(initialIndex)
|
|
73
71
|
const prevIndex = usePrevious(initialIndex)
|
|
74
72
|
const prevMaxIndex = usePrevious(maxIndex)
|
|
75
73
|
|
|
76
|
-
const {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
hasSelfPercent,
|
|
81
|
-
setWidth,
|
|
82
|
-
setHeight,
|
|
83
|
-
nodeRef: scrollViewRef
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
// console.log('[mpx-picker-view-column], render ---> columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'columnData=', columnData.length, 'pickerH=', pickerH, 'itemRawH=', itemRawH, 'itemHeight=', itemHeight)
|
|
87
|
-
|
|
88
|
-
const paddingHeight = useMemo(
|
|
89
|
-
() => Math.round((pickerH - itemHeight) / 2),
|
|
90
|
-
[pickerH, itemHeight]
|
|
91
|
-
)
|
|
74
|
+
const initialOffset = useMemo(() => ({
|
|
75
|
+
x: 0,
|
|
76
|
+
y: itemRawH * initialIndex
|
|
77
|
+
}), [itemRawH])
|
|
92
78
|
|
|
93
79
|
const snapToOffsets = useMemo(
|
|
94
80
|
() => columnData.map((_, i) => i * itemRawH),
|
|
@@ -96,34 +82,12 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
96
82
|
)
|
|
97
83
|
|
|
98
84
|
const contentContainerStyle = useMemo(() => {
|
|
99
|
-
return [
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}, [itemRawH, maxIndex])
|
|
106
|
-
|
|
107
|
-
const getYofIndex = useCallback((index: number) => {
|
|
108
|
-
return index * itemRawH
|
|
109
|
-
}, [itemRawH])
|
|
110
|
-
|
|
111
|
-
const stableResetScrollPosition = useStableCallback((y: number) => {
|
|
112
|
-
console.log('[mpx-picker-view-column], reset --->', 'columnIndex=', columnIndex, 'y=', y, touching.current, scrolling.current)
|
|
113
|
-
if (touching.current || scrolling.current) {
|
|
114
|
-
return
|
|
115
|
-
}
|
|
116
|
-
// needReset.current = true
|
|
117
|
-
if (y % itemRawH !== 0) {
|
|
118
|
-
scrolling.current = true
|
|
119
|
-
const targetIndex = getIndex(y)
|
|
120
|
-
const targetY = getYofIndex(targetIndex)
|
|
121
|
-
scrollViewRef.current?.scrollTo({ x: 0, y: targetY, animated: false })
|
|
122
|
-
} else {
|
|
123
|
-
onMomentumScrollEnd({ nativeEvent: { contentOffset: { y } } })
|
|
124
|
-
}
|
|
125
|
-
})
|
|
126
|
-
const debounceResetScrollPosition = useDebounceCallback(stableResetScrollPosition, 10)
|
|
85
|
+
return [
|
|
86
|
+
{
|
|
87
|
+
paddingVertical: Math.round(pickerH - itemRawH) / 2
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}, [pickerH, itemRawH])
|
|
127
91
|
|
|
128
92
|
useEffect(() => {
|
|
129
93
|
if (
|
|
@@ -138,170 +102,188 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
|
|
|
138
102
|
) {
|
|
139
103
|
return
|
|
140
104
|
}
|
|
141
|
-
|
|
142
|
-
scrollViewRef.current?.scrollTo({
|
|
143
|
-
x: 0,
|
|
144
|
-
y: getYofIndex(initialIndex),
|
|
145
|
-
animated: false
|
|
146
|
-
})
|
|
147
|
-
}, isAndroid ? 200 : 0)
|
|
105
|
+
|
|
148
106
|
activeIndex.current = initialIndex
|
|
107
|
+
scrollViewRef.current.scrollTo({
|
|
108
|
+
x: 0,
|
|
109
|
+
y: itemRawH * initialIndex,
|
|
110
|
+
animated: false
|
|
111
|
+
})
|
|
149
112
|
}, [itemRawH, initialIndex])
|
|
150
113
|
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
114
|
+
const onScrollViewLayout = () => {
|
|
115
|
+
getInnerLayout && getInnerLayout(layoutRef)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const {
|
|
119
|
+
layoutRef,
|
|
120
|
+
layoutProps
|
|
121
|
+
} = useLayout({
|
|
122
|
+
props,
|
|
123
|
+
hasSelfPercent,
|
|
124
|
+
setWidth,
|
|
125
|
+
setHeight,
|
|
126
|
+
nodeRef: scrollViewRef,
|
|
127
|
+
onLayout: onScrollViewLayout
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
const onContentSizeChange = (w: number, h: number) => {
|
|
131
|
+
scrollViewRef.current?.scrollTo({
|
|
132
|
+
x: 0,
|
|
133
|
+
y: itemRawH * initialIndex,
|
|
134
|
+
animated: false
|
|
135
|
+
})
|
|
158
136
|
}
|
|
159
137
|
|
|
160
138
|
const onItemLayout = (e: LayoutChangeEvent) => {
|
|
161
139
|
const { height: rawH } = e.nativeEvent.layout
|
|
162
140
|
if (rawH && itemRawH !== rawH) {
|
|
163
141
|
setItemRawH(rawH)
|
|
142
|
+
onColumnItemRawHChange(rawH)
|
|
164
143
|
}
|
|
165
144
|
}
|
|
166
145
|
|
|
167
|
-
const
|
|
168
|
-
isIOS && debounceResetScrollPosition.clear()
|
|
146
|
+
const onTouchStart = () => {
|
|
169
147
|
touching.current = true
|
|
170
|
-
prevScrollingInfo.current = {
|
|
171
|
-
index: activeIndex.current,
|
|
172
|
-
y: getYofIndex(activeIndex.current)
|
|
173
|
-
}
|
|
174
148
|
}
|
|
175
149
|
|
|
176
|
-
const
|
|
150
|
+
const onTouchEnd = () => {
|
|
151
|
+
touching.current = false
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const onTouchCancel = () => {
|
|
177
155
|
touching.current = false
|
|
178
|
-
const { y } = e.nativeEvent.contentOffset
|
|
179
|
-
if (isIOS) {
|
|
180
|
-
if (y > 0 && y < snapToOffsets[maxIndex]) {
|
|
181
|
-
debounceResetScrollPosition(y)
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
156
|
}
|
|
185
157
|
|
|
186
158
|
const onMomentumScrollBegin = () => {
|
|
187
|
-
isIOS && debounceResetScrollPosition.clear()
|
|
188
159
|
scrolling.current = true
|
|
189
160
|
}
|
|
190
161
|
|
|
191
|
-
const onMomentumScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent>
|
|
162
|
+
const onMomentumScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
192
163
|
scrolling.current = false
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
return debounceResetScrollPosition(scrollY)
|
|
164
|
+
if (!itemRawH) {
|
|
165
|
+
return
|
|
196
166
|
}
|
|
197
|
-
const
|
|
167
|
+
const { y: scrollY } = e.nativeEvent.contentOffset
|
|
168
|
+
let calcIndex = Math.round(scrollY / itemRawH)
|
|
198
169
|
activeIndex.current = calcIndex
|
|
199
170
|
if (calcIndex !== initialIndex) {
|
|
171
|
+
calcIndex = Math.max(0, Math.min(calcIndex, maxIndex)) || 0
|
|
200
172
|
onSelectChange(calcIndex)
|
|
201
173
|
}
|
|
202
174
|
}
|
|
203
175
|
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
176
|
+
const offsetY = useRef(new Animated.Value(0)).current
|
|
177
|
+
|
|
178
|
+
const onScroll = useMemo(
|
|
179
|
+
() =>
|
|
180
|
+
Animated.event([{ nativeEvent: { contentOffset: { y: offsetY } } }], {
|
|
181
|
+
useNativeDriver: true
|
|
182
|
+
}),
|
|
183
|
+
[offsetY]
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
const faces = useMemo(() => createFaces(itemRawH, visibleCount), [itemRawH])
|
|
187
|
+
|
|
188
|
+
const getTransform = useCallback(
|
|
189
|
+
(index: number) => {
|
|
190
|
+
const inputRange = faces.map((f) => itemRawH * (index + f.index))
|
|
191
|
+
return {
|
|
192
|
+
opacity: offsetY.interpolate({
|
|
193
|
+
inputRange: inputRange,
|
|
194
|
+
outputRange: faces.map((x) => x.opacity),
|
|
195
|
+
extrapolate: 'clamp'
|
|
196
|
+
}),
|
|
197
|
+
rotateX: offsetY.interpolate({
|
|
198
|
+
inputRange: inputRange,
|
|
199
|
+
outputRange: faces.map((x) => `${x.deg}deg`),
|
|
200
|
+
extrapolate: 'extend'
|
|
201
|
+
}),
|
|
202
|
+
translateY: offsetY.interpolate({
|
|
203
|
+
inputRange: inputRange,
|
|
204
|
+
outputRange: faces.map((x) => x.offsetY),
|
|
205
|
+
extrapolate: 'extend'
|
|
206
|
+
})
|
|
226
207
|
}
|
|
227
|
-
}
|
|
228
|
-
|
|
208
|
+
},
|
|
209
|
+
[offsetY, faces, itemRawH]
|
|
210
|
+
)
|
|
229
211
|
|
|
230
212
|
const renderInnerchild = () =>
|
|
231
|
-
columnData.map((item: React.
|
|
213
|
+
columnData.map((item: React.ReactNode, index: number) => {
|
|
214
|
+
const InnerProps = index === 0 ? { onLayout: onItemLayout } : {}
|
|
215
|
+
const strKey = `picker-column-${columnIndex}-${index}`
|
|
216
|
+
const { opacity, rotateX, translateY } = getTransform(index)
|
|
232
217
|
return (
|
|
233
|
-
<
|
|
234
|
-
key={
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
218
|
+
<Animated.View
|
|
219
|
+
key={strKey}
|
|
220
|
+
{...InnerProps}
|
|
221
|
+
style={[
|
|
222
|
+
{
|
|
223
|
+
height: itemHeight || DefaultPickerItemH,
|
|
224
|
+
width: '100%',
|
|
225
|
+
opacity,
|
|
226
|
+
transform: [
|
|
227
|
+
{ translateY },
|
|
228
|
+
{ rotateX },
|
|
229
|
+
{ perspective: 1000 } // 适配 Android
|
|
230
|
+
]
|
|
231
|
+
}
|
|
232
|
+
]}
|
|
233
|
+
>
|
|
234
|
+
{wrapChildren(
|
|
235
|
+
{ children: item },
|
|
236
|
+
{
|
|
237
|
+
hasVarDec,
|
|
238
|
+
varContext: varContextRef.current,
|
|
239
|
+
textStyle,
|
|
240
|
+
textProps
|
|
241
|
+
}
|
|
242
|
+
)}
|
|
243
|
+
</Animated.View>
|
|
246
244
|
)
|
|
247
245
|
})
|
|
248
246
|
|
|
249
247
|
const renderScollView = () => {
|
|
250
248
|
return (
|
|
251
|
-
<
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
</PickerViewColumnAnimationContext.Provider>
|
|
249
|
+
<Animated.ScrollView
|
|
250
|
+
ref={scrollViewRef}
|
|
251
|
+
bounces={true}
|
|
252
|
+
horizontal={false}
|
|
253
|
+
pagingEnabled={false}
|
|
254
|
+
nestedScrollEnabled={true}
|
|
255
|
+
removeClippedSubviews={true}
|
|
256
|
+
showsVerticalScrollIndicator={false}
|
|
257
|
+
showsHorizontalScrollIndicator={false}
|
|
258
|
+
{...layoutProps}
|
|
259
|
+
scrollEventThrottle={16}
|
|
260
|
+
contentContainerStyle={contentContainerStyle}
|
|
261
|
+
contentOffset={initialOffset}
|
|
262
|
+
snapToOffsets={snapToOffsets}
|
|
263
|
+
onContentSizeChange={onContentSizeChange}
|
|
264
|
+
onScroll={onScroll}
|
|
265
|
+
onTouchStart={onTouchStart}
|
|
266
|
+
onTouchEnd={onTouchEnd}
|
|
267
|
+
onTouchCancel={onTouchCancel}
|
|
268
|
+
onMomentumScrollBegin={onMomentumScrollBegin}
|
|
269
|
+
onMomentumScrollEnd={onMomentumScrollEnd}
|
|
270
|
+
>
|
|
271
|
+
{renderInnerchild()}
|
|
272
|
+
</Animated.ScrollView>
|
|
276
273
|
)
|
|
277
274
|
}
|
|
278
275
|
|
|
279
276
|
const renderOverlay = () => (
|
|
280
|
-
<PickerOverlay
|
|
281
|
-
itemHeight={itemHeight}
|
|
282
|
-
overlayItemStyle={pickerOverlayStyle}
|
|
283
|
-
/>
|
|
284
|
-
)
|
|
285
|
-
|
|
286
|
-
const renderMask = () => (
|
|
287
|
-
<PickerMask
|
|
288
|
-
itemHeight={itemHeight}
|
|
289
|
-
maskContainerStyle={pickerMaskStyle}
|
|
290
|
-
/>
|
|
277
|
+
<PickerOverlay itemHeight={itemHeight} overlayItemStyle={pickerOverlayStyle} />
|
|
291
278
|
)
|
|
292
279
|
|
|
293
280
|
return (
|
|
294
|
-
<SafeAreaView style={[
|
|
281
|
+
<SafeAreaView style={[{ display: 'flex', flex: 1 }]}>
|
|
295
282
|
{renderScollView()}
|
|
296
|
-
{renderMask()}
|
|
297
283
|
{renderOverlay()}
|
|
298
284
|
</SafeAreaView>
|
|
299
285
|
)
|
|
300
286
|
})
|
|
301
287
|
|
|
302
|
-
const styles = StyleSheet.create({
|
|
303
|
-
wrapper: { display: 'flex', flex: 1 }
|
|
304
|
-
})
|
|
305
|
-
|
|
306
288
|
_PickerViewColumn.displayName = 'MpxPickerViewColumn'
|
|
307
289
|
export default _PickerViewColumn
|