parent
8eda5b1849
commit
66a1e6c111
7 changed files with 114 additions and 40 deletions
@ -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)({ |
||||
backgroundColor: 'transparent', |
||||
borderRadius: BORDER_RADIUS, |
||||
height: '1em', |
||||
|
||||
[`& .${linearProgressClasses.bar}`]: { |
||||
borderRadius: BORDER_RADIUS, |
||||
backgroundColor: PANEL_BACKGROUND, |
||||
}, |
||||
}); |
||||
|
||||
export default BorderLinearProgress; |
||||
|
@ -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<StackBarProps> = (props) => { |
||||
const { value } = props; |
||||
|
||||
const values = useMemo<Record<string, StackBarValue>>( |
||||
() => ('value' in value ? { default: value as StackBarValue } : value), |
||||
[value], |
||||
); |
||||
|
||||
const entries = useMemo<[string, StackBarValue][]>( |
||||
() => Object.entries(values).reverse(), |
||||
[values], |
||||
); |
||||
|
||||
const bars = useMemo<ReactElement[]>( |
||||
() => |
||||
entries.map<ReactElement>( |
||||
([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 ( |
||||
<BorderLinearProgress |
||||
key={`stack-bar-${id}`} |
||||
sx={{ |
||||
position, |
||||
top, |
||||
width, |
||||
|
||||
[`& .${linearProgressClasses.bar}`]: { |
||||
backgroundColor, |
||||
}, |
||||
}} |
||||
variant="determinate" |
||||
value={val} |
||||
/> |
||||
); |
||||
}, |
||||
), |
||||
[entries], |
||||
); |
||||
|
||||
return ( |
||||
<Box position="relative"> |
||||
{bars} |
||||
<Underline /> |
||||
</Box> |
||||
); |
||||
}; |
||||
|
||||
export default StackBar; |
@ -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; |
@ -1,4 +1,5 @@ |
||||
import AllocationBar from './AllocationBar'; |
||||
import ProgressBar from './ProgressBar'; |
||||
import StackBar from './StackBar'; |
||||
|
||||
export { AllocationBar, ProgressBar }; |
||||
export { AllocationBar, ProgressBar, StackBar }; |
||||
|
@ -0,0 +1,8 @@ |
||||
type StackBarValue = { |
||||
colour?: string | Record<number, string>; |
||||
value: number; |
||||
}; |
||||
|
||||
type StackBarProps = { |
||||
value: StackBarValue | Record<string, StackBarValue>; |
||||
}; |
Loading…
Reference in new issue