简体   繁体   English

在 reactjs 材料 ui 进度条中显示百分比

[英]show percentage number in reactjs material ui progress bar

I use Linear Determinate and i want to display how much progress is completed in number.我使用线性确定,我想显示完成的进度数量。 like below image.如下图。

在此处输入图片说明

I don't think Material UI provides progress bar as shown in your image above.我认为 Material UI 没有提供如上图所示的进度条。

However, you can make use of React Bootstrap package and get things done.但是,您可以使用 React Bootstrap 包来完成任务。

Here is the link - https://react-bootstrap.github.io/components/progress/这是链接 - https://react-bootstrap.github.io/components/progress/

You could display this.state.completed which shows the percentage value of the progress and the just add some style to it.您可以显示this.state.completed ,它显示进度的百分比值,并为其添加一些样式。 Of course, you'll have to concatenate a % at the end if you want to be more explicit because it is nothing but a number.当然,如果你想更明确,你必须在最后连接一个% ,因为它只是一个数字。

Materiaui 支持进度条实现,请查看代码和框中的示例

Here are a few different material-ui custom styles mixed together to create the desired component:以下是几种不同的 material-ui 自定义样式混合在一起以创建所需的组件:

import React from "react";

import { withStyles } from "@material-ui/styles";
import { lighten, Box, LinearProgress, Typography } from "@material-ui/core";

interface Props {
  color?: "primary" | "secondary";
  hex?: string;
  value?: number;
}

/**
 * ProgressBar -- atom
 * A material-ui progress bar.
 * @param {'primary' | 'secondary'} color Choose to render the primary or secondary colors.
 * @param {string} hex Override the selected color with a hex value.
 * @param {number} value The value for the progress bar, between 0-100.
 * @return {JSX} React component
 */
const ProgressBar = ({ color, hex, value }: Props) => {
  let internalColor: string;

  if (typeof hex === "undefined") {
    internalColor = "#3f51b5";
  } else if (typeof hex !== "undefined" && /^#[0-9A-F]{6}$/i.test(hex)) {
    internalColor = hex;
  } else {
    throw new Error("Invalid hex prop -- please use a hex string.");
  }

  if (typeof value === "undefined") {
    value = 0;
  } else if (typeof value === "number" && value < 0) {
    throw new Error(
      "Invalid value prop -- please use a number more than or equal to 0."
    );
  } else if (typeof value === "number" && value > 100) {
    throw new Error(
      "Invalid value prop -- please use a number less than or equal to 100."
    );
  }

  // from: https://bit.dev/mui-org/material-ui/linear-progress
  const BorderLinearProgress = withStyles({
    root: {
      height: 20,
      width: "100%",
      backgroundColor: hex ? lighten(internalColor, 0.5) : undefined,
      borderRadius: "10px"
    },
    bar: {
      borderRadius: 20,
      backgroundColor: hex ? internalColor : undefined
    }
  })(LinearProgress);

  // from: https://stackoverflow.com/a/60609045/14198287
  const WhiteTextTypography = withStyles({
    root: {
      color: "#FFFFFF"
    }
  })(Typography);

  return (
    <Box position="relative" display="inline-flex" style={{ width: "100%" }}>
      <BorderLinearProgress
        color={hex ? undefined : color}
        variant="determinate"
        value={value}
      />
      <Box
        top={0}
        left={0}
        bottom={0}
        right={0}
        position="absolute"
        display="flex"
        alignItems="center"
        justifyContent="center"
      >
        <WhiteTextTypography variant="body2">{`${value}%`}</WhiteTextTypography>
      </Box>
    </Box>
  );
};

export default ProgressBar;

For a working example, see: https://codesandbox.io/s/stack-51254333-progressbar-x7j5m?file=/src/App.tsx:0-2390有关工作示例,请参阅: https : //codesandbox.io/s/stack-51254333-progressbar-x7j5m?file=/src/App.tsx : 0-2390

I hope you have found your answer but if that helps anyone with the same issue, I managed to achieve this by using React.createPortal .我希望你已经找到了答案,但如果这对遇到同样问题的人有所帮助,我设法通过使用React.createPortal来实现这React.createPortal ;) ;)

Here are the steps to implement this:以下是实现这一点的步骤:

  • Add a ref to your progress bar (the ref can't be used with useRef if you want your label to be initialized on mount, instead create an element local state ( useState<HtmlElement | undefined>() )向进度条添加 ref(如果您希望在装载时初始化标签,则 ref不能useRef一起使用,而是创建元素本地状态( useState<HtmlElement | undefined>()
  • Add this to your progress bar component:将此添加到您的进度条组件:
ref={(el: HTMLElement) => setElement(el)}
  • Create a component which will have your label, in it make sure to pass down the element from your local state ( IMPORTANT pass the child element from your node, not the parent -> el={element.firstElementChild} ).创建一个带有标签的组件,在其中确保从本地状态传递元素(重要的是从节点传递子元素,而不是父el={element.firstElementChild} -> el={element.firstElementChild} )。
  • Do a createPortal to "move" this component as a child of element.firstElementChild , aka: the progress bar.做一个createPortal来“移动”这个组件作为element.firstElementChild的子element.firstElementChild ,也就是:进度条。 Here is my code for that:这是我的代码:
// in my case I made sure my HTML code for my label has an position absolute so I can move it to the far right of my progress bar.
const MyLabel: FC<{ el: Element; extraLabel: string }> = ({ el, extraLabel }) => {
  return (
    <>
      {createPortal(
        <>..your HTML code for your label..</>, 
        el,
      )}
    </>
  );
};

Here is my final output:这是我的最终输出:

在此处输入图片说明

Hope it helps <3希望有帮助 <3

For more information on how to use React.createPortal and understand its magic, here is the documentation : https://reactjs.org/docs/portals.html有关如何使用React.createPortal并了解其神奇之处的更多信息,请参阅文档: https : React.createPortal

From a senior FullStack dev, Audrey.来自高级 FullStack 开发人员 Audrey。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM