beUI Pro für Mobile ist live: 50 React Native Blöcke und Screens
Charts
Composable, animated chart components built from small parts, with keyboard support, gliding tooltips, and theme-aware color classes.
Stacked bar chart
stacked-bar-chart.tsxStacked bars over time that grow from the baseline, with a tooltip that glides beside the active bar, reference lines, projected bars, series toggles, and arrow-key navigation.
"use client";
import { useState } from "react";
import { formatCompactValue } from "@/components/charts/chart-series";
import { SeriesToggles } from "@/components/charts/series-toggles";
import {
type ChartSeries,
StackedBarChart,
StackedBarChartAxis,
StackedBarChartPlot,
StackedBarChartReferenceLine,
StackedBarChartTooltip,
type StackedBarDatum,
} from "@/components/charts/stacked-bar-chart";
const SERIES: ChartSeries[] = [
{ id: "web", label: "Web", color: "bg-blue-500" },
{ id: "mobile", label: "Mobile", color: "bg-orange-500" },
{ id: "api", label: "API", color: "bg-teal-500" },
];
const DATA: StackedBarDatum[] = Array.from({ length: 21 }, (_, i) => {
const wave = Math.sin(i / 2.4) * 0.25 + 1 + i * 0.02;
return {
id: `day-${i + 1}`,
label: `Mar ${i + 1}`,
values: {
web: Math.round(4_200 * wave + ((i * 37) % 9) * 120),
mobile: Math.round(3_100 * wave + ((i * 53) % 7) * 140),
api: Math.round(1_800 * wave + ((i * 29) % 5) * 160),
},
};
});
export function StackedBarChartPreview() {
const [visible, setVisible] = useState<ReadonlySet<string>>(
() => new Set(SERIES.map((s) => s.id)),
);
const toggle = (id: string) =>
setVisible((current) => {
const next = new Set(current);
if (next.has(id)) next.delete(id);
else next.add(id);
return next;
});
return (
<div className="mx-auto w-full max-w-3xl px-4 py-10">
<StackedBarChart
data={DATA}
series={SERIES}
visibleSeries={visible}
projectFrom={17}
projectedValue={11_000}
formatValue={formatCompactValue}
label="Requests per day"
className="pt-6"
>
<StackedBarChartPlot className="h-56">
<StackedBarChartReferenceLine value={12_000} label="Target 12k" />
<StackedBarChartTooltip />
</StackedBarChartPlot>
<StackedBarChartAxis
marks={[
{ index: 0, label: "Mar 1" },
{ index: 16, label: "Today", emphasis: true },
{ index: 20, label: "Mar 21" },
]}
/>
</StackedBarChart>
<SeriesToggles
series={SERIES}
visible={visible}
onToggle={toggle}
className="mt-6"
/>
</div>
);
}
Der Quellcode ist gesperrt
Hol dir Zugang, um Premium-Komponenten zu installieren und den vollständigen Quellcode zu sehen.
Dashboard öffnenInstallieren
Segmented meter
segmented-meter.tsxA capacity meter split into colored segments, with a gliding tooltip, a linked legend, selection, and hover state you can share with tables or lists.
Storage
1,425 of 2,000 GB
Select a segment to filter
"use client";
import { useState } from "react";
import {
type MeterSegment,
SegmentedMeter,
SegmentedMeterLegend,
SegmentedMeterTooltip,
SegmentedMeterTrack,
} from "@/components/charts/segmented-meter";
const SEGMENTS: MeterSegment[] = [
{ id: "photos", label: "Photos", value: 612, color: "bg-sky-500" },
{ id: "video", label: "Video", value: 438, color: "bg-orange-500" },
{ id: "docs", label: "Documents", value: 214, color: "bg-emerald-500" },
{ id: "backups", label: "Backups", value: 161, color: "bg-amber-500" },
];
export function SegmentedMeterPreview() {
const [selected, setSelected] = useState<string | null>(null);
const picked = SEGMENTS.find((s) => s.id === selected);
return (
<div className="mx-auto w-full max-w-xl px-4 py-10">
<div className="flex items-baseline justify-between gap-3 text-sm">
<p className="font-medium">Storage</p>
<p className="text-muted-foreground tabular-nums">1,425 of 2,000 GB</p>
</div>
<SegmentedMeter
segments={SEGMENTS}
max={2_000}
selectedId={selected}
onSelect={(id) =>
setSelected((current) => (current === id ? null : id))
}
formatValue={(value) => `${value} GB`}
label="Storage by file type"
>
<SegmentedMeterTrack className="mt-16">
<SegmentedMeterTooltip />
</SegmentedMeterTrack>
<SegmentedMeterLegend trailing="575 GB free" />
</SegmentedMeter>
<p className="mt-6 text-muted-foreground text-sm" aria-live="polite">
{picked
? `Showing ${picked.label.toLowerCase()} only`
: "Select a segment to filter"}
</p>
</div>
);
}
Der Quellcode ist gesperrt
Hol dir Zugang, um Premium-Komponenten zu installieren und den vollständigen Quellcode zu sehen.
Dashboard öffnenInstallieren
Sparkline
sparkline.tsxA compact trend line that draws in from the left and renders correctly before hydration.
- +12%
Signups
2,418
- +4%
Active teams
864
- −9%
Churned
37
- +3%
Avg. response
212 ms
"use client";
import { Sparkline } from "@/components/charts/sparkline";
const METRICS = [
{
label: "Signups",
value: "2,418",
change: "+12%",
stroke: "stroke-blue-500",
values: [12, 14, 13, 17, 16, 19, 22, 21, 24, 27, 26, 30],
},
{
label: "Active teams",
value: "864",
change: "+4%",
stroke: "stroke-teal-500",
values: [40, 41, 43, 42, 44, 45, 44, 46, 47, 47, 48, 49],
},
{
label: "Churned",
value: "37",
change: "−9%",
stroke: "stroke-orange-500",
values: [9, 8, 9, 7, 8, 6, 7, 6, 5, 6, 5, 4],
},
{
label: "Avg. response",
value: "212 ms",
change: "+3%",
stroke: "stroke-lime-500",
values: [20, 22, 19, 23, 21, 24, 22, 25, 23, 24, 26, 25],
},
];
export function SparklinePreview() {
return (
<ul className="mx-auto w-full max-w-md divide-y divide-border px-4 py-8">
{METRICS.map((metric, index) => (
<li key={metric.label} className="flex items-center gap-4 py-4">
<div className="min-w-0 flex-1">
<p className="text-muted-foreground text-sm">{metric.label}</p>
<p className="mt-0.5 font-medium text-xl tabular-nums">
{metric.value}
</p>
</div>
<Sparkline
values={metric.values}
strokeClassName={metric.stroke}
width={96}
height={32}
delay={0.2 + index * 0.1}
label={`${metric.label} trend, ${metric.change}`}
className="h-8 w-24"
/>
<span className="w-12 text-right font-mono text-muted-foreground text-xs">
{metric.change}
</span>
</li>
))}
</ul>
);
}
Der Quellcode ist gesperrt
Hol dir Zugang, um Premium-Komponenten zu installieren und den vollständigen Quellcode zu sehen.
Dashboard öffnen