diff --git a/src/components/SizeChart/SizeChart.stories.tsx b/src/components/SizeChart/SizeChart.stories.tsx
new file mode 100644
index 00000000..326076a4
--- /dev/null
+++ b/src/components/SizeChart/SizeChart.stories.tsx
@@ -0,0 +1,79 @@
+// This file is part of MinIO Design System
+// Copyright (c) 2023 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+import React, { Fragment } from "react";
+import { Meta, Story } from "@storybook/react";
+
+import StoryThemeProvider from "../../../../../Downloads/mds-master 2/src/utils/StoryThemeProvider";
+import TestIcon from "../../../../../Downloads/mds-master 2/src/utils/TestIcon";
+import { Button, GlobalStyles } from "../../../../../Downloads/mds-master 2/src/components";
+import SizeChart from "./SizeChart";
+import { SizeChartProps } from "./SizeChart.types";
+
+export default {
+ title: "MDS/Data/SizeChart",
+ component: SizeChart,
+ argTypes: {},
+} as Meta;
+
+const Template: Story = (args) => (
+
+
+
+
+);
+
+export const Default = Template.bind({});
+Default.args = {
+ usedBytes: 45000,
+ totalBytes: 100000,
+};
+
+export const WarningSpace = Template.bind({});
+WarningSpace.args = {
+ usedBytes: 85000,
+ totalBytes: 100000,
+};
+
+export const DangerSpace = Template.bind({});
+DangerSpace.args = {
+ usedBytes: 95000,
+ totalBytes: 100000,
+};
+
+export const WithLabel = Template.bind({});
+WithLabel.args = {
+ usedBytes: 95000,
+ totalBytes: 100000,
+ label: true,
+};
+
+export const WithChartLabel = Template.bind({});
+WithChartLabel.args = {
+ usedBytes: 9504400,
+ totalBytes: 103840000,
+ label: true,
+ chartLabel: "Reported Usage",
+};
+
+export const CustomSize = Template.bind({});
+CustomSize.args = {
+ usedBytes: 95000,
+ totalBytes: 100000,
+ label: true,
+ width: 50,
+ height: 50,
+};
diff --git a/src/components/SizeChart/SizeChart.tsx b/src/components/SizeChart/SizeChart.tsx
new file mode 100644
index 00000000..c3f3898a
--- /dev/null
+++ b/src/components/SizeChart/SizeChart.tsx
@@ -0,0 +1,164 @@
+// This file is part of MinIO Design System
+// Copyright (c) 2023 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+import React, { FC, SVGProps, useEffect, useRef } from "react";
+import get from "lodash/get";
+import styled from "styled-components";
+
+import { lightColors } from "../../../../../Downloads/mds-master 2/src/global/themes";
+import { calculateBytes, overridePropsParse } from "../../../../../Downloads/mds-master 2/src/global/utils";
+import { SizeChartConstructProps, SizeChartProps } from "./SizeChart.types";
+
+const SizeChartBase = styled.svg & SizeChartConstructProps>(
+ ({ theme, usedBytes, totalBytes, chartLabel, sx }) => {
+ const percUsed = (usedBytes * 100) / totalBytes;
+
+ let color = get(theme, "signalColors.main", lightColors.mainBlue);
+
+ if (percUsed >= 90) {
+ color = get(theme, "signalColors.danger", lightColors.mainRed);
+ } else if (percUsed >= 80) {
+ color = get(theme, "signalColors.warning", lightColors.mainOrange);
+ }
+
+ return {
+ "& .usedSpace": {
+ stroke: color,
+ },
+ "& .availableSpace": {
+ stroke: get(theme, "signalColors.disabled", lightColors.disabledGrey),
+ },
+ "& .chartText": {
+ fill: "#000",
+ transform: "translateY(0.25em)",
+ },
+ "& .chartNumber": {
+ fontSize: "0.3em",
+ lineHeight: 1,
+ textAnchor: "middle",
+ transform:
+ chartLabel !== "" ? "translateY(-0.50em)" : "translateY(-0.25em)",
+ fontWeight: "bold",
+ fill: get(theme, "fontColor", lightColors.defaultFontColor),
+ },
+ "& .chartLabel": {
+ fontSize: "0.2em",
+ textAnchor: "middle",
+ transform: "translateY(0.7em)",
+ whiteSpace: "normal",
+ fontWeight: "bold",
+ fill: get(theme, "mutedText", lightColors.mutedText),
+ },
+ ...overridePropsParse(sx, theme),
+ };
+ },
+);
+
+const SizeChart: FC = ({
+ width = "150",
+ height = "150",
+ usedBytes,
+ totalBytes,
+ label,
+ chartLabel = "",
+ sx,
+}) => {
+ const val1D = useRef(null);
+ const val2D = useRef(null);
+
+ useEffect(() => {
+ setTimeout(function () {
+ if (val1D?.current) {
+ val1D.current.style.transition =
+ "stroke-dasharray 0.5s ease-in-out, stroke-dashoffset 0.5s ease-in-out";
+ val1D.current.style.strokeDasharray = "100 0";
+ }
+ }, 20);
+ }, []);
+
+ useEffect(() => {
+ const val1 = usedBytes;
+ const val2 = totalBytes - usedBytes;
+
+ const total = val1 + val2;
+
+ const per1 = (val1 / total) * 100;
+ const per2 = (val2 / total) * 100;
+ const offset = 25;
+
+ if (val1D?.current && val2D?.current) {
+ val1D.current.style.transition =
+ "stroke-dasharray 0.5s ease-in-out, stroke-dashoffset 0.5s ease-in-out";
+ val1D.current.style.strokeDasharray = per1 + " " + (100 - per1);
+ val1D.current.style.strokeDashoffset = `${offset}`;
+
+ val2D.current.style.transition =
+ "stroke-dasharray 0.5s ease-in-out, stroke-dashoffset 0.5s ease-in-out";
+ val2D.current.style.strokeDasharray = per2 + " " + (100 - per2);
+ val2D.current.style.strokeDashoffset = `${100 - per1 + offset}`;
+ }
+ }, [usedBytes, totalBytes]);
+
+ const usedSizeUnits = calculateBytes(usedBytes);
+
+ return (
+
+
+
+ {label && (
+
+
+ {usedSizeUnits.total} {usedSizeUnits.unit}
+
+
+ {chartLabel}
+
+
+ )}
+
+ );
+};
+
+export default SizeChart;
diff --git a/src/components/SizeChart/SizeChart.types.ts b/src/components/SizeChart/SizeChart.types.ts
new file mode 100644
index 00000000..95b2249b
--- /dev/null
+++ b/src/components/SizeChart/SizeChart.types.ts
@@ -0,0 +1,32 @@
+// This file is part of MinIO Design System
+// Copyright (c) 2023 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+import { OverrideTheme } from "../../../../../Downloads/mds-master 2/src/global/global.types";
+
+export interface SizeChartMain {
+ label: boolean;
+ width?: string;
+ height?: string;
+}
+
+export interface SizeChartConstructProps {
+ usedBytes: number;
+ totalBytes: number;
+ chartLabel?: string;
+ sx?: OverrideTheme;
+}
+
+export type SizeChartProps = SizeChartMain & SizeChartConstructProps;