Parcourir la source

Merge pull request #1797 from Avaiga/feature/progress_width

Adding width property to linear & circular progress
Nam Nguyen il y a 8 mois
Parent
commit
5a8f6e7865

+ 116 - 0
frontend/taipy-gui/src/components/Taipy/Progress.spec.tsx

@@ -161,6 +161,122 @@ describe("Progress component", () => {
         const circularProgressCircle = container.querySelector(".MuiCircularProgress-circle");
         expect(circularProgressCircle).not.toHaveStyle("color: blue");
     });
+
+    it("applies width to circular progress when width is defined as number", () => {
+        const { container } = render(<Progress linear={false} value={50} width={100} />);
+        const circularProgress = container.querySelector(".MuiCircularProgress-root");
+        expect(circularProgress).toHaveStyle("width: 100px");
+        expect(circularProgress).toHaveStyle("height: 100px");
+    });
+
+    it("applies width to circular progress when width is defined as number & title is defined", () => {
+        const { container } = render(<Progress linear={false} value={50} width={100} title="Title" />);
+        const circularProgress = container.querySelector(".MuiCircularProgress-root");
+        expect(circularProgress).toHaveStyle("width: 100px");
+        expect(circularProgress).toHaveStyle("height: 100px");
+    });
+
+    it("applies width to circular progress when width is defined as number & title, titleAnchor are defined", () => {
+        const { container } = render(
+            <Progress linear={false} value={50} width={100} title="Title" titleAnchor="top" />
+        );
+        const circularProgress = container.querySelector(".MuiCircularProgress-root");
+        expect(circularProgress).toHaveStyle("width: 100px");
+        expect(circularProgress).toHaveStyle("height: 100px");
+    });
+
+    it("applies width to circular progress when width is defined as number & title, titleAnchor, showValue are defined", () => {
+        const { container } = render(
+            <Progress linear={false} value={50} width={100} title="Title" titleAnchor="top" showValue={true} />
+        );
+        const circularProgress = container.querySelector(".MuiCircularProgress-root");
+        expect(circularProgress).toHaveStyle("width: 100px");
+        expect(circularProgress).toHaveStyle("height: 100px");
+    });
+
+    it("applies width to circular progress when width is defined as string", () => {
+        const { container } = render(<Progress linear={false} value={50} width="10rem" />);
+        const circularProgress = container.querySelector(".MuiCircularProgress-root");
+        expect(circularProgress).toHaveStyle("width: 10rem");
+        expect(circularProgress).toHaveStyle("height: 10rem");
+    });
+
+    it("applies width to circular progress when width is defined as string & title is defined", () => {
+        const { container } = render(<Progress linear={false} value={50} width="10rem" title="Title" />);
+        const circularProgress = container.querySelector(".MuiCircularProgress-root");
+        expect(circularProgress).toHaveStyle("width: 10rem");
+        expect(circularProgress).toHaveStyle("height: 10rem");
+    });
+
+    it("applies width to circular progress when width is defined as string & title, titleAnchor are defined", () => {
+        const { container } = render(
+            <Progress linear={false} value={50} width="10rem" title="Title" titleAnchor="top" />
+        );
+        const circularProgress = container.querySelector(".MuiCircularProgress-root");
+        expect(circularProgress).toHaveStyle("width: 10rem");
+        expect(circularProgress).toHaveStyle("height: 10rem");
+    });
+
+    it("applies width to circular progress when width is defined as string & title, titleAnchor, showValue are defined", () => {
+        const { container } = render(
+            <Progress linear={false} value={50} width="10rem" title="Title" titleAnchor="top" showValue={true} />
+        );
+        const circularProgress = container.querySelector(".MuiCircularProgress-root");
+        expect(circularProgress).toHaveStyle("width: 10rem");
+        expect(circularProgress).toHaveStyle("height: 10rem");
+    });
+
+    it("applies width to linear progress when width is defined as number", () => {
+        const { container } = render(<Progress linear value={50} width={100} />);
+        const linearProgress = container.querySelectorAll(".MuiBox-root")[0];
+        expect(linearProgress).toHaveStyle("width: 100px");
+    });
+
+    it("applies width to linear progress when width is defined as number & title is defined", () => {
+        const { container } = render(<Progress linear value={50} width={100} title="Title" />);
+        const linearProgress = container.querySelectorAll(".MuiBox-root")[0];
+        expect(linearProgress).toHaveStyle("width: 100px");
+    });
+
+    it("applies width to linear progress when width is defined as number & title, titleAnchor are defined", () => {
+        const { container } = render(<Progress linear value={50} width={100} title="Title" titleAnchor="top" />);
+        const linearProgress = container.querySelectorAll(".MuiBox-root")[0];
+        expect(linearProgress).toHaveStyle("width: 100px");
+    });
+
+    it("applies width to linear progress when width is defined as number & title, titleAnchor, showValue are defined", () => {
+        const { container } = render(
+            <Progress linear showValue value={50} width={100} title="Title" titleAnchor="top" />
+        );
+        const linearProgress = container.querySelectorAll(".MuiBox-root")[0];
+        expect(linearProgress).toHaveStyle("width: 100px");
+    });
+
+    it("applies width to linear progress when width is defined as string", () => {
+        const { container } = render(<Progress linear value={50} width="10rem" />);
+        const linearProgress = container.querySelectorAll(".MuiBox-root")[0];
+        expect(linearProgress).toHaveStyle("width: 10rem");
+    });
+
+    it("applies width to linear progress when width is defined as string & title is defined", () => {
+        const { container } = render(<Progress linear value={50} width="10rem" title="Title" />);
+        const linearProgress = container.querySelectorAll(".MuiBox-root")[0];
+        expect(linearProgress).toHaveStyle("width: 10rem");
+    });
+
+    it("applies width to linear progress when width is defined as string & title, titleAnchor are defined", () => {
+        const { container } = render(<Progress linear value={50} width="10rem" title="Title" titleAnchor="top" />);
+        const linearProgress = container.querySelectorAll(".MuiBox-root")[0];
+        expect(linearProgress).toHaveStyle("width: 10rem");
+    });
+
+    it("applies width to linear progress when width is defined as string & title, titleAnchor, showValue are defined", () => {
+        const { container } = render(
+            <Progress linear value={50} width="10rem" title="Title" titleAnchor="top" showValue={true} />
+        );
+        const linearProgress = container.querySelectorAll(".MuiBox-root")[0];
+        expect(linearProgress).toHaveStyle("width: 10rem");
+    });
 });
 
 describe("Progress functions", () => {

+ 18 - 4
frontend/taipy-gui/src/components/Taipy/Progress.tsx

@@ -18,7 +18,9 @@ import LinearProgress from "@mui/material/LinearProgress";
 import Typography from "@mui/material/Typography";
 
 import { useClassNames, useDynamicProperty } from "../../utils/hooks";
-import { TaipyBaseProps } from "./utils";
+import { getCssSize, TaipyBaseProps } from "./utils";
+import { SxProps } from "@mui/material/styles";
+import { Theme } from "@mui/system";
 
 interface ProgressBarProps extends TaipyBaseProps {
     color?: string;
@@ -31,6 +33,7 @@ interface ProgressBarProps extends TaipyBaseProps {
     title?: string;
     defaultTitle?: string;
     titleAnchor?: "top" | "bottom" | "left" | "right" | "none";
+    width?: string | number;
 }
 
 const linearSx = { display: "flex", alignItems: "center", width: "100%" };
@@ -75,8 +78,9 @@ const Progress = (props: ProgressBarProps) => {
         return {
             boxWithFlexDirectionSx: {
                 ...linearSx,
+                width: props.width ? getCssSize(props.width) : "100%",
                 flexDirection: getFlexDirection(titleAnchor),
-            },
+            } as SxProps<Theme>,
             circularBoxSx: {
                 ...circularSx,
                 flexDirection: getFlexDirection(titleAnchor),
@@ -99,7 +103,11 @@ const Progress = (props: ProgressBarProps) => {
                 },
             },
         };
-    }, [props.color, title, titleAnchor]);
+    }, [props.color, props.width, title, titleAnchor]);
+
+    const circularProgressSize = useMemo(() => {
+        return props.width ? getCssSize(props.width) : undefined;
+    }, [props.width]);
 
     const { boxWithFlexDirectionSx, circularBoxSx, linearProgressSx, circularProgressSx, linearProgressFullWidthSx } =
         memoizedValues;
