CircleProgress

This commit is contained in:
Max S 2024-07-15 17:26:38 +02:00
parent a28e0ae950
commit 9cb87460c1
4 changed files with 123 additions and 14 deletions

View File

@ -0,0 +1,24 @@
@import "@Themes/constants.scss";
.root {
display: flex;
align-items: center;
gap: 24px;
svg {
width: 100%;
height: 100%;
transform: rotate(-90deg);
.circleBackground {
fill: none;
stroke: var(--background-elevation-2);
}
.circleProgress {
fill: none;
stroke: var(--color-secondary-500);
transition: stroke-dashoffset 0.35s;
}
}
}

View File

@ -0,0 +1,61 @@
import React, { useCallback, useEffect, useRef, useState } from "react";
import Typography, { ETypo, ETypoColor } from "../Typography";
import classes from "./classes.module.scss";
type IProps = {
percentage: number;
};
export default function CircleProgress(props: IProps) {
const { percentage } = props;
const [animatedProgress, setAnimatedProgress] = useState(0);
const requestRef = useRef<number>();
const animate = useCallback(() => {
setAnimatedProgress((prev) => {
if (prev < percentage) {
return prev + 1;
} else {
if (requestRef.current) {
cancelAnimationFrame(requestRef.current);
}
return prev;
}
});
requestRef.current = requestAnimationFrame(animate);
}, [percentage]);
useEffect(() => {
requestRef.current = requestAnimationFrame(animate);
return () => {
if (requestRef.current) {
cancelAnimationFrame(requestRef.current);
}
};
}, [animate, percentage]);
const radius = 11;
const circumference = 2 * Math.PI * radius;
const offset = circumference - (animatedProgress / 100) * circumference;
return (
<div className={classes["root"]}>
<svg xmlns="http://www.w3.org/2000/svg" width="27" height="27" viewBox="0 0 27 27" fill="none">
<circle className={classes["circleBackground"]} cx="13.5" cy="13.5" r={radius} strokeWidth="3" />
<circle
className={classes["circleProgress"]}
cx="13.5"
cy="13.5"
r={radius}
strokeWidth="3"
strokeDasharray={circumference}
strokeDashoffset={offset}
/>
</svg>
<Typography typo={ETypo.TEXT_LG_REGULAR} color={ETypoColor.COLOR_NEUTRAL_950}>
{percentage}%
</Typography>
</div>
);
}

View File

@ -72,6 +72,17 @@
margin-bottom: 24px; margin-bottom: 24px;
} }
} }
.components {
display: flex;
flex-direction: column;
gap: 24px;
.rows {
display: flex;
gap: 16px;
}
}
} }
.buttons { .buttons {

View File

@ -7,6 +7,7 @@ import classes from "./classes.module.scss";
import Newletter from "@Front/Components/DesignSystem/Newsletter"; import Newletter from "@Front/Components/DesignSystem/Newsletter";
import Button, { EButtonStyleType, EButtonVariant } from "@Front/Components/DesignSystem/Button"; import Button, { EButtonStyleType, EButtonVariant } from "@Front/Components/DesignSystem/Button";
import Tag, { ETagColor, ETagVariant } from "@Front/Components/DesignSystem/Tag"; import Tag, { ETagColor, ETagVariant } from "@Front/Components/DesignSystem/Tag";
import CircleProgress from "@Front/Components/DesignSystem/CircleProgress";
type IProps = {}; type IProps = {};
type IState = { type IState = {
@ -28,6 +29,31 @@ export default class Folder extends BasePage<IProps, IState> {
return ( return (
<DefaultNotaryDashboard title={"Dossier"} onSelectedFolder={this.onSelectedFolder} mobileBackText={"Liste des dossiers"}> <DefaultNotaryDashboard title={"Dossier"} onSelectedFolder={this.onSelectedFolder} mobileBackText={"Liste des dossiers"}>
<div className={classes["root"]}> <div className={classes["root"]}>
<div className={classes["components"]}>
<Typography typo={ETypo.TEXT_LG_BOLD}>Circle Progress</Typography>
<div className={classes["rows"]}>
<CircleProgress percentage={0} />
<CircleProgress percentage={30} />
<CircleProgress percentage={60} />
<CircleProgress percentage={100} />
</div>
<Typography typo={ETypo.TEXT_LG_BOLD}>Tags</Typography>
<div className={classes["rows"]}>
<Tag color={ETagColor.INFO} variant={ETagVariant.REGULAR} label="Info" />
<Tag color={ETagColor.SUCCESS} variant={ETagVariant.REGULAR} label="Success" />
<Tag color={ETagColor.WARNING} variant={ETagVariant.REGULAR} label="Warning" />
<Tag color={ETagColor.ERROR} variant={ETagVariant.REGULAR} label="Error" />
</div>
<Typography typo={ETypo.TEXT_LG_BOLD}>Table Tags</Typography>
<div className={classes["rows"]}>
<Tag color={ETagColor.INFO} variant={ETagVariant.SEMI_BOLD} label="INFO" />
<Tag color={ETagColor.SUCCESS} variant={ETagVariant.SEMI_BOLD} label="SUCCESS" />
<Tag color={ETagColor.WARNING} variant={ETagVariant.SEMI_BOLD} label="WARNING" />
<Tag color={ETagColor.ERROR} variant={ETagVariant.SEMI_BOLD} label="ERROR" />
</div>
</div>
<div className={classes["no-folder-selected"]}> <div className={classes["no-folder-selected"]}>
<Typography typo={ETypo.TITLE_H1}>Informations du dossier</Typography> <Typography typo={ETypo.TITLE_H1}>Informations du dossier</Typography>
<div className={classes["choose-a-folder"]}> <div className={classes["choose-a-folder"]}>
@ -97,21 +123,8 @@ export default class Folder extends BasePage<IProps, IState> {
INFO INFO
</Button> </Button>
</div> </div>
<div className={classes["buttons"]}>
<Tag color={ETagColor.INFO} variant={ETagVariant.REGULAR} label="Info" />
<Tag color={ETagColor.SUCCESS} variant={ETagVariant.REGULAR} label="Success" />
<Tag color={ETagColor.WARNING} variant={ETagVariant.REGULAR} label="Warning" />
<Tag color={ETagColor.ERROR} variant={ETagVariant.REGULAR} label="Error" />
</div>
<div className={classes["buttons"]}>
<Tag color={ETagColor.INFO} variant={ETagVariant.SEMI_BOLD} label="INFO" />
<Tag color={ETagColor.SUCCESS} variant={ETagVariant.SEMI_BOLD} label="SUCCESS" />
<Tag color={ETagColor.WARNING} variant={ETagVariant.SEMI_BOLD} label="WARNING" />
<Tag color={ETagColor.ERROR} variant={ETagVariant.SEMI_BOLD} label="ERROR" />
</div>
</div> </div>
<Newletter isOpen /> <Newletter isOpen={false} />
</div> </div>
</div> </div>
</DefaultNotaryDashboard> </DefaultNotaryDashboard>