This commit is contained in:
Ubuntu
2026-07-03 16:58:28 +08:00
commit 32b43f85bd
6240 changed files with 1987678 additions and 0 deletions
+55
View File
@@ -0,0 +1,55 @@
import { Card } from "@/components/retroui/Card";
import { Badge } from "@/components/retroui/Badge";
import { Text } from "@/components/retroui/Text";
import { Button } from "@/components/retroui/Button";
const CourseCard = () => {
return (
<div className="flex justify-center">
<Card className="w-[400px] mx-auto border-2 shadow-none">
{/* Course Content */}
<Card.Content>
{/* Title & Price */}
<div className="flex justify-between items-start mb-2 gap-6">
<Card.Title className="font-sans">
Advanced React Patterns
</Card.Title>
<div>
<Badge className="font-medium">
$49.99
</Badge>
</div>
</div>
{/* Description */}
<Text className="text-sm font-normal text-muted-foreground mb-4">
Master advanced React patterns and build scalable applications with
best practices.
</Text>
{/* Stats */}
<div className="flex text-sm justify-between gap-4 py-4 border-y-2 border-black/10 mb-4">
<div className="flex items-center gap-1">
<span>📚</span>
<span className="font-medium">12 Modules</span>
</div>
<div className="flex items-center gap-1">
<span>⭐</span>
<span className="font-medium">4.9/5</span>
</div>
<div className="flex items-center gap-1">
<span>👥</span>
<span className="font-medium">2.1k enrolled</span>
</div>
</div>
<Button className="w-full font-bold font-sans justify-center">
Enroll Now →
</Button>
</Card.Content>
</Card>
</div>
);
};
export default CourseCard;
+111
View File
@@ -0,0 +1,111 @@
import { Button } from "@/components/retroui/Button";
import { Text } from "@/components/retroui/Text";
import { Checkbox } from "@/components/retroui/Checkbox";
import { Input } from "@/components/retroui/Input";
import { Label } from "@/components/retroui/Label";
import { Eye, EyeOff, Github, Mail } from "lucide-react";
import { useState } from "react";
export default function SignInBlock() {
const [showPassword, setShowPassword] = useState(false);
return (
<div className="mx-auto w-full max-w-lg overflow-hidden rounded border-2 bg-card">
<div className="bg-accent p-6">
<Text as="h3" className="text-accent-foreground">Sign In</Text>
<Text className="text-sm text-accent-foreground">
Welcome back! Enter your details to access your account.
</Text>
</div>
<div className="p-6">
<div className="space-y-4">
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="you@example.com" />
</div>
<div className="space-y-2">
<div className="flex items-center justify-between">
<Label htmlFor="password">Password</Label>
<a
href="/forgot-password"
className="text-sm font-medium underline underline-offset-4"
>
Forgot password?
</a>
</div>
<div className="relative">
<Input
id="password"
type={showPassword ? "text" : "password"}
placeholder="••••••••"
/>
<button
type="button"
className="absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent"
onClick={() => setShowPassword(!showPassword)}
>
{showPassword ? (
<EyeOff className="h-4 w-4" />
) : (
<Eye className="h-4 w-4" />
)}
<span className="sr-only">
{showPassword ? "Hide password" : "Show password"}
</span>
</button>
</div>
</div>
<div className="flex items-center space-x-2">
<Checkbox id="remember" />
<label
htmlFor="remember"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Remember me
</label>
</div>
</div>
<div className="mt-8 space-y-6">
<Button className="w-full justify-center">Sign In</Button>
<div className="relative">
<div className="absolute inset-0 flex items-center">
<span className="w-full border-t border-gray-300" />
</div>
<div className="relative flex justify-center text-xs uppercase">
<span className="bg-white px-2 text-gray-500">
Or continue with
</span>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<Button
variant="secondary"
className="flex items-center justify-center"
>
<Github className="mr-2 h-5 w-5" />
Github
</Button>
<Button
variant="secondary"
className="flex items-center justify-center"
>
<Mail className="mr-2 h-5 w-5" />
Google
</Button>
</div>
</div>
<div className="mt-6 text-center text-sm">
Don't have an account?{" "}
<a
href="/sign-up"
className="font-bold underline underline-offset-4"
>
Sign up
</a>
</div>
</div>
</div>
);
}
+77
View File
@@ -0,0 +1,77 @@
import { Avatar } from "@/components/retroui/Avatar";
import { Badge } from "@/components/retroui/Badge";
import { Text } from "@/components/retroui/Text";
import { Clock, User } from "lucide-react";
export default function TeamMembersBlock() {
return (
<div className="flex flex-col gap-3">
<div
className="border-2 p-4 flex items-center justify-between gap-3 bg-card rounded"
>
<div className="flex items-center gap-3">
<Avatar className="w-10 h-10">
<Avatar.Image
src="https://pub-5f7cbdfd9ffa4c838e386788f395f0c4.r2.dev/people/person_a.png"
alt="Person A"
/>
<Avatar.Fallback>
<User className="h-5 w-5 text-muted-foreground" />
</Avatar.Fallback>
</Avatar>
<div>
<Text className="font-semibold">Alex Johnson</Text>
<span className="text-sm text-muted-foreground">alex@example.com</span>
</div>
</div>
<Badge variant="solid" size="sm">
Admin
</Badge>
</div>
<div className="border-2 p-4 flex items-center justify-between gap-3 bg-card rounded">
<div className="flex items-center gap-3">
<Avatar className="w-10 h-10">
<Avatar.Image
src="https://pub-5f7cbdfd9ffa4c838e386788f395f0c4.r2.dev/people/person_b.png"
alt="Person B"
/>
<Avatar.Fallback>
<User className="h-5 w-5 text-muted-foreground" />
</Avatar.Fallback>
</Avatar>
<div>
<Text className="font-semibold">John Doe</Text>
<span className="text-sm text-muted-foreground">john@example.com</span>
</div>
</div>
<Badge variant="solid" size="sm">
Member
</Badge>
</div>
<div className="border-2 p-4 flex items-center justify-between gap-3 bg-card rounded">
<div className="flex items-center gap-3">
<Avatar className="w-10 h-10">
<Avatar.Image
src="https://pub-5f7cbdfd9ffa4c838e386788f395f0c4.r2.dev/people/person_c.png"
alt="Person C"
/>
<Avatar.Fallback>
<User className="h-5 w-5 text-muted-foreground" />
</Avatar.Fallback>
</Avatar>
<div>
<Text className="font-semibold">Jane Smith</Text>
<span className="text-sm text-muted-foreground">jane@example.com</span>
</div>
</div>
<Badge variant="surface" size="sm">
Pending
</Badge>
</div>
</div>
);
}
@@ -0,0 +1,15 @@
// import { LineChart, Line, CartesianGrid, XAxis, YAxis, ResponsiveContainer } from 'recharts';
import { AreaChart } from "@/components/retroui/charts/AreaChart";
const data = [{ name: 'Jan', orders: 12 }, { name: 'Feb', orders: 32 }, { name: 'Mar', orders: 19 }, { name: 'Apr', orders: 35 }, { name: 'May', orders: 40 }, { name: 'Jun', orders: 25 }];
export default function ChartStyleDefault() {
return (
<AreaChart
data={data}
index="name"
categories={["orders"]}
/>
)
}
@@ -0,0 +1,24 @@
import { AreaChart } from "@/components/retroui/charts/AreaChart";
const data = [
{ date: '01', value: 120 },
{ date: '02', value: 190 },
{ date: '03', value: 300 },
{ date: '04', value: 500 },
{ date: '05', value: 280 },
{ date: '06', value: 400 }
];
export default function AreaChartStyleMinimal() {
return (
<AreaChart
data={data}
index="date"
categories={["value"]}
showGrid={false}
fillColors={["var(--muted)"]}
strokeColors={["var(--muted-foreground)"]}
className="h-32"
/>
)
}
@@ -0,0 +1,15 @@
import { AreaChart } from "@/components/retroui/charts/AreaChart";
const data = [{ name: 'Jan', orders: 12, cancel: 9 }, { name: 'Feb', orders: 32, cancel: 19 }, { name: 'Mar', orders: 19, cancel: 8 }, { name: 'Apr', orders: 35, cancel: 14 }, { name: 'May', orders: 40, cancel: 12 }, { name: 'Jun', orders: 25, cancel: 5 }];
export default function ChartStyleMultiple() {
return (
<AreaChart
data={data}
index="name"
categories={["orders", "cancel"]}
strokeColors={["var(--foreground)", "var(--destructive)"]}
fillColors={["var(--primary)", "var(--destructive)"]}
/>
)
}
@@ -0,0 +1,24 @@
import { AreaChart } from "@/components/retroui/charts/AreaChart";
const data = [
{ name: 'Jan', mobile: 20, desktop: 30, tablet: 10 },
{ name: 'Feb', mobile: 25, desktop: 35, tablet: 15 },
{ name: 'Mar', mobile: 22, desktop: 28, tablet: 12 },
{ name: 'Apr', mobile: 30, desktop: 40, tablet: 18 },
{ name: 'May', mobile: 28, desktop: 38, tablet: 16 },
{ name: 'Jun', mobile: 32, desktop: 42, tablet: 20 }
];
export default function AreaChartStyleStacked() {
return (
<AreaChart
data={data}
index="name"
showGrid={false}
categories={["mobile", "desktop", "tablet"]}
strokeColors={["var(--primary)", "var(--secondary)", "var(--accent)"]}
fillColors={["var(--primary)", "var(--secondary)", "var(--accent)"]}
fill="solid"
/>
)
}
@@ -0,0 +1,13 @@
import { BarChart } from "@/components/retroui/charts/BarChart";
const data = [{ name: 'Jan', orders: 12 }, { name: 'Feb', orders: 32 }, { name: 'Mar', orders: 19 }, { name: 'Apr', orders: 35 }, { name: 'May', orders: 40 }, { name: 'Jun', orders: 25 }];
export default function BarChartStyleDefault() {
return (
<BarChart
data={data}
index="name"
categories={["orders"]}
/>
)
}
@@ -0,0 +1,15 @@
import { BarChart } from "@/components/retroui/charts/BarChart";
const data = [{ name: 'Jan', orders: 12, cancel: 9 }, { name: 'Feb', orders: 32, cancel: 19 }, { name: 'Mar', orders: 19, cancel: 8 }, { name: 'Apr', orders: 35, cancel: 14 }, { name: 'May', orders: 40, cancel: 12 }, { name: 'Jun', orders: 25, cancel: 5 }];
export default function BarChartStyleMultiple() {
return (
<BarChart
data={data}
index="name"
categories={["orders", "cancel"]}
strokeColors={["var(--foreground)", "var(--destructive)"]}
fillColors={["var(--primary)", "var(--destructive)"]}
/>
)
}
@@ -0,0 +1,22 @@
import { BarChart } from "@/components/retroui/charts/BarChart";
const data = [
{ category: 'Sales', value: 400 },
{ category: 'Marketing', value: 300 },
{ category: 'Support', value: 200 },
{ category: 'Development', value: 500 },
{ category: 'HR', value: 100 }
];
export default function BarChartStyleHorizontal() {
return (
<BarChart
data={data}
index="category"
categories={["value"]}
alignment="horizontal"
fillColors={["var(--primary)"]}
className="h-96"
/>
)
}
@@ -0,0 +1,15 @@
import { BarChart } from "@/components/retroui/charts/BarChart";
const data = [{ name: 'Jan', orders: 12, cancel: 9 }, { name: 'Feb', orders: 32, cancel: 19 }, { name: 'Mar', orders: 19, cancel: 8 }, { name: 'Apr', orders: 35, cancel: 14 }, { name: 'May', orders: 40, cancel: 12 }, { name: 'Jun', orders: 25, cancel: 5 }];
export default function BarChartStyleMultiple() {
return (
<BarChart
data={data}
index="name"
categories={["orders", "cancel"]}
strokeColors={["var(--foreground)", "var(--destructive)"]}
fillColors={["var(--primary)", "var(--destructive)"]}
/>
)
}
@@ -0,0 +1,15 @@
import { BarChart } from "@/components/retroui/charts/BarChart";
const data = [{ name: 'Jan', orders: 12, cancel: 2 }, { name: 'Feb', orders: 32, cancel: 9 }, { name: 'Mar', orders: 19, cancel: 5 }, { name: 'Apr', orders: 35, cancel: 8 }, { name: 'May', orders: 40, cancel: 17 }, { name: 'Jun', orders: 15, cancel: 12 }];
export default function BarChartStyleStacked() {
return (
<BarChart
data={data}
index="name"
stacked
categories={["orders", "cancel"]}
fillColors={["var(--primary)", "var(--destructive)"]}
/>
)
}
@@ -0,0 +1,25 @@
import { LineChart } from "@/components/retroui/charts/LineChart";
const data = [
{ time: '00:00', cpu: 20, memory: 40 },
{ time: '04:00', cpu: 35, memory: 50 },
{ time: '08:00', cpu: 60, memory: 75 },
{ time: '12:00', cpu: 80, memory: 85 },
{ time: '16:00', cpu: 65, memory: 70 },
{ time: '20:00', cpu: 40, memory: 55 },
{ time: '24:00', cpu: 25, memory: 45 }
];
export default function LineChartStyleCurved() {
return (
<LineChart
data={data}
index="time"
categories={["cpu", "memory"]}
strokeColors={["var(--destructive)", "var(--warning)"]}
strokeWidth={3}
dotSize={6}
valueFormatter={(value) => `${value}%`}
/>
)
}
@@ -0,0 +1,13 @@
import { LineChart } from "@/components/retroui/charts/LineChart";
const data = [{ name: 'Jan', orders: 12 }, { name: 'Feb', orders: 32 }, { name: 'Mar', orders: 19 }, { name: 'Apr', orders: 35 }, { name: 'May', orders: 40 }, { name: 'Jun', orders: 25 }];
export default function LineChartStyleDefault() {
return (
<LineChart
data={data}
index="name"
categories={["orders"]}
/>
)
}
@@ -0,0 +1,25 @@
import { LineChart } from "@/components/retroui/charts/LineChart";
const data = [
{ week: 'W1', engagement: 85 },
{ week: 'W2', engagement: 92 },
{ week: 'W3', engagement: 78 },
{ week: 'W4', engagement: 96 },
{ week: 'W5', engagement: 88 },
{ week: 'W6', engagement: 94 }
];
export default function LineChartStyleDots() {
return (
<LineChart
data={data}
index="week"
categories={["engagement"]}
strokeColors={["var(--primary)"]}
strokeWidth={1}
dotSize={8}
showGrid={false}
valueFormatter={(value) => `${value}%`}
/>
)
}
@@ -0,0 +1,14 @@
import { LineChart } from "@/components/retroui/charts/LineChart";
const data = [{ name: 'Jan', orders: 12, cancel: 9 }, { name: 'Feb', orders: 32, cancel: 19 }, { name: 'Mar', orders: 19, cancel: 8 }, { name: 'Apr', orders: 35, cancel: 14 }, { name: 'May', orders: 40, cancel: 12 }, { name: 'Jun', orders: 25, cancel: 5 }];
export default function LineChartStyleMultiple() {
return (
<LineChart
data={data}
index="name"
categories={["orders", "cancel"]}
strokeColors={["var(--foreground)", "var(--destructive)"]}
/>
)
}
@@ -0,0 +1,18 @@
import { PieChart } from "@/components/retroui/charts/PieChart";
const data = [
{ name: 'Desktop', value: 400 },
{ name: 'Mobile', value: 300 },
{ name: 'Tablet', value: 200 },
{ name: 'Other', value: 100 }
];
export default function PieChartStyleDefault() {
return (
<PieChart
data={data}
dataKey="value"
nameKey="name"
/>
)
}
@@ -0,0 +1,20 @@
import { PieChart } from "@/components/retroui/charts/PieChart";
const data = [
{ name: 'Desktop', value: 400 },
{ name: 'Mobile', value: 300 },
{ name: 'Tablet', value: 200 },
{ name: 'Other', value: 100 }
];
export default function PieChartStyleDonut() {
return (
<PieChart
data={data}
dataKey="value"
nameKey="name"
innerRadius={70}
colors={["var(--primary)", "var(--secondary)", "var(--destructive)", "var(--muted)"]}
/>
)
}
@@ -0,0 +1,22 @@
import { PieChart } from "@/components/retroui/charts/PieChart";
const data = [
{ browser: 'Chrome', users: 65 },
{ browser: 'Firefox', users: 25 },
{ browser: 'Safari', users: 8 },
{ browser: 'Edge', users: 2 }
];
export default function PieChartStyleSmall() {
return (
<PieChart
data={data}
dataKey="users"
nameKey="browser"
outerRadius={60}
colors={["var(--chart-1)", "var(--chart-2)", "var(--chart-3)", "var(--chart-4)"]}
valueFormatter={(value) => `${value}%`}
className="h-60"
/>
)
}
@@ -0,0 +1,28 @@
"use client";
import { Accordion } from "@/components/retroui/Accordion";
export default function AccordionStyleDefault() {
return (
<Accordion type="single" collapsible className="space-y-4 w-full">
<Accordion.Item value="item-1">
<Accordion.Header>Accordion Item 1</Accordion.Header>
<Accordion.Content>
This is the content of the first accordion item.
</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="item-2">
<Accordion.Header>Accordion Item 2</Accordion.Header>
<Accordion.Content>
This is the content of the second accordion item.
</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="item-3">
<Accordion.Header>Accordion Item 3</Accordion.Header>
<Accordion.Content>
This is the content of the third accordion item.
</Accordion.Content>
</Accordion.Item>
</Accordion>
);
}
@@ -0,0 +1,25 @@
import { Alert } from "@/components/retroui/Alert";
import { CheckCircle, InfoIcon, XIcon } from "lucide-react";
export default function AlertAllStatus() {
return (
<div className="space-y-4">
<Alert status="success" className="flex items-center">
<CheckCircle className="h-4 w-4 mr-4" />
<Alert.Title>This is a success alert!</Alert.Title>
</Alert>
<Alert status="info" className="flex items-center">
<InfoIcon className="h-4 w-4 mr-4" />
<Alert.Title>This is an info alert!</Alert.Title>
</Alert>
<Alert status="error" className="flex items-center">
<XIcon className="h-4 w-4 mr-4" />
<Alert.Title>This is an error alert!</Alert.Title>
</Alert>
<Alert status="warning" className="flex items-center">
<InfoIcon className="h-4 w-4 mr-4" />
<Alert.Title>This is an error alert!</Alert.Title>
</Alert>
</div>
);
}
@@ -0,0 +1,12 @@
import { Alert } from "@/components/retroui/Alert";
export default function AlertStyleDefault() {
return (
<Alert>
<Alert.Title>Heads up!</Alert.Title>
<Alert.Description>
This is where you can write description that no one reads...
</Alert.Description>
</Alert>
);
}
@@ -0,0 +1,12 @@
import { Alert } from "@/components/retroui/Alert";
export default function AlertStyleDefault() {
return (
<Alert variant="solid">
<Alert.Title>Heads up!</Alert.Title>
<Alert.Description>
This is where you can write description that no one reads...
</Alert.Description>
</Alert>
);
}
@@ -0,0 +1,16 @@
import { Alert } from "@/components/retroui/Alert";
import { CheckCircle } from "lucide-react";
export default function AlertStyleDefaultIcon() {
return (
<Alert className="flex">
<CheckCircle className="h-5 w-5 mr-4 mt-2" />
<div>
<Alert.Title>Heads up!</Alert.Title>
<Alert.Description>
This is where you can write description that no one reads...
</Alert.Description>
</div>
</Alert>
);
}
@@ -0,0 +1,10 @@
import { Avatar } from "@/components/retroui/Avatar";
export default function AvatarStyleFallback() {
return (
<Avatar>
<Avatar.Image src="broken-link" alt="Arif Logs" />
<Avatar.Fallback>AH</Avatar.Fallback>
</Avatar>
);
}
@@ -0,0 +1,20 @@
import { Avatar } from "@/components/retroui/Avatar";
export default function AvatarStyleCircleSizes() {
return (
<div className="flex items-center space-x-4">
<Avatar>
<Avatar.Image src="/images/avatar.jpeg" alt="Arif Logs" />
<Avatar.Fallback>AH</Avatar.Fallback>
</Avatar>
<Avatar className="h-16 w-16">
<Avatar.Image src="/images/avatar.jpeg" alt="Arif Logs" />
<Avatar.Fallback>AH</Avatar.Fallback>
</Avatar>
<Avatar className="h-20 w-20">
<Avatar.Image src="/images/avatar.jpeg" alt="Arif Logs" />
<Avatar.Fallback>AH</Avatar.Fallback>
</Avatar>
</div>
);
}
@@ -0,0 +1,10 @@
import { Avatar } from "@/components/retroui/Avatar";
export default function AvatarStyleCircle() {
return (
<Avatar>
<Avatar.Image src="/images/avatar.jpeg" alt="Arif Logs" />
<Avatar.Fallback>AH</Avatar.Fallback>
</Avatar>
);
}
@@ -0,0 +1,5 @@
import { Badge } from "@/components/retroui/Badge";
export default function BadgeStyleDefault() {
return <Badge>Default Badge</Badge>;
}
@@ -0,0 +1,14 @@
import { Badge } from "@/components/retroui/Badge";
export default function BadgeStyleRounded() {
return (
<div className="space-x-4">
<Badge variant="solid" className="rounded-sm">
Rounded
</Badge>
<Badge variant="solid" className="rounded-full">
Full
</Badge>
</div>
);
}
@@ -0,0 +1,11 @@
import { Badge } from "@/components/retroui/Badge";
export default function BadgeStyleVariants() {
return (
<div className="space-x-4">
<Badge size="sm">small</Badge>
<Badge>medium</Badge>
<Badge size="lg">large</Badge>
</div>
);
}
@@ -0,0 +1,12 @@
import { Badge } from "@/components/retroui/Badge";
export default function BadgeStyleVariants() {
return (
<div className="flex flex-wrap gap-4">
<Badge>Default</Badge>
<Badge variant="outline">Outlined</Badge>
<Badge variant="solid">Solid</Badge>
<Badge variant="surface">Surface</Badge>
</div>
);
}
@@ -0,0 +1,26 @@
import { Breadcrumb } from "@/components/retroui/Breadcrumb";
import { Slash } from "lucide-react";
export default function BreadcrumbCustomSeparator() {
return (
<Breadcrumb>
<Breadcrumb.List>
<Breadcrumb.Item>
<Breadcrumb.Link href="/">Home</Breadcrumb.Link>
</Breadcrumb.Item>
<Breadcrumb.Separator>
<Slash />
</Breadcrumb.Separator>
<Breadcrumb.Item>
<Breadcrumb.Link href="/docs/components">Components</Breadcrumb.Link>
</Breadcrumb.Item>
<Breadcrumb.Separator>
<Slash />
</Breadcrumb.Separator>
<Breadcrumb.Item>
<Breadcrumb.Page>Breadcrumb</Breadcrumb.Page>
</Breadcrumb.Item>
</Breadcrumb.List>
</Breadcrumb>
);
}
@@ -0,0 +1,27 @@
import Link from "next/link"
import { Breadcrumb } from "@/components/retroui/Breadcrumb"
export default function BreadcrumbLinkComponent() {
return (
<Breadcrumb>
<Breadcrumb.List>
<Breadcrumb.Item>
<Breadcrumb.Link asChild>
<Link href="/">Home</Link>
</Breadcrumb.Link>
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item>
<Breadcrumb.Link asChild>
<Link href="/docs/components">Components</Link>
</Breadcrumb.Link>
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item>
<Breadcrumb.Page>Breadcrumb</Breadcrumb.Page>
</Breadcrumb.Item>
</Breadcrumb.List>
</Breadcrumb>
)
}
@@ -0,0 +1,30 @@
import Link from "next/link"
import { Breadcrumb } from "@/components/retroui/Breadcrumb";
export default function BreadcrumbCollapsed() {
return (
<Breadcrumb>
<Breadcrumb.List>
<Breadcrumb.Item>
<Breadcrumb.Link asChild>
<Link href="/">Home</Link>
</Breadcrumb.Link>
</Breadcrumb.Item>
<Breadcrumb.Item>
<Breadcrumb.Ellipsis />
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item>
<Breadcrumb.Link asChild>
<Link href="/docs/components">Components</Link>
</Breadcrumb.Link>
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item>
<Breadcrumb.Page>Breadcrumb</Breadcrumb.Page>
</Breadcrumb.Item>
</Breadcrumb.List>
</Breadcrumb>
)
}
@@ -0,0 +1,21 @@
import { Breadcrumb } from "@/components/retroui/Breadcrumb";
export default function BreadcrumbStyleDefault() {
return (
<Breadcrumb>
<Breadcrumb.List>
<Breadcrumb.Item>
<Breadcrumb.Link href="/">Home</Breadcrumb.Link>
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item>
<Breadcrumb.Link href="/docs/components">Components</Breadcrumb.Link>
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item>
<Breadcrumb.Page>Breadcrumb</Breadcrumb.Page>
</Breadcrumb.Item>
</Breadcrumb.List>
</Breadcrumb>
);
}
@@ -0,0 +1,5 @@
import { Button } from "@/components/retroui/Button";
export default function ButtonStyleDefault() {
return <Button>Click Me!</Button>;
}
@@ -0,0 +1,10 @@
import { Button } from "@/components/retroui/Button";
import { PenIcon } from "lucide-react";
export default function ButtonStyleIcon() {
return (
<Button size="icon">
<PenIcon className="w-4 h-4" />
</Button>
);
}
@@ -0,0 +1,5 @@
import { Button } from "@/components/retroui/Button";
export default function ButtonStyleLink() {
return <Button variant="link">Click Me!</Button>;
}
@@ -0,0 +1,5 @@
import { Button } from "@/components/retroui/Button";
export default function ButtonStyleOutline() {
return <Button variant="outline">Click Me!</Button>;
}
@@ -0,0 +1,5 @@
import { Button } from "@/components/retroui/Button";
export default function ButtonStyleSecondary() {
return <Button variant="secondary">Click Me!</Button>;
}
@@ -0,0 +1,10 @@
import { Button } from "@/components/retroui/Button";
import { Trash } from "lucide-react";
export default function ButtonStyleWithIcon() {
return (
<Button className="bg-destructive text-white hover:bg-destructive/90">
<Trash className="h-4 w-4 mr-2" /> Delete
</Button>
);
}
@@ -0,0 +1,18 @@
"use client"
import { Calendar } from "@/components/retroui/Calendar"
const start = new Date()
export default function CalendarStyleDefault() {
return (
<div className="max-w-[350px] w-full">
<Calendar
numberOfMonths={1}
mode="single"
defaultMonth={start}
selected={start}
/>
</div>
)
}
@@ -0,0 +1,23 @@
import { Button } from "@/components/retroui/Button";
import { Card } from "@/components/retroui/Card";
export default function CommerceCard() {
return (
<Card className="w-[350px] shadow-none hover:shadow-none">
<Card.Content className="pb-0">
<img
src="/images/gameboy.jpg"
className="w-full h-full"
alt="Gameboy"
/>
</Card.Content>
<Card.Header className="pb-0">
<Card.Title>Classic 8-bit Gameboy</Card.Title>
</Card.Header>
<Card.Content className="flex justify-between items-center">
<p className="text-lg font-semibold">$29.90</p>
<Button>Add to cart</Button>
</Card.Content>
</Card>
);
}
@@ -0,0 +1,15 @@
import { Card } from "@/components/retroui/Card";
export default function BasicCard() {
return (
<Card>
<Card.Header>
<Card.Title>This is Card Title</Card.Title>
<Card.Description>
I can not find what to write here.. so imagine I wrote some good
stuff.
</Card.Description>
</Card.Header>
</Card>
);
}
@@ -0,0 +1,30 @@
import { Text } from "@/components/retroui/Text";
import { Card } from "@/components/retroui/Card";
import { Avatar } from "@/components/retroui/Avatar";
export default function TestimonialCard() {
return (
<Card className="w-full max-w-[400px] shadow-none hover:shadow-md">
<Card.Content>
<Text className="text-lg">
&quot; RetroUI is the cooling looking UI library out there! &quot;
</Text>
<div className="flex items-center space-x-2 mt-6">
<Avatar className="h-10 w-10">
<Avatar.Image
alt="avatar"
src="https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=880&q=80"
/>
</Avatar>
<div>
<div className="font-medium">Leroy Jenkins</div>
<div className="text-sm text-gray-500 dark:text-gray-400">
CEO of Uber
</div>
</div>
</div>
</Card.Content>
</Card>
);
}
@@ -0,0 +1,28 @@
import * as React from "react"
import { Card } from "@/components/retroui/Card"
import {
Carousel,
} from "@/components/retroui/Carousel"
export default function CarouselStyleDefault() {
return (
<Carousel className="w-full max-w-xs">
<Carousel.Content>
{Array.from({ length: 5 }).map((_, index) => (
<Carousel.Item key={index}>
<div className="p-4">
<Card className="w-full">
<Card.Content className="flex aspect-square items-center justify-center p-6">
<span className="text-4xl font-semibold">{index + 1}</span>
</Card.Content>
</Card>
</div>
</Carousel.Item>
))}
</Carousel.Content>
<Carousel.Previous />
<Carousel.Next />
</Carousel>
)
}
@@ -0,0 +1,28 @@
import * as React from "react"
import { Card } from "@/components/retroui/Card"
import {
Carousel,
} from "@/components/retroui/Carousel"
export default function CarouselStyleSizes() {
return (
<Carousel className="w-full max-w-sm">
<Carousel.Content>
{Array.from({ length: 5 }).map((_, index) => (
<Carousel.Item key={index} className="md:basis-1/2 lg:basis-1/3">
<div className="p-1">
<Card className="w-full">
<Card.Content className="flex aspect-square items-center justify-center p-6">
<span className="text-4xl font-semibold">{index + 1}</span>
</Card.Content>
</Card>
</div>
</Carousel.Item>
))}
</Carousel.Content>
<Carousel.Previous />
<Carousel.Next />
</Carousel>
)
}
@@ -0,0 +1,37 @@
import * as React from "react"
import { Card } from "@/components/retroui/Card"
import {
Carousel,
} from "@/components/retroui/Carousel"
const cards = [
{label: "1", color: "purple-300"},
{label: "2", color: "green-300"},
{label: "3", color: "red-300"},
{label: "4", color: "yellow-300"},
{label: "5", color: "blue-300"},
]
export default function CarouselStyleVertical() {
return (
<Carousel opts={{
align: "start",
}} className="w-full max-w-xs" orientation="vertical">
<Carousel.Content className="h-[300px]">
{cards.map((card, index) => (
<Carousel.Item key={index} className="md:basis-1/2">
<div className="p-1">
<Card className={`w-full h-[200px] bg-${card.color} rounded-lg`}>
<Card.Content className="flex h-full w-full items-center justify-center p-6">
<span className="text-4xl font-semibold">{card.label}</span>
</Card.Content>
</Card>
</div>
</Carousel.Item>
))}
</Carousel.Content>
<Carousel.Previous className="rounded-full shadow-sm" />
<Carousel.Next className="rounded-full shadow-sm" />
</Carousel>
)
}
@@ -0,0 +1,11 @@
import { Checkbox } from "@/components/retroui/Checkbox";
import { Text } from "@/components/retroui/Text";
export default function CheckboxStyleDefault() {
return (
<div className="flex gap-2 items-center">
<Checkbox />
<Text>Accept terms and conditions</Text>
</div>
);
}
@@ -0,0 +1,11 @@
import { Checkbox } from "@/components/retroui/Checkbox";
export default function CheckboxStyleSizes() {
return (
<div className="flex gap-4">
<Checkbox size="sm" />
<Checkbox />
<Checkbox size="lg" />
</div>
);
}
@@ -0,0 +1,11 @@
import { Checkbox } from "@/components/retroui/Checkbox";
export default function CheckboxStyleVariants() {
return (
<div className="flex gap-4">
<Checkbox />
<Checkbox variant="outline" />
<Checkbox variant="solid" />
</div>
);
}
@@ -0,0 +1,57 @@
"use client";
import { Command } from "@/components/retroui/Command";
import {
Settings,
User,
Calendar,
Calculator,
Smile,
CreditCard,
} from "lucide-react";
export default function CommandStyleDefault() {
return (
<div className="space-y-4">
<Command className="border shadow-md md:min-w-[450px] max-w-[500px]">
<Command.Input placeholder="Type a command or search..." />
<Command.List>
<Command.Empty>No results found.</Command.Empty>
<Command.Group heading="Suggestions">
<Command.Item>
<Calendar />
<span>Calendar</span>
</Command.Item>
<Command.Item>
<Smile />
<span>Search Emoji</span>
</Command.Item>
<Command.Item disabled>
<Calculator />
<span>Calculator</span>
</Command.Item>
</Command.Group>
<Command.Separator />
<Command.Group heading="Settings">
<Command.Item>
<User />
<span>Profile</span>
<Command.Shortcut>⌘P</Command.Shortcut>
</Command.Item>
<Command.Item>
<CreditCard />
<span>Billing</span>
<Command.Shortcut>⌘B</Command.Shortcut>
</Command.Item>
<Command.Item>
<Settings />
<span>Settings</span>
<Command.Shortcut>⌘S</Command.Shortcut>
</Command.Item>
</Command.Group>
</Command.List>
</Command>
</div>
);
}
@@ -0,0 +1,78 @@
"use client";
import * as React from "react";
import { Command } from "@/components/retroui/Command";
import {
Calculator,
Calendar,
CreditCard,
Settings,
Smile,
User,
} from "lucide-react";
export default function Component() {
const [open, setOpen] = React.useState(false);
React.useEffect(() => {
const down = (e: KeyboardEvent) => {
if (e.key === "j" && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
setOpen((open) => !open);
}
};
document.addEventListener("keydown", down);
return () => document.removeEventListener("keydown", down);
}, []);
return (
<>
<p className="text-muted-foreground text-sm">
Press{" "}
<kbd className="bg-muted text-muted-foreground pointer-events-none inline-flex h-5 items-center gap-1 rounded border px-1.5 font-mono text-[10px] font-medium opacity-100 select-none">
<span className="text-xs">⌘</span>J
</kbd>
</p>
<Command.Dialog open={open} onOpenChange={setOpen}>
<Command.Input placeholder="Type a command or search..." />
<Command.List>
<Command.Empty>No results found.</Command.Empty>
<Command.Group heading="Suggestions">
<Command.Item>
<Calendar />
<span>Calendar</span>
</Command.Item>
<Command.Item>
<Smile />
<span>Search Emoji</span>
</Command.Item>
<Command.Item>
<Calculator />
<span>Calculator</span>
</Command.Item>
</Command.Group>
<Command.Separator />
<Command.Group heading="Settings">
<Command.Item>
<User />
<span>Profile</span>
<Command.Shortcut>⌘P</Command.Shortcut>
</Command.Item>
<Command.Item>
<CreditCard />
<span>Billing</span>
<Command.Shortcut>⌘B</Command.Shortcut>
</Command.Item>
<Command.Item>
<Settings />
<span>Settings</span>
<Command.Shortcut>⌘S</Command.Shortcut>
</Command.Item>
</Command.Group>
</Command.List>
</Command.Dialog>
</>
);
}
@@ -0,0 +1,42 @@
"use client";
import { ContextMenu } from "@/components/retroui/ContextMenu";
export default function ContextMenuStyleDefault() {
return (
<div className="flex items-center justify-center min-h-[200px] p-8">
<ContextMenu>
<ContextMenu.Trigger
className="flex h-[150px] w-[300px] items-center justify-center
border-2 border-dashed border-border text-sm bg-background
transition-all"
>
Right click here
</ContextMenu.Trigger>
<ContextMenu.Content>
<ContextMenu.Item>Copy</ContextMenu.Item>
<ContextMenu.Item>Cut</ContextMenu.Item>
<ContextMenu.Item>Paste</ContextMenu.Item>
<ContextMenu.Separator />
<ContextMenu.Item>Share</ContextMenu.Item>
<ContextMenu.Sub>
<ContextMenu.SubTrigger>More options</ContextMenu.SubTrigger>
<ContextMenu.SubContent>
<ContextMenu.Item>Archive</ContextMenu.Item>
<ContextMenu.Item>Delete</ContextMenu.Item>
</ContextMenu.SubContent>
</ContextMenu.Sub>
<ContextMenu.Separator />
<ContextMenu.CheckboxItem checked>
Show hidden files
</ContextMenu.CheckboxItem>
<ContextMenu.RadioGroup value="one">
<ContextMenu.Label>View mode</ContextMenu.Label>
<ContextMenu.RadioItem value="one">List</ContextMenu.RadioItem>
<ContextMenu.RadioItem value="two">Grid</ContextMenu.RadioItem>
</ContextMenu.RadioGroup>
</ContextMenu.Content>
</ContextMenu>
</div>
);
}
@@ -0,0 +1,29 @@
import { Button } from "@/components/retroui/Button";
import { Dialog } from "@/components/retroui/Dialog";
import { Text } from "@/components/retroui/Text";
export default function DialogStyleDefault() {
return (
<Dialog>
<Dialog.Trigger asChild>
<Button>Open Dialog</Button>
</Dialog.Trigger>
<Dialog.Content>
<Dialog.Header>
<Text as="h5">Confirm your action?</Text>
</Dialog.Header>
<section className="flex flex-col gap-4 p-4">
<section className="text-xl">
<p>Are you sure you want to delete this item?</p>
<p>This action cannout be undone.</p>
</section>
<section className="flex w-full justify-end">
<Dialog.Trigger asChild>
<Button>Confirm</Button>
</Dialog.Trigger>
</section>
</section>
</Dialog.Content>
</Dialog>
);
}
@@ -0,0 +1,61 @@
import { Button } from "@/components/retroui/Button";
import { Dialog } from "@/components/retroui/Dialog";
import { Text } from "@/components/retroui/Text";
import { useState } from "react";
type Variants =
| "auto"
| "sm"
| "md"
| "lg"
| "xl"
| "2xl"
| "3xl"
| "4xl"
| "screen";
export default function DialogStyleWidthVariant() {
const [variant, setVariant] = useState<Variants>("auto");
const sizes: Variants[] = [
"auto",
"sm",
"md",
"lg",
"xl",
"2xl",
"3xl",
"4xl",
"screen",
];
return (
<Dialog>
<Dialog.Trigger asChild>
<Button>Open Dialog</Button>
</Dialog.Trigger>
<Dialog.Content size={variant}>
<Dialog.Header>
<Text as="h5">Dialog with variants</Text>
</Dialog.Header>
<section className="flex flex-col gap-4 p-4">
<section className="text-xl">
<p>Choose your width size</p>
<section className="flex flex-wrap gap-4">
{sizes.map((singleVariant) => (
<Button
key={"variant-list-" + singleVariant}
type="button"
variant={singleVariant == variant ? "default" : "outline"}
onClick={() => setVariant(singleVariant)}
>
{singleVariant}
</Button>
))}
</section>
</section>
</section>
</Dialog.Content>
</Dialog>
);
}
@@ -0,0 +1,32 @@
import { Button } from "@/components/retroui/Button";
import { Text } from "@/components/retroui/Text";
import { Dialog } from "@/components/retroui/Dialog";
export default function DialogStyleWithFooter() {
return (
<Dialog>
<Dialog.Trigger asChild>
<Button>Open Dialog</Button>
</Dialog.Trigger>
<Dialog.Content>
<Dialog.Header position={"fixed"} asChild>
<Text as="h5">Confirm your action?</Text>
</Dialog.Header>
<section className="flex flex-col gap-4 p-4">
<section className="text-xl">
<p>Are you sure you want to delete this item?</p>
<p>This action cannout be undone.</p>
</section>
</section>
<Dialog.Footer>
<Dialog.Trigger asChild>
<Button>Confirm</Button>
</Dialog.Trigger>
<Dialog.Trigger asChild>
<Button variant={"outline"}>Close</Button>
</Dialog.Trigger>
</Dialog.Footer>
</Dialog.Content>
</Dialog>
);
}
@@ -0,0 +1,40 @@
import { Button } from "@/components/retroui/Button";
import { Dialog } from "@/components/retroui/Dialog";
import { Input } from "@/components/retroui/Input";
import { Text } from "@/components/retroui/Text";
export default function DialogStyleWithForm() {
return (
<Dialog>
<Dialog.Trigger asChild>
<Button>Open Form</Button>
</Dialog.Trigger>
<Dialog.Content size={"md"}>
<Dialog.Header position={"fixed"}>
<Text as="h5">Contact Us</Text>
</Dialog.Header>
<form className="flex flex-col gap-4">
<div className="flex flex-col p-4 gap-4">
<div className="flex-col gap-2">
<label htmlFor="name">
Your name <span className="text-red-500">*</span>
</label>
<Input placeholder="Type your name" required />
</div>
<div className="flex-col gap-2">
<label htmlFor="name">
Your e-email <span className="text-red-500">*</span>
</label>
<Input placeholder="Type your name" required />
</div>
</div>
<Dialog.Footer>
<Dialog.Trigger asChild>
<Button type="submit">Submit</Button>
</Dialog.Trigger>
</Dialog.Footer>
</form>
</Dialog.Content>
</Dialog>
);
}
@@ -0,0 +1,28 @@
import * as React from "react"
import { Drawer } from "@/components/retroui/Drawer"
import { Button } from "@/components/retroui/Button"
export default function DrawerStyleDefault() {
return (
<Drawer>
<Drawer.Trigger asChild>
<Button>Submit</Button>
</Drawer.Trigger>
<Drawer.Content>
<Drawer.Header>
<Drawer.Title>Are you absolutely sure?</Drawer.Title>
<Drawer.Description>This action cannot be undone.</Drawer.Description>
</Drawer.Header>
<Drawer.Footer>
<div className="flex justify-center gap-3">
<Button>Submit</Button>
<Drawer.Close>
<Button variant="outline">Cancel</Button>
</Drawer.Close>
</div>
</Drawer.Footer>
</Drawer.Content>
</Drawer>
)
}
@@ -0,0 +1,41 @@
import * as React from "react"
import { Drawer } from "@/components/retroui/Drawer"
import { Button } from "@/components/retroui/Button"
import { Input } from "@/components/retroui/Input"
import { Label } from "@/components/retroui/Label"
import { Textarea } from "@/components/retroui/Textarea"
export default function DrawerStyleRightDirection() {
return (
<Drawer direction="right">
<Drawer.Trigger asChild>
<Button>Review Us</Button>
</Drawer.Trigger>
<Drawer.Content>
<Drawer.Header>
<Drawer.Title>Edit Profile</Drawer.Title>
<Drawer.Description>Make changes to your profile here. Click save when you're done.</Drawer.Description>
</Drawer.Header>
<form className="flex flex-col space-y-4 p-4">
<div className="flex flex-col space-y-2">
<Label>Email</Label>
<Input placeholder="Enter your email" />
</div>
<div className="flex flex-col space-y-2">
<Label>Comment</Label>
<Textarea rows={4} placeholder="Enter your comment" />
</div>
</form>
<Drawer.Footer>
<div className="flex justify-start gap-3">
<Button>Submit</Button>
<Drawer.Close>
<Button variant="outline">Cancel</Button>
</Drawer.Close>
</div>
</Drawer.Footer>
</Drawer.Content>
</Drawer>
)
}
@@ -0,0 +1,20 @@
import { Button, Empty } from "@/components/retroui";
import { InboxIcon } from "lucide-react";
export default function CustomEverythingEmpty() {
return (
<Empty>
<Empty.Content>
<Empty.Icon>
<InboxIcon className="size-10 md:size-12" />
</Empty.Icon>
<Empty.Title>No data</Empty.Title>
<Empty.Description>
Get started by creating your first item
</Empty.Description>
<Button>Create now</Button>
</Empty.Content>
</Empty>
);
}
@@ -0,0 +1,19 @@
import { Empty } from "@/components/retroui/Empty";
export default function CustomIconEmpty() {
return (
<Empty>
<Empty.Content>
<Empty.Icon>
<span className="text-4xl">👻</span>
</Empty.Icon>
<Empty.Title>No data</Empty.Title>
<Empty.Separator />
<Empty.Description>
There is nothing to show here yet. Imagine you wrote some good stuff
here.
</Empty.Description>
</Empty.Content>
</Empty>
);
}
@@ -0,0 +1,16 @@
import { Empty } from "@/components/retroui";
export default function DefaultEmpty() {
return (
<Empty>
<Empty.Content>
<Empty.Icon className="size-10 md:size-12" />
<Empty.Title>No Results</Empty.Title>
<Empty.Separator />
<Empty.Description>
Your search didn't match any items. Try adjusting your filters.
</Empty.Description>
</Empty.Content>
</Empty>
);
}
@@ -0,0 +1,39 @@
import { Empty } from "@/components/retroui/Empty";
import { Table } from "@/components/retroui/Table";
const invoices = [];
export default function TableEmpty() {
return (
<Table className="mx-auto">
<Table.Header>
<Table.Row>
<Table.Head className="w-[100px]">Invoice</Table.Head>
<Table.Head>Customer</Table.Head>
<Table.Head>Status</Table.Head>
<Table.Head>Method</Table.Head>
<Table.Head className="text-right">Amount</Table.Head>
</Table.Row>
</Table.Header>
<Table.Body>
{invoices?.length === 0 && (
<Table.Row>
<Table.Cell colSpan={5}>
<Empty className="border-none shadow-none">
<Empty.Content>
<Empty.Icon className="size-8" />
<Empty.Title className="md:text-base">Empty</Empty.Title>
<Empty.Description>
Get started by creating your first invoice.
</Empty.Description>
</Empty.Content>
</Empty>
</Table.Cell>
</Table.Row>
)}
</Table.Body>
</Table>
);
}
@@ -0,0 +1,5 @@
import { Input } from "@/components/retroui/Input";
export default function InputStyleDefault() {
return <Input type="text" placeholder="type something..." />;
}
@@ -0,0 +1,18 @@
import { Input } from "@/components/retroui/Input";
import { Label } from "@/components/retroui/Label";
export default function InputStyleError() {
return (
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="pokemon">Favorite Pokemon</Label>
<Input
type="pokemon"
id="pokemon"
placeholder="Charmander"
defaultValue="Son Goku"
aria-invalid
/>
<p className="text-sm text-red-500">Please provide a valid pokemon!</p>
</div>
);
}
@@ -0,0 +1,11 @@
import { Input } from "@/components/retroui/Input";
import { Label } from "@/components/retroui/Label";
export default function InputStyleWithLabel() {
return (
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="pokemon">Favorite Pokemon</Label>
<Input type="pokemon" id="pokemon" placeholder="Charmander" />
</div>
);
}
@@ -0,0 +1,10 @@
import { Input, Label } from "@/components/retroui";
export default function LabelStyleDefault() {
return (
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="pokemon">Favorite Pokemon</Label>
<Input type="pokemon" id="pokemon" placeholder="Charmander" />
</div>
);
}
+13
View File
@@ -0,0 +1,13 @@
"use client";
import { Checkbox } from "@/components/retroui";
import { Label } from "@/components/retroui";
export default function LabelDefault() {
return (
<div className="flex items-center bg-background space-x-2">
<Checkbox id="terms" />
<Label htmlFor="terms">Accept terms and conditions</Label>
</div>
);
}
@@ -0,0 +1,16 @@
import { Loader } from "@/components/retroui/Loader";
export default function LoaderPreview() {
return (
<div className="flex flex-col gap-4">
<div className="flex items-center gap-4">
<Loader count={4} />
<Loader count={5} delayStep={80} />
</div>
<div className="flex items-center gap-4">
<Loader duration={1.5} />
<Loader variant="secondary" count={4} duration={1.2} delayStep={120} />
</div>
</div>
);
}
@@ -0,0 +1,6 @@
import { Loader } from "@/components/retroui/Loader";
export default function LoaderPreview() {
return <Loader />;
}
@@ -0,0 +1,6 @@
import { Loader } from "@/components/retroui/Loader";
export default function LoaderPreview() {
return <Loader variant="outline" />;
}
@@ -0,0 +1,12 @@
import { Loader } from "@/components/retroui/Loader";
export default function LoaderPreview() {
return (
<div className="flex items-end gap-4">
<Loader size="sm" />
<Loader size="md" />
<Loader size="lg" />
</div>
);
}
@@ -0,0 +1,6 @@
import { Loader } from "@/components/retroui/Loader";
export default function LoaderPreview() {
return <Loader variant="secondary" />;
}
@@ -0,0 +1,17 @@
import { Button } from "@/components/retroui/Button";
import { Menu } from "@/components/retroui/Menu";
export default function MenuDefault() {
return (
<Menu>
<Menu.Trigger asChild>
<Button>Menu</Button>
</Menu.Trigger>
<Menu.Content className="min-w-36">
<Menu.Item>Menu Item 1</Menu.Item>
<Menu.Item>Menu Item 2</Menu.Item>
<Menu.Item>Menu Item 3</Menu.Item>
</Menu.Content>
</Menu>
);
}
@@ -0,0 +1,45 @@
"use client";
import { Popover, Label, Button, Input } from "@/components/retroui";
export default function PopoverStyleDefaultShadow() {
return (
<Popover>
<Popover.Trigger asChild>
<Button>Open Popover</Button>
</Popover.Trigger>
<Popover.Content className="w-80 shadow-md">
<div className="grid gap-4">
<div className="space-y-2">
<h4 className="font-medium leading-none">Dimensions</h4>
<p className="text-sm text-muted-foreground">
Set the dimensions for the layer.
</p>
</div>
<div className="grid gap-2">
<div className="grid grid-cols-3 items-center gap-4">
<Label htmlFor="width">Width</Label>
<Input
id="width"
defaultValue="100%"
className="col-span-2 h-8"
/>
</div>
<div className="grid grid-cols-3 items-center gap-4">
<Label htmlFor="height">Height</Label>
<Input
id="height"
defaultValue="25px"
className="col-span-2 h-8"
/>
</div>
</div>
</div>
</Popover.Content>
</Popover>
);
}
@@ -0,0 +1,45 @@
"use client";
import { Popover, Label, Button, Input } from "@/components/retroui";
export default function PopoverStyleDefault() {
return (
<Popover>
<Popover.Trigger asChild>
<Button>Open Popover</Button>
</Popover.Trigger>
<Popover.Content className="w-80 font-sans">
<div className="grid gap-4">
<div className="space-y-2">
<h4 className="font-medium leading-none">Dimensions</h4>
<p className="text-sm text-muted-foreground">
Set the dimensions for the layer.
</p>
</div>
<div className="grid gap-2">
<div className="grid grid-cols-3 items-center gap-4">
<Label htmlFor="width">Width</Label>
<Input
id="width"
defaultValue="100%"
className="col-span-2 h-8"
/>
</div>
<div className="grid grid-cols-3 items-center gap-4">
<Label htmlFor="height">Height</Label>
<Input
id="height"
defaultValue="25px"
className="col-span-2 h-8"
/>
</div>
</div>
</div>
</Popover.Content>
</Popover>
);
}
@@ -0,0 +1,16 @@
"use client";
import * as React from "react";
import { Progress } from "@/components/retroui/Progress";
export default function ProgressDemo() {
const [progress, setProgress] = React.useState(13);
React.useEffect(() => {
const timer = setTimeout(() => setProgress(66), 500);
return () => clearTimeout(timer);
}, []);
return <Progress value={progress} className="w-[60%]" />;
}
@@ -0,0 +1,20 @@
import { RadioGroup } from "@/components/retroui/Radio";
export default function RadioStyleSizes() {
return (
<RadioGroup>
<div className="flex items-center space-x-2">
<RadioGroup.Item value="1" />
<label htmlFor="1"> Option 1</label>
</div>
<div className="flex items-center space-x-2">
<RadioGroup.Item value="2" />
<label htmlFor="2"> Option 2</label>
</div>
<div className="flex items-center space-x-2">
<RadioGroup.Item value="3" />
<label htmlFor="3"> Option 3</label>
</div>
</RadioGroup>
);
}
@@ -0,0 +1,26 @@
import { RadioGroup } from "@/components/retroui/Radio";
export default function RadioStyleSizes() {
return (
<div className="flex gap-4">
<RadioGroup>
<div className="flex items-center space-x-2">
<RadioGroup.Item value="sm" size="sm" />
<label htmlFor="sm" className="text-sm">
Small
</label>
</div>
<div className="flex items-center space-x-2">
<RadioGroup.Item value="md" size="md" />
<label htmlFor="md">Medium</label>
</div>
<div className="flex items-center space-x-2">
<RadioGroup.Item value="lg" size="lg" />
<label htmlFor="lg" className="text-lg">
Large Size
</label>
</div>
</RadioGroup>
</div>
);
}
@@ -0,0 +1,22 @@
import { RadioGroup } from "@/components/retroui/Radio";
export default function RadioStyleVariants() {
return (
<div className="flex gap-4">
<RadioGroup>
<div className="flex items-center space-x-2">
<RadioGroup.Item value="default" variant="default" />
<label htmlFor="default">Default Style</label>
</div>
<div className="flex items-center space-x-2">
<RadioGroup.Item value="outline" variant="outline" />
<label htmlFor="outline">Outline Style</label>
</div>
<div className="flex items-center space-x-2">
<RadioGroup.Item value="solid" variant="solid" />
<label htmlFor="solid">Solid Style</label>
</div>
</RadioGroup>
</div>
);
}
@@ -0,0 +1,92 @@
import { Button, Card } from "@/components/retroui";
import { Slider } from "@/components/retroui/Slider";
import {
ArrowLeft,
Heart,
Pause,
Repeat,
Shuffle,
Sparkle,
StepBack,
StepForward,
} from "lucide-react";
export default function RetroPlayerStyle() {
return (
<Card className="w-full max-w-sm rounded-lg shadow-none">
{/* header */}
<Card.Header className="flex flex-row justify-between border-b border-black/50 dark:border-white/50">
<Button variant="ghost" className="p-0">
<ArrowLeft className="size-5" />
</Button>
<p className="text-sm font-bold">Now playing</p>
<Button variant="ghost" className="p-0">
<Heart className="size-5" />
</Button>
</Card.Header>
{/* card content */}
<Card.Content className="relative px-4 sm:px-12 py-6 overflow-hidden">
{/* thumbnail box */}
<div className="flex items-center gap-4 mb-6">
<img
src="/images/punk.svg"
alt="retro player album"
className="size-12 object-contain rounded-md border"
/>
<div className="flex-1">
<p className="font-semibold">Punk Anthem Music</p>
<p className="text-sm">by Punk</p>
</div>
</div>
<div className="">
{/* timeline box */}
<div>
<Slider value={[50]} />
<div className="flex items-center justify-between mt-1.5 select-none">
<p className="text-xs text-muted-foreground">
01:10
</p>
<p className="text-xs text-muted-foreground">
02:15
</p>
</div>
</div>
{/* controls */}
<div className="flex gap-2 sm:gap-3 items-center justify-between mt-3">
<Button variant="ghost" className="p-0">
<Repeat className="size-4" />
</Button>
<Button variant="ghost" className="p-0">
<StepBack className="size-5" />
</Button>
<Button
variant="outline"
className="rounded-full h-14 w-14"
>
<Pause className="size-5" />
</Button>
<Button variant="ghost" className="p-0">
<StepForward className="size-5" />
</Button>
<Button variant="ghost" className="p-0">
<Shuffle className="size-4" />
</Button>
</div>
</div>
<Sparkle
size={30}
strokeWidth={0.5}
className="absolute sm:block hidden -right-2 top-26 fill-amber-300 rotate-12"
/>
<Sparkle
size={20}
strokeWidth={0.5}
className="absolute sm:block hidden left-1 bottom-20 fill-slate-500"
/>
</Card.Content>
</Card>
);
}
@@ -0,0 +1,20 @@
import { Select } from "@/components/retroui/Select";
import React from "react";
export default function SelectStyleDefault() {
return (
<Select>
<Select.Trigger className="w-60">
<Select.Value placeholder="Pick your Pokemon" />
</Select.Trigger>
<Select.Content>
<Select.Group>
<Select.Item value="pikachu">Pikachu</Select.Item>
<Select.Item value="charizard">Charizard</Select.Item>
<Select.Item value="bulbasaur">Bulbasaur</Select.Item>
<Select.Item value="squirtle">Squirtle</Select.Item>
</Select.Group>
</Select.Content>
</Select>
);
}
@@ -0,0 +1,15 @@
import { Slider } from "@/components/retroui/Slider";
export default function SliderDefault() {
return (
<div className="w-[400px]">
<Slider
defaultValue={[50]}
min={0}
max={100}
step={1}
aria-label="Slider Control"
/>
</div>
);
}
@@ -0,0 +1,12 @@
import { Button } from "@/components/retroui";
import { toast } from "sonner";
export default function SonnerStyleRichColors() {
const onClick = () => {
toast.success("Congrats man (Colored) 🎉", {
richColors: true,
});
};
return <Button onClick={onClick}>Congratulate Me</Button>;
}
@@ -0,0 +1,16 @@
import { Button } from "@/components/retroui";
import { toast } from "sonner";
export default function SonnerStyleDefault() {
const onClick = () => {
toast("Event has been created", {
description: "Sunday, December 03, 2025",
cancel: {
label: "Undo",
onClick: () => {},
},
});
};
return <Button onClick={onClick}>Show Toast</Button>;
}
@@ -0,0 +1,10 @@
import { Button } from "@/components/retroui";
import { toast } from "sonner";
export default function SonnerStyleError() {
const onClick = () => {
toast.error("Oops! you ran into a pot hole");
};
return <Button onClick={onClick}>Show Toast (Error)</Button>;
}
@@ -0,0 +1,10 @@
import { Button } from "@/components/retroui";
import { toast } from "sonner";
export default function SonnerStyleStatus() {
const onClick = () => {
toast.success("Congrats man 🎉 (Plain)");
};
return <Button onClick={onClick}>Congratulate Me</Button>;
}
@@ -0,0 +1,11 @@
import { Switch } from "@/components/retroui/Switch";
import React from "react";
export default function SwitchStyleDefault() {
return (
<div className="flex items-center space-x-2">
<Switch id="notification" />
<label htmlFor="notification">Email Notifications</label>
</div>
);
}
@@ -0,0 +1,10 @@
import { Switch } from "@/components/retroui/Switch";
import React from "react";
export default function SwitchStyleDisabled() {
return (
<div className="flex items-center space-x-2">
<Switch id="notification" disabled />
</div>
);
}
@@ -0,0 +1,21 @@
import { Tabs, TabsPanels, TabsTrigger, TabsContent, TabsTriggerList } from "@/components/retroui/Tab";
export default function TabStyleDefault() {
return (
<Tabs className="w-full">
<TabsTriggerList>
<TabsTrigger>Home</TabsTrigger>
<TabsTrigger>About</TabsTrigger>
<TabsTrigger>Contact</TabsTrigger>
</TabsTriggerList>
<TabsPanels>
<TabsContent>
Welcome to RetroUI, a retro styled UI library built with React,
Tailwind CSS & Headless UI.
</TabsContent>
<TabsContent>This is the about section!</TabsContent>
<TabsContent>And, this is the contact section!</TabsContent>
</TabsPanels>
</Tabs>
);
}
@@ -0,0 +1,89 @@
import { Badge } from "@/components/retroui"
import {
Table,
} from "@/components/retroui/Table"
const invoices = [
{
invoice: "INV001",
customer: "John Doe",
paymentStatus: "Paid",
totalAmount: "$250.00",
paymentMethod: "Credit Card",
},
{
invoice: "INV002",
customer: "Jane Doe",
paymentStatus: "Pending",
totalAmount: "$150.00",
paymentMethod: "PayPal",
},
{
invoice: "INV003",
customer: "Mark Doe",
paymentStatus: "Unpaid",
totalAmount: "$350.00",
paymentMethod: "Bank Transfer",
},
{
invoice: "INV004",
customer: "Robert Doe",
paymentStatus: "Paid",
totalAmount: "$450.00",
paymentMethod: "Credit Card",
},
{
invoice: "INV005",
customer: "Isabella Doe",
paymentStatus: "Paid",
totalAmount: "$550.00",
paymentMethod: "PayPal",
},
{
invoice: "INV006",
customer: "Mrs. Doe",
paymentStatus: "Pending",
totalAmount: "$200.00",
paymentMethod: "Bank Transfer",
},
{
invoice: "INV007",
customer: "Mr. Doe",
paymentStatus: "Unpaid",
totalAmount: "$300.00",
paymentMethod: "Credit Card",
},
]
export default function TableStyleDefault() {
return (
<Table className="max-w-lg mb-6 mx-auto">
<Table.Header>
<Table.Row>
<Table.Head className="w-[100px]">Invoice</Table.Head>
<Table.Head>Customer</Table.Head>
<Table.Head>Status</Table.Head>
<Table.Head>Method</Table.Head>
<Table.Head className="text-right">Amount</Table.Head>
</Table.Row>
</Table.Header>
<Table.Body>
{invoices.map((invoice) => (
<Table.Row key={invoice.invoice}>
<Table.Cell className="font-medium">{invoice.invoice}</Table.Cell>
<Table.Cell>{invoice.customer}</Table.Cell>
<Table.Cell><Badge variant="solid" size="sm">{invoice.paymentStatus}</Badge></Table.Cell>
<Table.Cell>{invoice.paymentMethod}</Table.Cell>
<Table.Cell className="text-right">{invoice.totalAmount}</Table.Cell>
</Table.Row>
))}
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.Cell colSpan={4}>Total</Table.Cell>
<Table.Cell className="text-right">$2,500.00</Table.Cell>
</Table.Row>
</Table.Footer>
</Table>
)
}
@@ -0,0 +1,122 @@
import { Badge, Checkbox } from "@/components/retroui"
import {
Table,
} from "@/components/retroui/Table"
import { useState } from "react"
const employees = [
{
id: "1",
name: "Alice Johnson",
department: "Engineering",
status: "Active",
salary: "85,000",
},
{
id: "2",
name: "Bob Smith",
department: "Product",
status: "Active",
salary: "95,000",
},
{
id: "3",
name: "Carol Williams",
department: "Design",
status: "On Leave",
salary: "70,000",
},
{
id: "4",
name: "David Brown",
department: "Engineering",
status: "Active",
salary: "90,000",
},
{
id: "5",
name: "Eve Davis",
department: "Engineering",
status: "Active",
salary: "75,000",
},
{
id: "6",
name: "Frank Wilson",
department: "Marketing",
status: "Inactive",
salary: "80,000",
},
]
export default function TableWithCheckbox() {
const [selectedEmployees, setSelectedEmployees] = useState<Set<string>>(new Set())
const handleSelectAll = (checked: boolean) => {
if (checked) {
setSelectedEmployees(new Set(employees.map(emp => emp.id)))
} else {
setSelectedEmployees(new Set())
}
}
const handleSelectEmployee = (employeeId: string, checked: boolean) => {
const newSelected = new Set(selectedEmployees)
if (checked) {
newSelected.add(employeeId)
} else {
newSelected.delete(employeeId)
}
setSelectedEmployees(newSelected)
}
const isAllSelected = selectedEmployees.size === employees.length
return (
<Table className="max-w-lg mb-6 mx-auto">
<Table.Header>
<Table.Row>
<Table.Head className="w-[50px]">
<Checkbox
checked={isAllSelected}
onCheckedChange={handleSelectAll}
/>
</Table.Head>
<Table.Head>Name</Table.Head>
<Table.Head>Department</Table.Head>
<Table.Head>Status</Table.Head>
<Table.Head className="text-right">Salary</Table.Head>
</Table.Row>
</Table.Header>
<Table.Body>
{employees.map((employee) => (
<Table.Row key={employee.id}>
<Table.Cell>
<Checkbox
checked={selectedEmployees.has(employee.id)}
onCheckedChange={(checked) => handleSelectEmployee(employee.id, Boolean(checked))}
/>
</Table.Cell>
<Table.Cell className="font-medium">{employee.name}</Table.Cell>
<Table.Cell>{employee.department}</Table.Cell>
<Table.Cell>
<Badge
variant={employee.status === 'Active' ? 'default' : employee.status === 'On Leave' ? 'outline' : 'solid'}
size="sm"
>
{employee.status}
</Badge>
</Table.Cell>
<Table.Cell className="text-right">$ {employee.salary}</Table.Cell>
</Table.Row>
))}
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.Cell colSpan={4}>Selected: {selectedEmployees.size} / {employees.length}</Table.Cell>
<Table.Cell className="text-right font-semibold">$ {employees.reduce((total, employee) => total + Number(employee.salary.replace(',', '')), 0)}</Table.Cell>
</Table.Row>
</Table.Footer>
</Table>
)
}
@@ -0,0 +1,140 @@
import { Badge } from "@/components/retroui";
import { Table } from "@/components/retroui/Table";
const transactions = [
{
id: "TXN001",
date: "2024-01-15",
description: "Payment from Customer A",
amount: "$1,250.00",
category: "Revenue",
},
{
id: "TXN002",
date: "2024-01-15",
description: "Office Supplies Purchase",
amount: "-$85.50",
category: "Expense",
},
{
id: "TXN003",
date: "2024-01-16",
description: "Software License Renewal",
category: "Expense",
amount: "-$299.99",
},
{
id: "TXN004",
date: "2024-01-16",
description: "Payment from Customer B",
category: "Revenue",
amount: "$750.00",
},
{
id: "TXN005",
date: "2024-01-17",
description: "Marketing Campaign",
category: "Expense",
amount: "-$500.00",
},
{
id: "TXN006",
date: "2024-01-17",
description: "Freelancer Payment",
category: "Expense",
amount: "-$400.00",
},
{
id: "TXN007",
date: "2024-01-18",
description: "Payment from Customer C",
category: "Revenue",
amount: "$2,100.00",
},
{
id: "TXN008",
date: "2024-01-18",
description: "Equipment Purchase",
category: "Expense",
amount: "-$1,200.00",
},
{
id: "TXN009",
date: "2024-01-19",
description: "Subscription Fee",
category: "Expense",
amount: "-$49.99",
status: "Pending",
},
{
id: "TXN010",
date: "2024-01-19",
description: "Payment from Customer D",
category: "Revenue",
amount: "$890.00",
},
{
id: "TXN011",
date: "2024-01-20",
description: "Travel Expenses",
category: "Expense",
amount: "-$350.00",
},
{
id: "TXN012",
date: "2024-01-20",
description: "Payment from Customer E",
category: "Revenue",
amount: "$1,500.00",
},
];
export default function TableWithStickyHeader() {
return (
<div className="h-96 border-2">
<Table className="border-0 shadow-none">
<Table.Header className="sticky top-0">
<Table.Row className="bg-secondary hover:bg-secondary">
<Table.Head className="w-[100px] text-secondary-foreground">
ID
</Table.Head>
<Table.Head className="text-secondary-foreground">Date</Table.Head>
<Table.Head className="text-secondary-foreground">
Description
</Table.Head>
<Table.Head className="text-secondary-foreground">
Category
</Table.Head>
<Table.Head className="text-right text-secondary-foreground">
Amount
</Table.Head>
</Table.Row>
</Table.Header>
<Table.Body>
{transactions.map((transaction) => (
<Table.Row key={transaction.id}>
<Table.Cell className="font-medium">{transaction.id}</Table.Cell>
<Table.Cell>{transaction.date}</Table.Cell>
<Table.Cell>{transaction.description}</Table.Cell>
<Table.Cell>
<Badge
variant={
transaction.category === "Revenue" ? "default" : "outline"
}
size="sm"
>
{transaction.category}
</Badge>
</Table.Cell>
<Table.Cell
className={`text-right font-medium ${transaction.amount.startsWith("-") ? "text-destructive" : "text-foreground"}`}
>
{transaction.amount}
</Table.Cell>
</Table.Row>
))}
</Table.Body>
</Table>
</div>
);
}
@@ -0,0 +1,14 @@
import { Text } from "@/components/retroui/Text";
export default function TextHeadings() {
return (
<div className="space-y-4">
<Text as="h1">This is H1</Text>
<Text as="h2">This is H2</Text>
<Text as="h3">This is H3</Text>
<Text as="h4">This is H4</Text>
<Text as="h5">This is H5</Text>
<Text as="h6">This is H6</Text>
</div>
);
}
@@ -0,0 +1,11 @@
import { Textarea } from "@/components/retroui/Textarea";
export default function TextareaStyleDefault() {
return (
<Textarea
rows={4}
placeholder="type something..."
className="px-4 py-2 w-full border-2 shadow-md transition focus:outline-hidden focus:shadow-xs"
/>
);
}
@@ -0,0 +1,6 @@
import { TableOfContents } from "@/components/retroui/TableOfContents";
export default function TocStyleDefault() {
return <TableOfContents />
}
@@ -0,0 +1,9 @@
import { TableOfContents } from "@/components/retroui/TableOfContents";
import { Text } from "@/components/retroui/Text";
export default function TocStyleDepth() {
return <TableOfContents depth={3} className="w-80 h-96">
<Text className="mb-3 border-b pb-2">On this page</Text>
</TableOfContents>
}
@@ -0,0 +1,22 @@
import { TableOfContents } from "@/components/retroui/TableOfContents";
import { Text } from "@/components/retroui/Text";
export default function TocStyleManual() {
const manualData = [
{ id: 'introduction', title: 'Introduction', depth: 1 },
{ id: 'getting-started', title: 'Getting Started', depth: 2 },
{ id: 'installation', title: 'Installation', depth: 3 },
{ id: 'configuration', title: 'Configuration', depth: 3 },
{ id: 'advanced-usage', title: 'Advanced Usage', depth: 1 },
{ id: 'api-reference', title: 'API Reference', depth: 2 },
{ id: 'examples', title: 'Examples', depth: 2 },
{ id: 'troubleshooting', title: 'Troubleshooting', depth: 1 },
];
return <TableOfContents
data={manualData}
className="w-80 h-96"
>
<Text className="mb-3 border-b pb-2">Manual TOC</Text>
</TableOfContents>
}
@@ -0,0 +1,22 @@
"use client";
import { ToggleGroup, ToggleGroupItem } from "@/components/retroui";
import { Bold, Italic, Underline } from "lucide-react";
export default function ToggleGroupStyleDefault() {
return (
<ToggleGroup type="multiple" variant="default">
<ToggleGroupItem value="bold">
<Bold className="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="italic">
<Italic className="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="underline">
<Underline className="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
);
}

Some files were not shown because too many files have changed in this diff Show More