From 4af9be0ba1bbe55634c7dd25a1c3cb9581733992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E5=9D=A4?= Date: Tue, 16 Jul 2024 13:53:35 +0800 Subject: [PATCH] [5.2.0-rc.2]feat: Slider support popover --- components/slider/PropsType.tsx | 5 ++--- components/slider/demo/basic.tsx | 5 +++++ components/slider/index.en-US.md | 2 ++ components/slider/index.zh-CN.md | 2 ++ components/slider/slider.tsx | 4 ++-- components/slider/thumb.tsx | 37 +++++++++++++++++++++++++++----- 6 files changed, 45 insertions(+), 10 deletions(-) diff --git a/components/slider/PropsType.tsx b/components/slider/PropsType.tsx index e2caf4d7..588a5794 100644 --- a/components/slider/PropsType.tsx +++ b/components/slider/PropsType.tsx @@ -20,9 +20,8 @@ export type SliderProps = { disabled?: boolean range?: boolean icon?: ReactNode - // TODO-luokun - // popover?: boolean | ((value: number) => ReactNode) - // residentPopover?: boolean + popover?: boolean | ((value: number) => ReactNode) + residentPopover?: boolean onChange?: (value: SliderValue) => void onAfterChange?: (value: SliderValue) => void style?: StyleProp diff --git a/components/slider/demo/basic.tsx b/components/slider/demo/basic.tsx index 55fa2f9f..facf3be1 100644 --- a/components/slider/demo/basic.tsx +++ b/components/slider/demo/basic.tsx @@ -56,6 +56,11 @@ export default function StepperExample() { + + + + + ) } diff --git a/components/slider/index.en-US.md b/components/slider/index.en-US.md index 16f3539c..0db6079f 100644 --- a/components/slider/index.en-US.md +++ b/components/slider/index.en-US.md @@ -23,6 +23,8 @@ A Slider component for selecting particular value in range, eg: controls the dis | min | Min value | `number` | `0` | | | onAfterChange | Consistent with the trigger timing of `touchend`, pass the current value as a parameter | `(value: number | [number, number]) => void` | - | | | onChange | Triggered when the slider is dragged, and the current dragged value is passed in as a parameter | `(value: number | [number, number]) => void` | - | | +| popover | Whether to display the popover when dragging. Support passing in function to customize the rendering content. | `boolean | ((value: number) => ReactNode)` | `false` | `5.2.0` | +| residentPopover | Whether the `popover` is permanently displayed , this attribute takes effect when `popover` exists | `boolean ` | `false` | `5.2.0` | | range | Whether it is a double sliders | `boolean` | `false` | `5.2.0` | | step | Step distance, the value must be greater than `0`, and `(max-min)` can be divisible by `step`. When `marks` is not null, the configuration of `step` is invalid | `number` | `1` | `5.2.0` | | ticks | Whether to display the scale | `boolean` | `false` | `5.2.0` | diff --git a/components/slider/index.zh-CN.md b/components/slider/index.zh-CN.md index a9923c52..67b85c39 100644 --- a/components/slider/index.zh-CN.md +++ b/components/slider/index.zh-CN.md @@ -24,6 +24,8 @@ version: 5.2.0-rc.1 | min | 最小值 | `number` | `0` | | | onAfterChange | 与 `touchend` 触发时机一致,把当前值作为参数传入 | `(value: number | [number, number]) => void` | - | | | onChange | 拖拽滑块时触发,并把当前拖拽的值作为参数传入 | `(value: number | [number, number]) => void` | - | | +| popover | 是否在拖动时显示悬浮提示,支持传入函数自定义渲染内容 | `boolean | ((value: number) => ReactNode)` | `false` | `5.2.0` | +| residentPopover | `popover` 是否常驻显示,`popover` 存在时生效 | `boolean ` | `false` | `5.2.0` | | range | 是否为双滑块 | `boolean` | `false` | `5.2.0` | | step | 步距,取值必须大于 `0`,并且 `(max - min)` 可被 `step` 整除。当 `marks` 不为空对象时,`step` 的配置失效 | `number` | `1` | `5.2.0` | | ticks | 是否显示刻度 | `boolean` | `false` | `5.2.0` | diff --git a/components/slider/slider.tsx b/components/slider/slider.tsx index c5a99a71..b97c0bb4 100644 --- a/components/slider/slider.tsx +++ b/components/slider/slider.tsx @@ -187,8 +187,8 @@ export const Slider: React.FC = (props) => { max={max} disabled={disabled} icon={icon} - // popover={!!props.popover} - // residentPopover={!!props.residentPopover} + popover={!!props.popover} + residentPopover={!!props.residentPopover} onDrag={(locationX, last) => { if (!trackLayout) { return diff --git a/components/slider/thumb.tsx b/components/slider/thumb.tsx index 81e5c1b4..e7a40364 100644 --- a/components/slider/thumb.tsx +++ b/components/slider/thumb.tsx @@ -4,10 +4,12 @@ import { LayoutChangeEvent, LayoutRectangle, StyleProp, + View, ViewStyle, } from 'react-native' import { Gesture, GestureDetector } from 'react-native-gesture-handler' import Animated, { runOnJS, useAnimatedStyle } from 'react-native-reanimated' +import Tooltip from '../tooltip' import { SliderStyle } from './style' import { ThumbIcon } from './thumb-icon' @@ -19,8 +21,8 @@ type ThumbProps = { trackLayout?: LayoutRectangle onDrag: (value: number, last?: boolean) => void icon?: ReactNode - // popover: boolean | ((value: number) => ReactNode) - // residentPopover: boolean + popover: boolean | ((value: number) => ReactNode) + residentPopover: boolean style?: StyleProp styles: Partial } @@ -33,6 +35,7 @@ const Thumb: FC = (props) => { trackLayout, disabled, icon, + residentPopover, onDrag, style, styles, @@ -53,16 +56,29 @@ const Thumb: FC = (props) => { setThumbLayout(e.nativeEvent.layout) } + const [dragging, setDragging] = useState(false) + const gesture = Gesture.Pan() .enabled(!disabled) - .onBegin(() => {}) .onUpdate((e) => { + !dragging && runOnJS(setDragging)(true) runOnJS(onDrag)(e.absoluteX - (thumbLayout?.width || 0)) }) .onEnd((e) => { runOnJS(onDrag)(e.absoluteX - (thumbLayout?.width || 0), true) }) - .onFinalize(() => {}) + .onFinalize(() => { + runOnJS(setDragging)(false) + }) + + const renderPopoverContent = + typeof props.popover === 'function' + ? props.popover + : props.popover + ? (val: number) => val.toString() + : null + + const thumbElement = icon ? icon : return ( @@ -70,7 +86,18 @@ const Thumb: FC = (props) => { onStartShouldSetResponder={() => true} style={[styles.thumb, animatedStyles, style]} onLayout={handleLayout}> - {icon ? icon : } + {renderPopoverContent ? ( + + {thumbElement} + + ) : ( + thumbElement + )} )