Skip to content

Commit

Permalink
Merge pull request #1659 from didi/feat-lyf-pickerview
Browse files Browse the repository at this point in the history
update wrapChildren
  • Loading branch information
xiao19880917lu authored Oct 17, 2024
2 parents 8107fa7 + d2bf9ae commit ca6baba
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

import { View, Animated, SafeAreaView, NativeScrollEvent, NativeSyntheticEvent, LayoutChangeEvent, ScrollView } from 'react-native'
import React, { forwardRef, useRef, useState, useEffect, ReactElement, ReactNode } from 'react'
import { VarContext } from './context'
import { useTransformStyle, splitStyle } from './utils'
import { useTransformStyle, splitStyle, splitProps } from './utils'
import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
import { wrapChildren } from './common'
interface ColumnProps {
children: React.ReactNode,
selectedIndex: number,
Expand Down Expand Up @@ -36,7 +36,9 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
setContainerWidth,
setContainerHeight
} = useTransformStyle(style, { enableVar, externalVarContext })
const { innerStyle } = splitStyle(normalStyle)
const { textStyle } = splitStyle(normalStyle)
const { textProps } = splitProps(props)
// const { innerStyle } = splitStyle(normalStyle)
// scrollView的ref
const { nodeRef: scrollViewRef } = useNodesRef(props, ref, {})
// scrollView的布局存储
Expand Down Expand Up @@ -103,6 +105,22 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
const strKey = 'picker' + props.prefix + '-column' + index
const arrHeight = (wrapperStyle.itemHeight + '').match(/\d+/g) || []
const iHeight = (arrHeight[0] || defaultItemHeight) as number
return <View key={strKey} {...InnerProps} style={[{ height: iHeight, width: '100%' }]}>
{wrapChildren(
{
children: item
},
{
hasVarDec,
varContext: varContextRef.current
},
{
textStyle,
textProps
}
)}
</View>
/*
if (hasVarDec && varContextRef.current) {
const wrapChild = (<VarContext.Provider value={varContextRef.current}>
<View key={strKey} {...InnerProps} style={[{ height: iHeight, width: '100%' }]}>{item}</View>
Expand All @@ -111,6 +129,7 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
} else {
return <View key={strKey} {...InnerProps} style={[{ height: iHeight, width: '100%' }]}>{item}</View>
}
*/
})
const totalHeight = itemH * 5
if (wrapperStyle.height && totalHeight !== wrapperStyle.height) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { LinearGradient, LinearGradientProps } from 'react-native-linear-gradien
import React, { forwardRef, MutableRefObject, useState, useRef, ReactElement, JSX } from 'react'
import useInnerProps, { getCustomEvent } from './getInnerListeners'
import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
import { VarContext } from './context'
import { parseInlineStyle, useTransformStyle } from './utils'
import { wrapChildren } from './common'
import { parseInlineStyle, useTransformStyle, splitStyle, splitProps } from './utils'
/**
* ✔ value
* ✔ bindchange
Expand Down Expand Up @@ -76,6 +76,8 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
setContainerWidth,
setContainerHeight
} = useTransformStyle(style, { enableVar, externalVarContext })
const { textStyle } = splitStyle(normalStyle)
const { textProps } = splitProps(props)

const isSetW = indicatorW !== undefined ? 1 : 0
const innerLayout = useRef({})
Expand Down Expand Up @@ -137,12 +139,19 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
...extraProps
}
const realElement = React.cloneElement(child as ReactElement, childProps)
if (hasVarDec && varContextRef.current) {
const wrapChild = <VarContext.Provider value={varContextRef.current}>{realElement}</VarContext.Provider>
return wrapChild
} else {
return realElement
}
return wrapChildren(
{
children: realElement
},
{
hasVarDec,
varContext: varContextRef.current
},
{
textStyle,
textProps
}
)
}

const renderTopMask = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ const _SwiperItem = forwardRef<HandlerRef<View, SwiperItemProps>, SwiperItemProp
'enable-offset': enableOffset,
'enable-var': enableVar,
'external-var-context': externalVarContext,
style,
children
style
} = props

const { textProps } = splitProps(props)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/**
* swiper 实现
*/
import { Animated, View, ScrollView, Dimensions, NativeSyntheticEvent, NativeScrollEvent, NativeScrollPoint, Platform } from 'react-native'
import { Animated, View, ScrollView, Dimensions, NativeSyntheticEvent, NativeScrollEvent, NativeScrollPoint, Platform, LayoutChangeEvent } from 'react-native'
import { JSX, forwardRef, useState, useRef, useEffect, ReactNode } from 'react'
import { CarouseProps, CarouseState } from './type'
import { getCustomEvent } from '../getInnerListeners'
import useNodesRef, { HandlerRef } from '../useNodesRef' // 引入辅助函数
import { VarContext } from '../context'
import { useTransformStyle } from '../utils'
import { useTransformStyle, splitStyle, splitProps } from '../utils'
import { wrapChildren } from '../common'

