Skip to content

Commit

Permalink
Merge pull request #1657 from didi/feat-lyf-pickerview
Browse files Browse the repository at this point in the history
picker-view & swiper fix & var percent
  • Loading branch information
xiao19880917lu authored Oct 16, 2024
2 parents f63c337 + 2ccddd9 commit 7747c4f
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
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 } from './utils'
// import { Reanimated } from 'react-native-reanimated';
import { useTransformStyle, splitStyle } from './utils'
import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
interface ColumnProps {
children: React.ReactNode,
Expand All @@ -29,20 +28,21 @@ const defaultItemHeight = 36
const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>, ColumnProps>((props: ColumnProps, ref) => {
const { children, selectedIndex, onColumnLayoutChange, onSelectChange, getInnerLayout, style, wrapperStyle, 'enable-var': enableVar, 'external-var-context': externalVarContext } = props
// PickerViewColumn
const { normalStyle, hasVarDec, varContextRef } = useTransformStyle(style, { enableVar, externalVarContext })
const {
normalStyle,
hasVarDec,
hasPercent,
varContextRef,
setContainerWidth,
setContainerHeight
} = useTransformStyle(style, { enableVar, externalVarContext })
const { innerStyle } = splitStyle(normalStyle)
// scrollView的ref
const { nodeRef: scrollViewRef } = useNodesRef(props, ref, {})
// scrollView的布局存储
const layoutRef = useRef({})
// 每个元素的高度
let [itemH, setItemH] = useState(0)
// scrollView内容的初始offset
/*
let [offset, setOffset] = useState({
x: 0,
y: 0
})
*/

useEffect(() => {
if (selectedIndex && itemH) {
Expand All @@ -51,7 +51,12 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
}
}, [selectedIndex, itemH])

const onScrollViewLayout = () => {
const onScrollViewLayout = (res: LayoutChangeEvent) => {
if (hasPercent) {
const { width, height } = res?.nativeEvent?.layout || {}
setContainerWidth(width || 0)
setContainerHeight(height || 0)
}
scrollViewRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
getInnerLayout && getInnerLayout(layoutRef)
Expand Down Expand Up @@ -97,17 +102,15 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
const InnerProps = index === 0 ? { onLayout: onItemLayout } : {}
const strKey = 'picker' + props.prefix + '-column' + index
const arrHeight = (wrapperStyle.itemHeight + '').match(/\d+/g) || []
const iHeight = arrHeight[0] || defaultItemHeight

const iHeight = (arrHeight[0] || defaultItemHeight) as number
if (hasVarDec && varContextRef.current) {
const wrapChild = (<VarContext.Provider value={varContextRef.current}>
<View key={strKey} {...InnerProps} style={[{ height: iHeight }, normalStyle]}>{item}</View>
<View key={strKey} {...InnerProps} style={[{ height: iHeight, width: '100%' }]}>{item}</View>
</VarContext.Provider>)
return wrapChild
} else {
return <View key={strKey} {...InnerProps} style={[{ height: iHeight }, normalStyle]}>{item}</View>
return <View key={strKey} {...InnerProps} style={[{ height: iHeight, width: '100%' }]}>{item}</View>
}
// return <View key={strKey} {...InnerProps} {...normalStyle} style={[{ height: iHeight }]}>{item}</View>
})
const totalHeight = itemH * 5
if (wrapperStyle.height && totalHeight !== wrapperStyle.height) {
Expand All @@ -126,10 +129,6 @@ const _PickerViewColumn = forwardRef<HandlerRef<ScrollView & View, ColumnProps>,
}

const renderScollView = () => {
const contentContainerStyle = {
textAlign: 'center'
}

return (<Animated.ScrollView
horizontal={false}
ref={scrollViewRef}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { View } from 'react-native'
import { View, LayoutChangeEvent } from 'react-native'
import { LinearGradient, LinearGradientProps } from 'react-native-linear-gradient'
import React, { forwardRef, MutableRefObject, useState, useRef, ReactElement, JSX } from 'react'
import useInnerProps, { getCustomEvent } from './getInnerListeners'
import { VarContext } from './context'
import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
import { VarContext } from './context'
import { parseInlineStyle, useTransformStyle } from './utils'
/**
* ✔ value
Expand All @@ -27,7 +27,8 @@ interface PickerViewProps {
}
'indicator-style'?: string
'enable-var': boolean
'external-var-context'?: Record<string, any>
'external-var-context'?: Record<string, any>,
'enable-offset': boolean
}

interface PickerLayout {
Expand Down Expand Up @@ -66,9 +67,16 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
// 微信设置到pick-view上上设置的normalStyle如border等需要转换成RN的style然后进行透传
const indicatorStyle = parseInlineStyle(props['indicator-style'])
const { height: indicatorH, width: indicatorW } = indicatorStyle
// const { normalStyle: lineStyle} = useTransformStyle(indicatorStyle, { enableVar, externalVarContext})
// picker-view 设置的color等textStyle,在小程序上的表现是可以继承到最内层的text样式, 但是RN内部column是slot无法设置, 需要业务自己在column内的元素上设置
const { normalStyle, hasVarDec, varContextRef } = useTransformStyle(style, { enableVar, externalVarContext })
const {
normalStyle,
hasVarDec,
varContextRef,
hasPercent,
setContainerWidth,
setContainerHeight
} = useTransformStyle(style, { enableVar, externalVarContext })

const isSetW = indicatorW !== undefined ? 1 : 0
const innerLayout = useRef({})
const cloneRef = useRef(null)
Expand All @@ -81,11 +89,8 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
} else {
maskPos.height = itemH * 2
}

const { nodeRef } = useNodesRef<View, PickerViewProps>(props, ref, {})

// value 如何关联picker-view-column这几个slot的内容呢

const onColumnLayoutChange = (layoutConfig: PickerLayout) => {
pickH = layoutConfig.height
setPickH(layoutConfig.height)
Expand All @@ -97,18 +102,23 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
const eventData = getCustomEvent('change', {}, { detail: { value: changeValue, source: 'change' }, layoutRef: innerLayout })
bindchange && bindchange(eventData)
}
/*
const onWrapperLayout = () => {
wrapRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
const a = { x, y, width, height, offsetLeft, offsetTop }
})
}
*/

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

const innerProps = useInnerProps(props, { ref: nodeRef }, [], { layoutRef: innerLayout })
const onWrapperLayout = (res: LayoutChangeEvent) => {
if (hasPercent) {
const { width, height } = res?.nativeEvent?.layout || {}
setContainerWidth(width || 0)
setContainerHeight(height || 0)
}
}

const innerProps = useInnerProps(props, { ref: nodeRef }, [
'style',
'enable-offset'
], { layoutRef: innerLayout })

const cloneChild = (child: React.ReactNode, index: number) => {
const extraProps = index === 0 ? { getInnerLayout: getInnerLayout, innerProps } : {}
Expand All @@ -133,7 +143,6 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
} else {
return realElement
}
// return React.cloneElement(child as ReactElement, childProps)
}

const renderTopMask = () => {
Expand Down Expand Up @@ -190,7 +199,7 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
}
}

return (<View style={[normalStyle, { position: 'relative', overflow: 'hidden' }]} ref={wrapRef}>
return (<View style={[normalStyle, { position: 'relative', overflow: 'hidden' }]} ref={wrapRef} onLayout={onWrapperLayout}>
{renderTopMask()}
<View style={[styles.wrapper]}>
{renderSubChild()}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,53 @@
import { View } from 'react-native'
import { View, LayoutChangeEvent } from 'react-native'
import { ReactNode, forwardRef, useRef } from 'react'
import useInnerProps from './getInnerListeners'
import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
import { wrapChildren } from './common'
import { useTransformStyle, splitStyle, splitProps } from './utils'

interface SwiperItemProps {
'item-id'?: string;
'enable-offset'?: boolean;
'enable-var': boolean;
'external-var-context'?: Record<string, any>;
children?: ReactNode;
style?: Object;
}

const _SwiperItem = forwardRef<HandlerRef<View, SwiperItemProps>, SwiperItemProps>((props: SwiperItemProps, ref) => {
const { children, 'enable-offset': enableOffset, style } = props
const {
'enable-offset': enableOffset,
'enable-var': enableVar,
'external-var-context': externalVarContext,
style,
children
} = props

const { textProps } = splitProps(props)
const layoutRef = useRef({})
const { nodeRef } = useNodesRef(props, ref, {})

const onLayout = () => {
nodeRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
})
const {
normalStyle,
hasVarDec,
varContextRef,
hasPercent,
setContainerWidth,
setContainerHeight
} = useTransformStyle(style, { enableVar, externalVarContext })
const { textStyle } = splitStyle(normalStyle)

const onLayout = (e: LayoutChangeEvent) => {
if (hasPercent) {
const { width, height } = e?.nativeEvent?.layout || {}
setContainerWidth(width || 0)
setContainerHeight(height || 0)
}
if (enableOffset) {
nodeRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
})
}
}

const innerProps = useInnerProps(props, {
Expand All @@ -34,7 +63,19 @@ const _SwiperItem = forwardRef<HandlerRef<View, SwiperItemProps>, SwiperItemProp
data-itemId={props['item-id']}
style={[style]}
{...innerProps}>
{children}
{
wrapChildren(
props,
{
hasVarDec,
varContext: varContextRef.current
},
{
textStyle,
textProps
}
)
}
</View>
)
})
Expand Down
Loading

0 comments on commit 7747c4f

Please sign in to comment.