50 lines
1.5 KiB
TypeScript
50 lines
1.5 KiB
TypeScript
import { Box } from './Box';
|
|
import { Text } from './Text';
|
|
import { Stack } from './Stack';
|
|
|
|
export interface HorizontalBarChartItem {
|
|
label: string;
|
|
value: number;
|
|
color?: string;
|
|
}
|
|
|
|
export interface HorizontalBarChartProps {
|
|
items?: HorizontalBarChartItem[];
|
|
total?: number;
|
|
data?: HorizontalBarChartItem[]; // Alias for items
|
|
maxValue?: number; // Alias for total
|
|
}
|
|
|
|
export const HorizontalBarChart = ({
|
|
items,
|
|
total,
|
|
data,
|
|
maxValue
|
|
}: HorizontalBarChartProps) => {
|
|
const actualItems = items || data || [];
|
|
const actualTotal = total || maxValue || actualItems.reduce((acc, item) => acc + item.value, 0);
|
|
|
|
return (
|
|
<Box display="flex" flexDirection="col" gap={4}>
|
|
{actualItems.map((item, index) => {
|
|
const percentage = actualTotal > 0 ? (item.value / actualTotal) * 100 : 0;
|
|
return (
|
|
<Box key={index}>
|
|
<Stack direction="row" justify="between" marginBottom={1}>
|
|
<Text size="xs" variant="low" uppercase weight="bold">{item.label}</Text>
|
|
<Text size="xs" variant="high" weight="bold">{item.value}</Text>
|
|
</Stack>
|
|
<Box fullWidth height="0.5rem" bg="var(--ui-color-bg-surface-muted)" style={{ borderRadius: '9999px', overflow: 'hidden' }}>
|
|
<Box
|
|
fullHeight
|
|
bg={item.color || 'var(--ui-color-intent-primary)'}
|
|
style={{ width: `${percentage}%`, transition: 'width 0.3s ease-in-out' }}
|
|
/>
|
|
</Box>
|
|
</Box>
|
|
);
|
|
})}
|
|
</Box>
|
|
);
|
|
};
|