diff --git a/striker-ui/components/Bars/AllocationBar.tsx b/striker-ui/components/Bars/AllocationBar.tsx
index 90b3df0f..ebbe6292 100644
--- a/striker-ui/components/Bars/AllocationBar.tsx
+++ b/striker-ui/components/Bars/AllocationBar.tsx
@@ -1,13 +1,9 @@
-import { LinearProgress } from '@mui/material';
-import { styled } from '@mui/material/styles';
+import { styled } from '@mui/material';
+
+import { PURPLE, RED, BLUE } from '../../lib/consts/DEFAULT_THEME';
-import {
- PURPLE,
- RED,
- BLUE,
- BORDER_RADIUS,
-} from '../../lib/consts/DEFAULT_THEME';
import BorderLinearProgress from './BorderLinearProgress';
+import Underline from './Underline';
const PREFIX = 'AllocationBar';
@@ -15,7 +11,6 @@ const classes = {
barOk: `${PREFIX}-barOk`,
barWarning: `${PREFIX}-barWarning`,
barAlert: `${PREFIX}-barAlert`,
- underline: `${PREFIX}-underline`,
};
const StyledDiv = styled('div')(() => ({
@@ -30,10 +25,6 @@ const StyledDiv = styled('div')(() => ({
[`& .${classes.barAlert}`]: {
backgroundColor: RED,
},
-
- [`& .${classes.underline}`]: {
- borderRadius: BORDER_RADIUS,
- },
}));
const breakpointWarning = 70;
@@ -54,11 +45,7 @@ const AllocationBar = ({ allocated }: { allocated: number }): JSX.Element => (
variant="determinate"
value={allocated}
/>
-
+
);
diff --git a/striker-ui/components/Bars/BorderLinearProgress.tsx b/striker-ui/components/Bars/BorderLinearProgress.tsx
index 50c1de44..57509a31 100644
--- a/striker-ui/components/Bars/BorderLinearProgress.tsx
+++ b/striker-ui/components/Bars/BorderLinearProgress.tsx
@@ -1,14 +1,15 @@
-import { LinearProgress } from '@mui/material';
-import { styled } from '@mui/material/styles';
-import {
- PANEL_BACKGROUND,
- BORDER_RADIUS,
-} from '../../lib/consts/DEFAULT_THEME';
+import { LinearProgress, linearProgressClasses, styled } from '@mui/material';
+
+import { BORDER_RADIUS } from '../../lib/consts/DEFAULT_THEME';
const BorderLinearProgress = styled(LinearProgress)({
- height: '1em',
+ backgroundColor: 'transparent',
borderRadius: BORDER_RADIUS,
- backgroundColor: PANEL_BACKGROUND,
+ height: '1em',
+
+ [`& .${linearProgressClasses.bar}`]: {
+ borderRadius: BORDER_RADIUS,
+ },
});
export default BorderLinearProgress;
diff --git a/striker-ui/components/Bars/ProgressBar.tsx b/striker-ui/components/Bars/ProgressBar.tsx
index 9f0280ad..d122acf2 100644
--- a/striker-ui/components/Bars/ProgressBar.tsx
+++ b/striker-ui/components/Bars/ProgressBar.tsx
@@ -1,15 +1,15 @@
-import { LinearProgress } from '@mui/material';
-import { styled } from '@mui/material/styles';
+import { styled } from '@mui/material';
+
+import { PURPLE, BLUE } from '../../lib/consts/DEFAULT_THEME';
-import { PURPLE, BLUE, BORDER_RADIUS } from '../../lib/consts/DEFAULT_THEME';
import BorderLinearProgress from './BorderLinearProgress';
+import Underline from './Underline';
const PREFIX = 'ProgressBar';
const classes = {
barOk: `${PREFIX}-barOk`,
barInProgress: `${PREFIX}-barInProgress`,
- underline: `${PREFIX}-underline`,
};
const StyledDiv = styled('div')(() => ({
@@ -20,10 +20,6 @@ const StyledDiv = styled('div')(() => ({
[`& .${classes.barInProgress}`]: {
backgroundColor: PURPLE,
},
-
- [`& .${classes.underline}`]: {
- borderRadius: BORDER_RADIUS,
- },
}));
const completed = 100;
@@ -44,11 +40,7 @@ const ProgressBar = ({
variant="determinate"
value={progressPercentage}
/>
-
+
);
diff --git a/striker-ui/components/Bars/StackBar.tsx b/striker-ui/components/Bars/StackBar.tsx
new file mode 100644
index 00000000..d0676490
--- /dev/null
+++ b/striker-ui/components/Bars/StackBar.tsx
@@ -0,0 +1,72 @@
+import { Box, linearProgressClasses } from '@mui/material';
+import { FC, ReactElement, useMemo } from 'react';
+
+import { GREY } from '../../lib/consts/DEFAULT_THEME';
+
+import BorderLinearProgress from './BorderLinearProgress';
+import Underline from './Underline';
+
+const StackBar: FC = (props) => {
+ const { value } = props;
+
+ const values = useMemo>(
+ () => ('value' in value ? { default: value as StackBarValue } : value),
+ [value],
+ );
+
+ const entries = useMemo<[string, StackBarValue][]>(
+ () => Object.entries(values).reverse(),
+ [values],
+ );
+
+ const bars = useMemo(
+ () =>
+ entries.map(
+ ([id, { colour = GREY, value: val }], index) => {
+ const backgroundColor =
+ typeof colour === 'string'
+ ? colour
+ : Object.entries(colour).findLast(
+ ([mark]) => val >= Number(mark),
+ )?.[1] ?? GREY;
+
+ let position: 'absolute' | 'relative' = 'relative';
+ let top: 0 | undefined;
+ let width: string | undefined;
+
+ if (index) {
+ position = 'absolute';
+ top = 0;
+ width = '100%';
+ }
+
+ return (
+
+ );
+ },
+ ),
+ [entries],
+ );
+
+ return (
+
+ {bars}
+
+
+ );
+};
+
+export default StackBar;
diff --git a/striker-ui/components/Bars/Underline.tsx b/striker-ui/components/Bars/Underline.tsx
new file mode 100644
index 00000000..b2553a2a
--- /dev/null
+++ b/striker-ui/components/Bars/Underline.tsx
@@ -0,0 +1,13 @@
+import { Box, styled } from '@mui/material';
+
+import { BORDER_RADIUS, DISABLED } from '../../lib/consts/DEFAULT_THEME';
+
+const Underline = styled(Box)({
+ backgroundColor: DISABLED,
+ borderRadius: BORDER_RADIUS,
+ display: 'block',
+ height: '4px',
+ position: 'relative',
+});
+
+export default Underline;
diff --git a/striker-ui/components/Bars/index.tsx b/striker-ui/components/Bars/index.tsx
index 0863c898..d321b41e 100644
--- a/striker-ui/components/Bars/index.tsx
+++ b/striker-ui/components/Bars/index.tsx
@@ -1,4 +1,5 @@
import AllocationBar from './AllocationBar';
import ProgressBar from './ProgressBar';
+import StackBar from './StackBar';
-export { AllocationBar, ProgressBar };
+export { AllocationBar, ProgressBar, StackBar };
diff --git a/striker-ui/types/StackBar.d.ts b/striker-ui/types/StackBar.d.ts
new file mode 100644
index 00000000..b0af9b11
--- /dev/null
+++ b/striker-ui/types/StackBar.d.ts
@@ -0,0 +1,8 @@
+type StackBarValue = {
+ colour?: string | Record;
+ value: number;
+};
+
+type StackBarProps = {
+ value: StackBarValue | Record;
+};