Skip to content

Stats Grid

BlockMantine ≥ 9MantineProvider

Responsive metric grid with custom icons, comparison labels and trends.

Install

One command copies the item's source into your project, where you own and edit it.

Terminal window
npx manteen add @house/stats-grid

Dependencies

  • @mantine/core@^9npm
  • @tabler/icons-react@^3npm

Installing this item also installs @house/mantine-ui-license from the registry.

Preview

Usage

A copy-ready example published by the registry author. Imports use the aliases Manteen configures at init.

stats-grid.usage.tsx
import { IconCoin, IconDiscount2, IconReceipt2, IconUserPlus } from "@tabler/icons-react";
import { StatsGrid } from "@/components/ui/stats-grid";
export function QuarterlyStats() {
return (
<StatsGrid
items={[
{
title: "Revenue",
value: "$48,392",
diff: 12,
icon: <IconCoin size={22} stroke={1.5} />,
},
{
title: "New customers",
value: "1,204",
diff: 8,
icon: <IconUserPlus size={22} stroke={1.5} />,
},
{
title: "Discount volume",
value: "$3,120",
diff: -4,
icon: <IconDiscount2 size={22} stroke={1.5} />,
comparisonLabel: "Compared to last quarter",
},
{
title: "Refunds",
value: "312",
diff: -2,
icon: <IconReceipt2 size={22} stroke={1.5} />,
},
]}
/>
);
}

Props

Author-documented props, carried verbatim from the registry item.

PropTypeDefaultDescription
items*StatsGridItem[]Renders one stat card per item, laying them out in a responsive grid that scales up to four columns on desktop based on the item count.

* required

Styling

No public Styles API is declared. Installed CSS remains editable because your project owns the source; internal class names are implementation details, not a customization contract.

Source

2 installable files ship with this item.

registry/mantine-ui/stats-grid/stats-grid.tsxcomponent · 2.0 kB · tsx
/**
* Adapted from Mantine UI's StatsGrid at
* ffbf61c559f374a7ea28fcf00355e84dcbe9a908. MIT licensed; see
* LICENSES/MANTINE-UI.txt after installation.
*/
import { Group, Paper, SimpleGrid, Text } from "@mantine/core";
import { IconArrowDownRight, IconArrowUpRight } from "@tabler/icons-react";
import type { ReactNode } from "react";
import classes from "./stats-grid.module.css";
export interface StatsGridItem {
title: string;
value: ReactNode;
diff: number;
icon?: ReactNode;
comparisonLabel?: string;
}
export interface StatsGridProps {
items: StatsGridItem[];
}
export function StatsGrid({ items }: StatsGridProps) {
const desktopColumns = Math.max(1, Math.min(items.length, 4));
const stats = items.map((stat) => {
const DiffIcon = stat.diff >= 0 ? IconArrowUpRight : IconArrowDownRight;
return (
<Paper withBorder p="md" radius="md" key={stat.title}>
<Group justify="space-between">
<Text size="xs" className={classes.title}>
{stat.title}
</Text>
{stat.icon && <span className={classes.icon}>{stat.icon}</span>}
</Group>
<Group align="flex-end" gap="xs" mt={25}>
<Text className={classes.value}>{stat.value}</Text>
<Text
c={
stat.diff >= 0
? "light-dark(var(--mantine-color-teal-9), var(--mantine-color-teal-4))"
: "light-dark(var(--mantine-color-red-9), var(--mantine-color-red-4))"
}
fz="sm"
fw={500}
className={classes.diff}
>
<span>{stat.diff}%</span>
<DiffIcon size={16} stroke={1.5} />
</Text>
</Group>
<Text fz="xs" mt={7} className={classes.comparison}>
{stat.comparisonLabel ?? "Compared to previous period"}
</Text>
</Paper>
);
});
return (
<div className={classes.root}>
<SimpleGrid cols={{ base: 1, xs: 2, md: desktopColumns }}>{stats}</SimpleGrid>
</div>
);
}
registry/mantine-ui/stats-grid/stats-grid.module.cssstyle · 707 B · css
/*
* Adapted from Mantine UI's StatsGrid at
* ffbf61c559f374a7ea28fcf00355e84dcbe9a908. MIT licensed; see
* LICENSES/MANTINE-UI.txt after installation.
*/
.root {
padding: calc(var(--mantine-spacing-xl) * 1.5);
}
.value {
font-size: 24px;
font-weight: 700;
line-height: 1;
}
.diff {
display: flex;
align-items: center;
line-height: 1;
}
.icon {
display: inline-flex;
color: light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-3));
}
.title {
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-gray-4));
font-weight: 700;
text-transform: uppercase;
}
.comparison {
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-gray-4));
}

Author notes

Adapted from Mantine UI StatsGrid at ffbf61c559…; metrics and icons are supplied by the consumer.