/**
* 默认的Style类型
Expand Down Expand Up @@ -48,7 +48,8 @@ const styles: { [key: string]: Object } = {
const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, CarouseProps>((props, ref): JSX.Element => {
// 默认取水平方向的width
const { width } = Dimensions.get('window')
const { styleObj, previousMargin = 0, nextMargin = 0, enableVar, externalVarContext } = props
const { style, previousMargin = 0, nextMargin = 0, enableVar, externalVarContext } = props
const styleObj = JSON.parse(JSON.stringify(style || ''))
const newChild = Array.isArray(props.children) ? props.children.filter(child => child) : props.children
const totalElements = Array.isArray(newChild) ? newChild.length : (newChild ? 1 : 0)
const defaultHeight = (styleObj?.height || 150)
Expand All @@ -71,6 +72,8 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
setContainerWidth,
setContainerHeight
} = useTransformStyle(styleObj, { enableVar, externalVarContext })
const { textStyle, innerStyle } = splitStyle(normalStyle)
const { textProps } = splitProps(props)
// 内部存储上一次的offset值
const autoplayTimerRef = useRef<ReturnType <typeof setTimeout> | null>(null)
const { nodeRef: scrollViewRef } = useNodesRef<ScrollView & View, CarouseProps>(props, ref, {
Expand Down Expand Up @@ -313,17 +316,18 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
/**
* @desc: 水平方向时,获取元素的布局,更新, 其中如果传递100%时需要依赖measure计算元算的宽高
*/
function onWrapperLayout () {
function onWrapperLayout (e: LayoutChangeEvent) {
if (hasPercent) {
const { width, height } = e?.nativeEvent?.layout || {}
setContainerWidth(width || 0)
setContainerHeight(height || 0)
}
if (props.enableOffset) {
scrollViewRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
const isWDiff = state.width !== width
const isHDiff = state.height !== height
if (isWDiff || isHDiff) {
if (hasPercent) {
setContainerWidth(width || 0)
setContainerHeight(height || 0)
}
const changeState = {
width: isWDiff ? width : state.width,
height: isHDiff ? height : state.height
Expand Down Expand Up @@ -352,12 +356,13 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
}

function renderScrollView (pages: ReactNode) {
// const offsetsArray = []
const scrollElementProps = {
ref: scrollViewRef,
horizontal: props.horizontal,
pagingEnabled: false,
// snapToOffsets: true,
decelerationRate: 0.99, // 'fast'
decelerationRate: 0.80, // 'fast'
showsHorizontalScrollIndicator: false,
showsVerticalScrollIndicator: false,
bounces: false,
Expand Down Expand Up @@ -447,17 +452,22 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
} else if (i === pages.length && typeof width === 'number') {
nextMargin && (extraStyle.marginRight = nextMargin)
}
const realElement = (
<View style={[pageStyle, styles.slide, extraStyle]} key={ 'page' + i}>
{children[+page]}
</View>
)
if (hasVarDec && varContextRef.current) {
const wrapChild = <VarContext.Provider value={varContextRef.current}>{realElement}</VarContext.Provider>
return wrapChild
} else {
return realElement
}
// return (<View style={[pageStyle, styles.slide, extraStyle]} key={ 'page' + i}>{children[+page]}</View>)
return (<View style={[pageStyle, styles.slide, extraStyle]} key={ 'page' + i}>
{wrapChildren(
{
children: children[+page]
},
{
hasVarDec,
varContext: varContextRef.current
},
{
textStyle,
textProps
}
)}
</View>)
})
return arrElements
} else {
Expand All @@ -466,24 +476,18 @@ const _Carouse = forwardRef<HandlerRef<ScrollView & View, CarouseProps>, Carouse
{children}
</View>
)
if (hasVarDec && varContextRef.current) {
const wrapChild = <VarContext.Provider value={varContextRef.current}>{realElement}</VarContext.Provider>
return wrapChild
} else {
return realElement
}
return realElement
}
}

