mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-26 22:26:05 +00:00
* feat: add phosphor icons to base ui * feat_ add phosphor to blocks * feat: add phosphor to radix blocks * feat: add phosphor to radix ui * feat: add phosphor to radix example * feat: add missing phosphor icons * fix: rename broken icons * chore: format files * fix: add missing phosphor icons * chore: build registry --------- Co-authored-by: shadcn <m@shadcn.com>
576 lines
17 KiB
TypeScript
576 lines
17 KiB
TypeScript
"use client"
|
|
|
|
import * as React from "react"
|
|
import {
|
|
Area,
|
|
AreaChart,
|
|
Bar,
|
|
BarChart,
|
|
CartesianGrid,
|
|
Label,
|
|
Line,
|
|
LineChart,
|
|
Pie,
|
|
PieChart,
|
|
PolarAngleAxis,
|
|
PolarGrid,
|
|
PolarRadiusAxis,
|
|
Radar,
|
|
RadarChart,
|
|
RadialBar,
|
|
RadialBarChart,
|
|
XAxis,
|
|
} from "recharts"
|
|
|
|
import {
|
|
Example,
|
|
ExampleWrapper,
|
|
} from "@/registry/bases/base/components/example"
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardFooter,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from "@/registry/bases/base/ui/card"
|
|
import {
|
|
ChartContainer,
|
|
ChartTooltip,
|
|
ChartTooltipContent,
|
|
type ChartConfig,
|
|
} from "@/registry/bases/base/ui/chart"
|
|
import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
|
|
|
|
const areaChartData = [
|
|
{ month: "January", desktop: 186 },
|
|
{ month: "February", desktop: 305 },
|
|
{ month: "March", desktop: 237 },
|
|
{ month: "April", desktop: 73 },
|
|
{ month: "May", desktop: 209 },
|
|
{ month: "June", desktop: 214 },
|
|
]
|
|
|
|
const areaChartConfig = {
|
|
desktop: {
|
|
label: "Desktop",
|
|
color: "var(--chart-1)",
|
|
},
|
|
} satisfies ChartConfig
|
|
|
|
export default function ChartExample() {
|
|
return (
|
|
<ExampleWrapper>
|
|
<ChartAreaExample />
|
|
<ChartBarExample />
|
|
<ChartLineExample />
|
|
<ChartRadialExample />
|
|
<ChartRadarExample />
|
|
</ExampleWrapper>
|
|
)
|
|
}
|
|
|
|
function ChartAreaExample() {
|
|
return (
|
|
<Example title="Area Chart">
|
|
<Card className="w-full">
|
|
<CardHeader>
|
|
<CardTitle>Area Chart</CardTitle>
|
|
<CardDescription>
|
|
Showing total visitors for the last 6 months
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<ChartContainer config={areaChartConfig}>
|
|
<AreaChart
|
|
accessibilityLayer
|
|
data={areaChartData}
|
|
margin={{
|
|
left: 12,
|
|
right: 12,
|
|
}}
|
|
>
|
|
<CartesianGrid vertical={false} />
|
|
<XAxis
|
|
dataKey="month"
|
|
tickLine={false}
|
|
axisLine={false}
|
|
tickMargin={8}
|
|
tickFormatter={(value) => value.slice(0, 3)}
|
|
/>
|
|
<ChartTooltip
|
|
cursor={false}
|
|
content={<ChartTooltipContent indicator="line" />}
|
|
/>
|
|
<Area
|
|
dataKey="desktop"
|
|
type="natural"
|
|
fill="var(--color-desktop)"
|
|
fillOpacity={0.4}
|
|
stroke="var(--color-desktop)"
|
|
/>
|
|
</AreaChart>
|
|
</ChartContainer>
|
|
</CardContent>
|
|
<CardFooter>
|
|
<div className="flex w-full items-start gap-2">
|
|
<div className="grid gap-2">
|
|
<div className="flex items-center gap-2 leading-none font-medium">
|
|
Trending up by 5.2% this month{" "}
|
|
<IconPlaceholder
|
|
lucide="TrendingUpIcon"
|
|
tabler="IconTrendingUp"
|
|
hugeicons="ChartUpIcon"
|
|
phosphor="TrendUpIcon"
|
|
className="size-4"
|
|
/>
|
|
</div>
|
|
<div className="text-muted-foreground flex items-center gap-2 leading-none">
|
|
January - June 2024
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</CardFooter>
|
|
</Card>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
const barChartData = [
|
|
{ month: "January", desktop: 186, mobile: 80 },
|
|
{ month: "February", desktop: 305, mobile: 200 },
|
|
{ month: "March", desktop: 237, mobile: 120 },
|
|
{ month: "April", desktop: 73, mobile: 190 },
|
|
{ month: "May", desktop: 209, mobile: 130 },
|
|
{ month: "June", desktop: 214, mobile: 140 },
|
|
]
|
|
|
|
const barChartConfig = {
|
|
desktop: {
|
|
label: "Desktop",
|
|
color: "var(--chart-1)",
|
|
},
|
|
mobile: {
|
|
label: "Mobile",
|
|
color: "var(--chart-2)",
|
|
},
|
|
} satisfies ChartConfig
|
|
|
|
function ChartBarExample() {
|
|
return (
|
|
<Example title="Bar Chart">
|
|
<Card className="w-full">
|
|
<CardHeader>
|
|
<CardTitle>Bar Chart - Multiple</CardTitle>
|
|
<CardDescription>January - June 2024</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<ChartContainer config={barChartConfig}>
|
|
<BarChart accessibilityLayer data={barChartData}>
|
|
<CartesianGrid vertical={false} />
|
|
<XAxis
|
|
dataKey="month"
|
|
tickLine={false}
|
|
tickMargin={10}
|
|
axisLine={false}
|
|
tickFormatter={(value) => value.slice(0, 3)}
|
|
/>
|
|
<ChartTooltip
|
|
cursor={false}
|
|
content={<ChartTooltipContent indicator="dashed" />}
|
|
/>
|
|
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
|
|
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
|
|
</BarChart>
|
|
</ChartContainer>
|
|
</CardContent>
|
|
<CardFooter className="flex-col items-start gap-2">
|
|
<div className="flex gap-2 leading-none font-medium">
|
|
Trending up by 5.2% this month{" "}
|
|
<IconPlaceholder
|
|
lucide="TrendingUpIcon"
|
|
tabler="IconTrendingUp"
|
|
hugeicons="ChartUpIcon"
|
|
phosphor="TrendUpIcon"
|
|
className="size-4"
|
|
/>
|
|
</div>
|
|
<div className="text-muted-foreground leading-none">
|
|
Showing total visitors for the last 6 months
|
|
</div>
|
|
</CardFooter>
|
|
</Card>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
const lineChartData = [
|
|
{ month: "January", desktop: 186, mobile: 80 },
|
|
{ month: "February", desktop: 305, mobile: 200 },
|
|
{ month: "March", desktop: 237, mobile: 120 },
|
|
{ month: "April", desktop: 73, mobile: 190 },
|
|
{ month: "May", desktop: 209, mobile: 130 },
|
|
{ month: "June", desktop: 214, mobile: 140 },
|
|
]
|
|
|
|
const lineChartConfig = {
|
|
desktop: {
|
|
label: "Desktop",
|
|
color: "var(--chart-1)",
|
|
},
|
|
mobile: {
|
|
label: "Mobile",
|
|
color: "var(--chart-2)",
|
|
},
|
|
} satisfies ChartConfig
|
|
|
|
function ChartLineExample() {
|
|
return (
|
|
<Example title="Line Chart">
|
|
<Card className="w-full">
|
|
<CardHeader>
|
|
<CardTitle>Line Chart - Multiple</CardTitle>
|
|
<CardDescription>January - June 2024</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<ChartContainer config={lineChartConfig}>
|
|
<LineChart
|
|
accessibilityLayer
|
|
data={lineChartData}
|
|
margin={{
|
|
left: 12,
|
|
right: 12,
|
|
}}
|
|
>
|
|
<CartesianGrid vertical={false} />
|
|
<XAxis
|
|
dataKey="month"
|
|
tickLine={false}
|
|
axisLine={false}
|
|
tickMargin={8}
|
|
tickFormatter={(value) => value.slice(0, 3)}
|
|
/>
|
|
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
|
|
<Line
|
|
dataKey="desktop"
|
|
type="monotone"
|
|
stroke="var(--color-desktop)"
|
|
strokeWidth={2}
|
|
dot={false}
|
|
/>
|
|
<Line
|
|
dataKey="mobile"
|
|
type="monotone"
|
|
stroke="var(--color-mobile)"
|
|
strokeWidth={2}
|
|
dot={false}
|
|
/>
|
|
</LineChart>
|
|
</ChartContainer>
|
|
</CardContent>
|
|
<CardFooter>
|
|
<div className="flex w-full items-start gap-2">
|
|
<div className="grid gap-2">
|
|
<div className="flex items-center gap-2 leading-none font-medium">
|
|
Trending up by 5.2% this month{" "}
|
|
<IconPlaceholder
|
|
lucide="TrendingUpIcon"
|
|
tabler="IconTrendingUp"
|
|
hugeicons="ChartUpIcon"
|
|
phosphor="TrendUpIcon"
|
|
className="size-4"
|
|
/>
|
|
</div>
|
|
<div className="text-muted-foreground flex items-center gap-2 leading-none">
|
|
Showing total visitors for the last 6 months
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</CardFooter>
|
|
</Card>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
const pieChartData = [
|
|
{ browser: "chrome", visitors: 275, fill: "var(--color-chrome)" },
|
|
{ browser: "safari", visitors: 200, fill: "var(--color-safari)" },
|
|
{ browser: "firefox", visitors: 287, fill: "var(--color-firefox)" },
|
|
{ browser: "edge", visitors: 173, fill: "var(--color-edge)" },
|
|
{ browser: "other", visitors: 190, fill: "var(--color-other)" },
|
|
]
|
|
|
|
const pieChartConfig = {
|
|
visitors: {
|
|
label: "Visitors",
|
|
},
|
|
chrome: {
|
|
label: "Chrome",
|
|
color: "var(--chart-1)",
|
|
},
|
|
safari: {
|
|
label: "Safari",
|
|
color: "var(--chart-2)",
|
|
},
|
|
firefox: {
|
|
label: "Firefox",
|
|
color: "var(--chart-3)",
|
|
},
|
|
edge: {
|
|
label: "Edge",
|
|
color: "var(--chart-4)",
|
|
},
|
|
other: {
|
|
label: "Other",
|
|
color: "var(--chart-5)",
|
|
},
|
|
} satisfies ChartConfig
|
|
|
|
function ChartPieExample() {
|
|
const totalVisitors = React.useMemo(() => {
|
|
return pieChartData.reduce((acc, curr) => acc + curr.visitors, 0)
|
|
}, [])
|
|
|
|
return (
|
|
<Example title="Pie Chart">
|
|
<Card className="w-full">
|
|
<CardHeader className="items-center pb-0">
|
|
<CardTitle>Pie Chart - Donut with Text</CardTitle>
|
|
<CardDescription>January - June 2024</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="flex-1 pb-0">
|
|
<ChartContainer
|
|
config={pieChartConfig}
|
|
className="mx-auto aspect-square max-h-[250px]"
|
|
>
|
|
<PieChart>
|
|
<ChartTooltip
|
|
cursor={false}
|
|
content={<ChartTooltipContent hideLabel />}
|
|
/>
|
|
<Pie
|
|
data={pieChartData}
|
|
dataKey="visitors"
|
|
nameKey="browser"
|
|
innerRadius={60}
|
|
strokeWidth={5}
|
|
>
|
|
<Label
|
|
content={({ viewBox }) => {
|
|
if (viewBox && "cx" in viewBox && "cy" in viewBox) {
|
|
return (
|
|
<text
|
|
x={viewBox.cx}
|
|
y={viewBox.cy}
|
|
textAnchor="middle"
|
|
dominantBaseline="middle"
|
|
>
|
|
<tspan
|
|
x={viewBox.cx}
|
|
y={viewBox.cy}
|
|
className="fill-foreground text-3xl font-bold"
|
|
>
|
|
{totalVisitors.toLocaleString()}
|
|
</tspan>
|
|
<tspan
|
|
x={viewBox.cx}
|
|
y={(viewBox.cy || 0) + 24}
|
|
className="fill-muted-foreground"
|
|
>
|
|
Visitors
|
|
</tspan>
|
|
</text>
|
|
)
|
|
}
|
|
}}
|
|
/>
|
|
</Pie>
|
|
</PieChart>
|
|
</ChartContainer>
|
|
</CardContent>
|
|
<CardFooter className="flex-col gap-2">
|
|
<div className="flex items-center gap-2 leading-none font-medium">
|
|
Trending up by 5.2% this month{" "}
|
|
<IconPlaceholder
|
|
lucide="TrendingUpIcon"
|
|
tabler="IconTrendingUp"
|
|
hugeicons="ChartUpIcon"
|
|
phosphor="TrendUpIcon"
|
|
className="size-4"
|
|
/>
|
|
</div>
|
|
<div className="text-muted-foreground leading-none">
|
|
Showing total visitors for the last 6 months
|
|
</div>
|
|
</CardFooter>
|
|
</Card>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
const radarChartData = [
|
|
{ month: "January", desktop: 186, mobile: 80 },
|
|
{ month: "February", desktop: 305, mobile: 200 },
|
|
{ month: "March", desktop: 237, mobile: 120 },
|
|
{ month: "April", desktop: 73, mobile: 190 },
|
|
{ month: "May", desktop: 209, mobile: 130 },
|
|
{ month: "June", desktop: 214, mobile: 140 },
|
|
]
|
|
|
|
const radarChartConfig = {
|
|
desktop: {
|
|
label: "Desktop",
|
|
color: "var(--chart-1)",
|
|
},
|
|
mobile: {
|
|
label: "Mobile",
|
|
color: "var(--chart-2)",
|
|
},
|
|
} satisfies ChartConfig
|
|
|
|
function ChartRadarExample() {
|
|
return (
|
|
<Example title="Radar Chart">
|
|
<Card className="w-full">
|
|
<CardHeader className="items-center pb-4">
|
|
<CardTitle>Radar Chart - Multiple</CardTitle>
|
|
<CardDescription>
|
|
Showing total visitors for the last 6 months
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="pb-0">
|
|
<ChartContainer
|
|
config={radarChartConfig}
|
|
className="mx-auto aspect-square max-h-[250px]"
|
|
>
|
|
<RadarChart data={radarChartData}>
|
|
<ChartTooltip
|
|
cursor={false}
|
|
content={<ChartTooltipContent indicator="line" />}
|
|
/>
|
|
<PolarAngleAxis dataKey="month" />
|
|
<PolarGrid />
|
|
<Radar
|
|
dataKey="desktop"
|
|
fill="var(--color-desktop)"
|
|
fillOpacity={0.6}
|
|
/>
|
|
<Radar dataKey="mobile" fill="var(--color-mobile)" />
|
|
</RadarChart>
|
|
</ChartContainer>
|
|
</CardContent>
|
|
<CardFooter className="flex-col gap-2">
|
|
<div className="flex items-center gap-2 leading-none font-medium">
|
|
Trending up by 5.2% this month{" "}
|
|
<IconPlaceholder
|
|
lucide="TrendingUpIcon"
|
|
tabler="IconTrendingUp"
|
|
hugeicons="ChartUpIcon"
|
|
phosphor="TrendUpIcon"
|
|
className="size-4"
|
|
/>
|
|
</div>
|
|
<div className="text-muted-foreground flex items-center gap-2 leading-none">
|
|
January - June 2024
|
|
</div>
|
|
</CardFooter>
|
|
</Card>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
const radialChartData = [
|
|
{ browser: "safari", visitors: 1260, fill: "var(--color-safari)" },
|
|
]
|
|
|
|
const radialChartConfig = {
|
|
visitors: {
|
|
label: "Visitors",
|
|
},
|
|
safari: {
|
|
label: "Safari",
|
|
color: "var(--chart-2)",
|
|
},
|
|
} satisfies ChartConfig
|
|
|
|
function ChartRadialExample() {
|
|
return (
|
|
<Example title="Radial Chart">
|
|
<Card className="w-full">
|
|
<CardHeader>
|
|
<CardTitle>Radial Chart - Shape</CardTitle>
|
|
<CardDescription>January - June 2024</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="flex-1 pb-0">
|
|
<ChartContainer
|
|
config={radialChartConfig}
|
|
className="mx-auto aspect-square max-h-[210px]"
|
|
>
|
|
<RadialBarChart
|
|
data={radialChartData}
|
|
endAngle={100}
|
|
innerRadius={80}
|
|
outerRadius={140}
|
|
>
|
|
<PolarGrid
|
|
gridType="circle"
|
|
radialLines={false}
|
|
stroke="none"
|
|
className="first:fill-muted last:fill-background"
|
|
polarRadius={[86, 74]}
|
|
/>
|
|
<RadialBar dataKey="visitors" background />
|
|
<PolarRadiusAxis tick={false} tickLine={false} axisLine={false}>
|
|
<Label
|
|
content={({ viewBox }) => {
|
|
if (viewBox && "cx" in viewBox && "cy" in viewBox) {
|
|
return (
|
|
<text
|
|
x={viewBox.cx}
|
|
y={viewBox.cy}
|
|
textAnchor="middle"
|
|
dominantBaseline="middle"
|
|
>
|
|
<tspan
|
|
x={viewBox.cx}
|
|
y={viewBox.cy}
|
|
className="fill-foreground text-4xl font-bold"
|
|
>
|
|
{radialChartData[0].visitors.toLocaleString()}
|
|
</tspan>
|
|
<tspan
|
|
x={viewBox.cx}
|
|
y={(viewBox.cy || 0) + 24}
|
|
className="fill-muted-foreground"
|
|
>
|
|
Visitors
|
|
</tspan>
|
|
</text>
|
|
)
|
|
}
|
|
}}
|
|
/>
|
|
</PolarRadiusAxis>
|
|
</RadialBarChart>
|
|
</ChartContainer>
|
|
</CardContent>
|
|
<CardFooter className="flex-col gap-2">
|
|
<div className="flex items-center gap-2 leading-none font-medium">
|
|
Trending up by 5.2% this month{" "}
|
|
<IconPlaceholder
|
|
lucide="TrendingUpIcon"
|
|
tabler="IconTrendingUp"
|
|
hugeicons="ChartUpIcon"
|
|
phosphor="TrendUpIcon"
|
|
className="size-4"
|
|
/>
|
|
</div>
|
|
<div className="text-muted-foreground leading-none">
|
|
Showing total visitors for the last 6 months
|
|
</div>
|
|
</CardFooter>
|
|
</Card>
|
|
</Example>
|
|
)
|
|
}
|