@@ -133,7 +141,12 @@ const Progress = (props: ProgressBarProps) => {
                     </Typography>
                 ) : null}
                 <Box sx={circularSx} className={className} id={props.id}>
-                    <CircularProgress sx={circularProgressSx} variant="determinate" value={value} />
+                    <CircularProgress
+                        sx={circularProgressSx}
+                        variant="determinate"
+                        value={value}
+                        size={circularProgressSize}
+                    />
                     <Box sx={circularPrgSx}>
                         <Typography variant="caption" component="div" color="text.secondary">
                             {`${Math.round(value)}%`}
@@ -170,6 +183,7 @@ const Progress = (props: ProgressBarProps) => {
                 variant={value === undefined ? "indeterminate" : "determinate"}
                 value={value}
                 className={className}
+                size={circularProgressSize}
             />
         </Box>
     );

+ 1 - 0
taipy/gui/_renderers/factory.py

@@ -614,6 +614,7 @@ class _Factory:
                 ("title", PropertyType.dynamic_string),
                 ("title_anchor", PropertyType.string, "bottom"),
                 ("render", PropertyType.dynamic_boolean, True),
+                ("width", PropertyType.string_or_number),
             ]
         )
         ._set_propagate(),

+ 6 - 0
taipy/gui/viselements.json

@@ -1374,6 +1374,12 @@
                         "type": "dynamic(bool)",
                         "default_value": "True",
                         "doc": "If False, this progress indicator is hidden from the page."
+                    },
+                    {
+                        "name": "width",
+                        "type": "Union[str,int]",
+                        "default_value": "None",
+                        "doc": "The width of this progress indicator, in CSS units."
                     }
                 ]
             }