const pages: Array<ReactNode> | ReactNode = renderPages()
const strStyle: string = 'container_' + state.dir
const eventProps = props.innerProps || {}
const layoutStyle = dir === 'x' ? { width: defaultWidth, height: defaultHeight } : { width: defaultWidth }
return (<View style={[layoutStyle]}>
return (<View style={[{ display: 'flex' }]} onLayout={onWrapperLayout}>
<View
style={[styles[strStyle], layoutStyle]}
{...eventProps}
onLayout={onWrapperLayout}>
{...eventProps}>
{renderScrollView(pages)}
</View>
<View>{props.showsPagination && renderPagination()}</View>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,39 @@ const _SwiperWrapper = forwardRef<HandlerRef<ScrollView, SwiperProps>, SwiperPro
dotColor: props['indicator-color'] || 'rgba(0, 0, 0, .3)',
activeDotColor: props['indicator-active-color'] || '#000000',
horizontal: props.vertical !== undefined ? !props.vertical : true,
styleObj: props.style || {},
previousMargin: props['previous-margin'] ? parseInt(props['previous-margin']) : 0,
nextMargin: props['next-margin'] ? parseInt(props['next-margin']) : 0,
enableOffset: props['enable-offset'] || true,
enableVar: props['enable-var'] || false,
style: props.style || {},
externalVarContext: props['external-var-context'],
bindchange: props.bindchange,
easingFunction: props['easing-function'] || 'default'
}
const { nodeRef } = useNodesRef<ScrollView, SwiperProps>(props, ref, {
})
const { nodeRef } = useNodesRef<ScrollView, SwiperProps>(props, ref, {})
const innerProps = useInnerProps(props, {
ref: nodeRef
}, [
'indicator-dots',
'indicator-color',
'indicator-active-color',
'previous-margin',
'next-margin'
'vertical',
'previous-margin',
'next-margin',
'enable-var',
'external-var-context',
'easing-function'
], { layoutRef: innerLayout })

const getInnerLayout = (layout: MutableRefObject<{}>) => {
innerLayout.current = layout.current
}

return <Carouse
getInnerLayout={getInnerLayout}
innerProps={innerProps}
{...innerProps}
{...swiperProp}>
{children}
</Carouse>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ export interface SwiperProps {
'indicator-color'?: string;
'indicator-active-color'?: string;
vertical?: boolean;
style?: Object;
style: {
[key: string]: any
};
'easing-function'?: EaseType;
'previous-margin'?: string;
'next-margin'?: string;
Expand Down Expand Up @@ -42,9 +44,8 @@ export interface CarouseProps {
bindchange?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void;
getInnerLayout: Function;
innerProps: Object;
styleObj: {
height?: number;
width?: number
style: {
[key: string]: any
};
enableVar: boolean;
externalVarContext?: Record<string, any>;
Expand Down

0 comments on commit ca6baba

Please sign in to comment.