summaryrefslogtreecommitdiff
path: root/src/ui/TooltipSlider.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/TooltipSlider.tsx')
-rw-r--r--src/ui/TooltipSlider.tsx95
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;