如何在 Material ui 滑块中的标签悬停时获取工具提示

问题描述 投票:0回答:1

我正在尝试创建一个滑块测验,我想要的是在滑块上的标签悬停时出现工具提示

现在,当我将鼠标悬停在拇指及其鼠标位置上时,我可以看到工具提示 这是图片

鼠标是我的红色M enter image description here

我想当鼠标位于其他值时显示工具提示 enter image description here

当拇指和鼠标位于同一点时,工具点可见 enter image description here

这是我如何使用它的代码

<PrettoSlider1     
      ValueLabelComponent={ValueLabelComponent2}
/>
 const ValueLabelComponent2 = (props) => {
    const { children, value } = props;
    if (value === 0) {
      return (
        <Tooltip placement="top" title={"Strongly disagree"}>
          {children}
        </Tooltip>
      );
    } else if (value <= 1) {
      return (
        <Tooltip placement="top" title={"Disagree"}>
          {children}
        </Tooltip>
      );
    } else if (value <= 2) {
      return (
        <Tooltip placement="top" title={"Neutral"}>
          {children}
        </Tooltip>
      );
    } else if (value <= 3) {
      return (
        <Tooltip placement="top" title={"Agree"}>
          {children}
        </Tooltip>
      );
    } else if (value <= 4) {
      return (
        <Tooltip placement="top" title={"Strongly agree"}>
          {children}
        </Tooltip>
      );
    } else {
      return (
        <Tooltip placement="top" title={""}>
          {children}
        </Tooltip>
      );
    }
  };

是否有可能,如果我像第二张图片中那样悬停,我可以在没有拇指的情况下获得工具提示

javascript reactjs material-ui slider
1个回答
0
投票

我必须实现一个类似的用例并提出以下解决方案。因此,如果您偶然发现这个问题,您可能会发现它很有用。

在我的解决方案中,我跟踪滑块内的鼠标光标 X 坐标,并使用到鼠标光标的距离计算最近的标记索引。当用户将鼠标悬停在滑块上时,将显示关闭标记的工具提示并跟随光标。看起来像这样:

Example

因此,用户在单击当前位置时会看到将要选择的标记的工具提示(似乎滑块组件使用类似的机制来确定要选择哪个谨慎的步骤/标记)。

它可能不是最优雅或最高性能的解决方案,但它非常适合我的用例。

代码如下:

import * as React from "react";
import Box from "@mui/material/Box";
import Slider from "@mui/material/Slider";
import { Tooltip } from "@mui/material";

export default function SliderWithTooltips() {
  const [markTooltip, setMarkTooltip] = React.useState("");

  const handleMouseMove = React.useCallback(
    (event: React.MouseEvent<HTMLDivElement>) => {
      // Determines the closest mark index to the mouse cursor by calculating
      // the distance of the relative X coordinate (relative to the slider element) of
      // the mouse cursor and the mark dom element.
      const mouseRelativeX =
        event.clientX - event.currentTarget.getBoundingClientRect().left;
      const sliderMarks = extractMarkElementRelativeXValues(
        event.currentTarget
      );
      let closestMarkIndex = 0;
      let closestDistance = Number.MAX_VALUE;
      let lastDistance = closestDistance;

      for (const mark of sliderMarks) {
        const distance = Math.abs(mouseRelativeX - mark.relativeX);

        // If the distance is increasing again, we have passed the closest mark and can abort the loop.
        if (distance > lastDistance) {
          break;
        }

        if (distance < closestDistance) {
          closestDistance = distance;
          closestMarkIndex = mark.index;
        }

        lastDistance = distance;
      }

      setMarkTooltip(markTooltips[closestMarkIndex]);
    },
    [setMarkTooltip]
  );

  return (
    <Box sx={{ width: 600, p: 4 }}>
      <Tooltip title={markTooltip} followCursor>
        <Slider
          valueLabelDisplay="auto"
          step={null}
          marks={marks}
          min={0}
          max={9}
          onMouseMove={handleMouseMove}
        />
      </Tooltip>
    </Box>
  );
}

function extractMarkElementRelativeXValues(sliderElement: HTMLSpanElement) {
  const sliderLeftX = sliderElement.getBoundingClientRect().left;

  return Array.from(sliderElement.getElementsByClassName("MuiSlider-mark")).map(
    (element) => ({
      index: Number(element.getAttribute("data-index")),
      relativeX: element.getBoundingClientRect().left - sliderLeftX,
    })
  );
}

const marks = [
  { value: 0 },
  { value: 1, label: "1" },
  { value: 2, label: "2" },
  { value: 3, label: "3" },
  { value: 4, label: "4" },
  { value: 5, label: "5" },
  { value: 6, label: "6" },
  { value: 7, label: "7" },
  { value: 8, label: "8" },
  { value: 9, label: "9" },
];

const markTooltips = [
  "No value",
  "Some tooltip 1",
  "Some tooltip 2",
  "Some tooltip 3",
  "Some tooltip 4",
  "Some tooltip 5",
  "Some tooltip 6",
  "Some tooltip 7",
  "Some tooltip 8",
  "Some tooltip 9",
];

我还在此处创建了一个 CodeSandbox 示例:https://codesandbox.io/p/sandbox/goofy-lehmann-5ljcdn?file=%2Fsrc%2FDemo.tsx

HTH, 本

© www.soinside.com 2019 - 2024. All rights reserved.