diff options
Diffstat (limited to 'src/ui/TooltipSlider.tsx')
| -rw-r--r-- | src/ui/TooltipSlider.tsx | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/ui/TooltipSlider.tsx b/src/ui/TooltipSlider.tsx new file mode 100644 index 0000000..0bb8350 --- /dev/null +++ b/src/ui/TooltipSlider.tsx @@ -0,0 +1,95 @@ +/** + * rc-tooltip tooltip slider + */ + +import * as React from "react"; +import "rc-tooltip/assets/bootstrap.css"; +import Slider from "rc-slider"; +import type { SliderProps } from "rc-slider"; +import raf from "rc-util/lib/raf"; +import Tooltip from "rc-tooltip"; + +const HandleTooltip = (props: { + value: number; + children: React.ReactElement; + visible: boolean; + tipFormatter?: (value: number) => React.ReactNode; +}) => { + const { + value, + children, + visible, + tipFormatter = (val) => `${val} %`, + ...restProps + } = props; + + const tooltipRef = React.useRef<any>(); + const rafRef = React.useRef<number | null>(null); + + function cancelKeepAlign() { + raf.cancel(rafRef.current!); + } + + function keepAlign() { + rafRef.current = raf(() => { + // tooltipRef.current?.forcePopupAlign(); + }); + } + + React.useEffect(() => { + if (visible) { + keepAlign(); + } else { + cancelKeepAlign(); + } + + return cancelKeepAlign; + }, [value, visible]); + + return ( + <Tooltip + placement="top" + overlay={tipFormatter(value)} + overlayInnerStyle={{ minHeight: "auto" }} + ref={tooltipRef} + visible={visible} + {...restProps} + > + {children} + </Tooltip> + ); +}; + +export const handleRender: SliderProps["handleRender"] = (node, props) => { + return ( + <HandleTooltip value={props.value} visible={props.dragging}> + {node} + </HandleTooltip> + ); +}; + +const TooltipSlider = ({ + tipFormatter, + tipProps, + ...props +}: SliderProps & { + tipFormatter?: (value: number) => React.ReactNode; + tipProps: any; +}) => { + const tipHandleRender: SliderProps["handleRender"] = (node, handleProps) => { + return ( + <HandleTooltip + value={handleProps.value} + visible={handleProps.dragging} + tipFormatter={tipFormatter} + {...tipProps} + > + {node} + </HandleTooltip> + ); + }; + + return <Slider {...props} handleRender={tipHandleRender} />; +}; + +export default TooltipSlider; |
