4512 lines
167 KiB
TypeScript
4512 lines
167 KiB
TypeScript
"use client"
|
||
|
||
import { useState } from "react"
|
||
import Link from "next/link"
|
||
import Image from "next/image"
|
||
import { Button } from "@/components/ui/button"
|
||
import { Badge } from "@/components/ui/badge"
|
||
import {
|
||
Card,
|
||
CardContent,
|
||
CardDescription,
|
||
CardFooter,
|
||
CardHeader,
|
||
CardTitle,
|
||
} from "@/components/ui/card"
|
||
import { Input } from "@/components/ui/input"
|
||
import { Separator } from "@/components/ui/separator"
|
||
import {
|
||
Select,
|
||
SelectContent,
|
||
SelectItem,
|
||
SelectTrigger,
|
||
SelectValue,
|
||
} from "@/components/ui/select"
|
||
import { Checkbox } from "@/components/ui/checkbox"
|
||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
|
||
import { Label } from "@/components/ui/label"
|
||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||
import {
|
||
Accordion,
|
||
AccordionContent,
|
||
AccordionItem,
|
||
AccordionTrigger,
|
||
} from "@/components/ui/accordion"
|
||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
|
||
import {
|
||
AlertDialog,
|
||
AlertDialogAction,
|
||
AlertDialogCancel,
|
||
AlertDialogContent,
|
||
AlertDialogDescription,
|
||
AlertDialogFooter,
|
||
AlertDialogHeader,
|
||
AlertDialogTitle,
|
||
AlertDialogTrigger,
|
||
} from "@/components/ui/alert-dialog"
|
||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||
import {
|
||
Dialog,
|
||
DialogContent,
|
||
DialogDescription,
|
||
DialogHeader,
|
||
DialogTitle,
|
||
DialogTrigger,
|
||
} from "@/components/ui/dialog"
|
||
import {
|
||
DropdownMenu,
|
||
DropdownMenuContent,
|
||
DropdownMenuItem,
|
||
DropdownMenuTrigger,
|
||
} from "@/components/ui/dropdown-menu"
|
||
import {
|
||
Sheet,
|
||
SheetContent,
|
||
SheetDescription,
|
||
SheetHeader,
|
||
SheetTitle,
|
||
SheetTrigger,
|
||
} from "@/components/ui/sheet"
|
||
import { Textarea } from "@/components/ui/textarea"
|
||
import { Skeleton } from "@/components/ui/skeleton"
|
||
import { Progress } from "@/components/ui/progress"
|
||
import { Slider } from "@/components/ui/slider"
|
||
import { Switch } from "@/components/ui/switch"
|
||
import {
|
||
Tooltip,
|
||
TooltipContent,
|
||
TooltipProvider,
|
||
TooltipTrigger,
|
||
} from "@/components/ui/tooltip"
|
||
import {
|
||
Popover,
|
||
PopoverContent,
|
||
PopoverTrigger,
|
||
} from "@/components/ui/popover"
|
||
import {
|
||
Breadcrumb,
|
||
BreadcrumbItem,
|
||
BreadcrumbLink,
|
||
BreadcrumbList,
|
||
BreadcrumbPage,
|
||
BreadcrumbSeparator,
|
||
} from "@/components/ui/breadcrumb"
|
||
import {
|
||
Table,
|
||
TableBody,
|
||
TableCaption,
|
||
TableCell,
|
||
TableFooter,
|
||
TableHead,
|
||
TableHeader,
|
||
TableRow,
|
||
} from "@/components/ui/table"
|
||
import { useToast } from "@/components/ui/use-toast"
|
||
import { Toaster } from "@/components/ui/toaster"
|
||
import {
|
||
Carousel,
|
||
CarouselContent,
|
||
CarouselItem,
|
||
CarouselNext,
|
||
CarouselPrevious,
|
||
} from "@/components/ui/carousel"
|
||
import { AspectRatio } from "@/components/ui/aspect-ratio"
|
||
import { ScrollArea } from "@/components/ui/scroll-area"
|
||
import {
|
||
HoverCard,
|
||
HoverCardContent,
|
||
HoverCardTrigger,
|
||
} from "@/components/ui/hover-card"
|
||
import {
|
||
Command,
|
||
CommandDialog,
|
||
CommandEmpty,
|
||
CommandGroup,
|
||
CommandInput,
|
||
CommandItem,
|
||
CommandList,
|
||
CommandSeparator,
|
||
CommandShortcut,
|
||
} from "@/components/ui/command"
|
||
import {
|
||
ContextMenu,
|
||
ContextMenuContent,
|
||
ContextMenuItem,
|
||
ContextMenuTrigger,
|
||
} from "@/components/ui/context-menu"
|
||
import {
|
||
Menubar,
|
||
MenubarContent,
|
||
MenubarItem,
|
||
MenubarMenu,
|
||
MenubarTrigger,
|
||
} from "@/components/ui/menubar"
|
||
import {
|
||
NavigationMenu,
|
||
NavigationMenuContent,
|
||
NavigationMenuItem,
|
||
NavigationMenuLink,
|
||
NavigationMenuList,
|
||
NavigationMenuTrigger,
|
||
} from "@/components/ui/navigation-menu"
|
||
import {
|
||
Pagination,
|
||
PaginationContent,
|
||
PaginationItem,
|
||
PaginationLink,
|
||
PaginationNext,
|
||
PaginationPrevious,
|
||
} from "@/components/ui/pagination"
|
||
import { Toggle } from "@/components/ui/toggle"
|
||
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
|
||
import {
|
||
Collapsible,
|
||
CollapsibleContent,
|
||
CollapsibleTrigger,
|
||
} from "@/components/ui/collapsible"
|
||
import {
|
||
Drawer,
|
||
DrawerClose,
|
||
DrawerContent,
|
||
DrawerDescription,
|
||
DrawerFooter,
|
||
DrawerHeader,
|
||
DrawerTitle,
|
||
DrawerTrigger,
|
||
} from "@/components/ui/drawer"
|
||
import {
|
||
ResizablePanelGroup,
|
||
ResizablePanel,
|
||
ResizableHandle,
|
||
} from "@/components/ui/resizable"
|
||
import {
|
||
Empty,
|
||
EmptyContent,
|
||
EmptyDescription,
|
||
EmptyHeader,
|
||
EmptyMedia,
|
||
EmptyTitle,
|
||
} from "@/components/ui/empty"
|
||
import { Kbd, KbdGroup } from "@/components/ui/kbd"
|
||
import { Spinner } from "@/components/ui/spinner"
|
||
import {
|
||
InputOTP,
|
||
InputOTPGroup,
|
||
InputOTPSlot,
|
||
} from "@/components/ui/input-otp"
|
||
import { Calendar } from "@/components/ui/calendar"
|
||
import {
|
||
Form,
|
||
FormControl,
|
||
FormDescription,
|
||
FormField,
|
||
FormItem,
|
||
FormLabel,
|
||
FormMessage,
|
||
} from "@/components/ui/form"
|
||
import {
|
||
Field,
|
||
FieldContent,
|
||
FieldDescription,
|
||
FieldError,
|
||
FieldGroup,
|
||
FieldLabel,
|
||
FieldLegend,
|
||
FieldSet,
|
||
FieldTitle,
|
||
} from "@/components/ui/field"
|
||
import {
|
||
Item,
|
||
ItemActions,
|
||
ItemContent,
|
||
ItemDescription,
|
||
ItemFooter,
|
||
ItemGroup,
|
||
ItemHeader,
|
||
ItemMedia,
|
||
ItemSeparator,
|
||
ItemTitle,
|
||
} from "@/components/ui/item"
|
||
import {
|
||
InputGroup,
|
||
InputGroupAddon,
|
||
InputGroupButton,
|
||
InputGroupInput,
|
||
InputGroupText,
|
||
InputGroupTextarea,
|
||
} from "@/components/ui/input-group"
|
||
import {
|
||
ButtonGroup,
|
||
ButtonGroupSeparator,
|
||
ButtonGroupText,
|
||
} from "@/components/ui/button-group"
|
||
// Sidebar components - complex component, shown in code example only
|
||
// Note: Sidebar requires SidebarProvider context, so it's shown in code example only
|
||
import {
|
||
ChartContainer,
|
||
ChartTooltip,
|
||
ChartTooltipContent,
|
||
} from "@/components/ui/chart"
|
||
import { Toaster as SonnerToaster } from "@/components/ui/sonner"
|
||
import {
|
||
LineChart,
|
||
Line,
|
||
BarChart,
|
||
Bar,
|
||
AreaChart,
|
||
Area,
|
||
PieChart,
|
||
Pie,
|
||
Cell,
|
||
RadarChart,
|
||
Radar,
|
||
PolarGrid,
|
||
PolarAngleAxis,
|
||
PolarRadiusAxis,
|
||
ComposedChart,
|
||
XAxis,
|
||
YAxis,
|
||
CartesianGrid,
|
||
} from "recharts"
|
||
import { Header } from "@/components/header"
|
||
import { Footer } from "@/components/footer"
|
||
import { GetFreeMachineModal } from "@/components/get-free-machine-modal"
|
||
import { Cart } from "@/components/cart"
|
||
import { CartButton } from "@/components/cart-button"
|
||
import { MobileCartButton } from "@/components/mobile-cart-button"
|
||
import { ProductGrid } from "@/components/product-grid"
|
||
import { VendingMachinesShowcase } from "@/components/vending-machines-showcase"
|
||
import { CreditCardReaderSection } from "@/components/credit-card-reader-section"
|
||
import { FeatureCard } from "@/components/feature-card"
|
||
import { ManualViewer } from "@/components/manual-viewer"
|
||
import { PartsPanel } from "@/components/parts-panel"
|
||
import { AboutPage } from "@/components/about-page"
|
||
import { ContactPage } from "@/components/contact-page"
|
||
import { WhoWeServePage } from "@/components/who-we-serve-page"
|
||
import { RepairsPage } from "@/components/repairs-page"
|
||
import { AuthorBio } from "@/components/author-bio"
|
||
import { PageWrapper, PageHeader } from "@/components/page-wrapper"
|
||
import { MovingServiceImage } from "@/components/moving-service-image"
|
||
import {
|
||
CheckCircle2,
|
||
Sparkles,
|
||
Wrench,
|
||
MonitorSmartphone,
|
||
CreditCard,
|
||
Package,
|
||
MapPin,
|
||
Phone,
|
||
Star,
|
||
Menu,
|
||
X,
|
||
Copy,
|
||
Check,
|
||
AlertCircle,
|
||
Info,
|
||
User,
|
||
Settings,
|
||
Search,
|
||
MoreHorizontal,
|
||
ChevronRight,
|
||
Loader2,
|
||
ShoppingCart,
|
||
} from "lucide-react"
|
||
import { HeroSection } from "@/components/hero-section"
|
||
import { StatsSection } from "@/components/stats-section"
|
||
import { FeaturesSection } from "@/components/features-section"
|
||
import { ProductShowcaseSection } from "@/components/product-showcase-section"
|
||
import { HowItWorksSection } from "@/components/how-it-works-section"
|
||
import { ServicesSection } from "@/components/services-section"
|
||
import { ServiceAreasSection } from "@/components/service-areas-section"
|
||
import { ReviewsSection } from "@/components/reviews-section"
|
||
import { RequestMachineSection } from "@/components/request-machine-section"
|
||
import { ContactSection } from "@/components/contact-section"
|
||
|
||
// Color palette data
|
||
const colorPalette = {
|
||
primary: [
|
||
{
|
||
name: "Primary",
|
||
variable: "--primary",
|
||
value: "#29A047",
|
||
description: "Primary brand color (green from logo)",
|
||
},
|
||
{
|
||
name: "Secondary",
|
||
variable: "--secondary",
|
||
value: "#54595F",
|
||
description: "Secondary color (gray)",
|
||
},
|
||
{
|
||
name: "Text/Foreground",
|
||
variable: "--foreground",
|
||
value: "oklch(0.178 0.014 275.627)",
|
||
description: "Main text color (dark black)",
|
||
},
|
||
{
|
||
name: "Background",
|
||
variable: "--background",
|
||
value: "#fff8eb",
|
||
description: "Warm cream background",
|
||
},
|
||
],
|
||
links: [
|
||
{
|
||
name: "Link Default",
|
||
variable: "--link-color",
|
||
value: "var(--foreground)",
|
||
description: "Default link color",
|
||
},
|
||
{
|
||
name: "Link Hover (Accent)",
|
||
variable: "--link-hover-color",
|
||
value: "#C4142C",
|
||
description: "Red accent/hover color",
|
||
},
|
||
{
|
||
name: "Link Hover Dark",
|
||
variable: "--link-hover-color-dark",
|
||
value: "#a01020",
|
||
description: "Darker red for gradients",
|
||
},
|
||
{
|
||
name: "Link Hover BG",
|
||
variable: "--link-hover-bg",
|
||
value: "rgba(196, 20, 44, 0.1)",
|
||
description: "Link hover background",
|
||
},
|
||
],
|
||
custom: [
|
||
{
|
||
name: "Yellow",
|
||
variable: "--yellow",
|
||
value: "#FCBA09",
|
||
description: "Custom yellow color",
|
||
},
|
||
{
|
||
name: "Orange",
|
||
variable: "--orange",
|
||
value: "#F79611",
|
||
description: "Custom orange color",
|
||
},
|
||
{
|
||
name: "Mountain Bubbles",
|
||
variable: "--mountain-bubbles",
|
||
value: "#FCBA0924",
|
||
description: "Yellow with transparency",
|
||
},
|
||
],
|
||
semantic: [
|
||
{
|
||
name: "Muted",
|
||
variable: "--muted",
|
||
value: "oklch(0.961 0.004 106.423)",
|
||
description: "Muted background",
|
||
},
|
||
{
|
||
name: "Muted Foreground",
|
||
variable: "--muted-foreground",
|
||
value: "oklch(0.556 0.014 275.627)",
|
||
description: "Muted text",
|
||
},
|
||
{
|
||
name: "Destructive",
|
||
variable: "--destructive",
|
||
value: "oklch(0.577 0.245 27.325)",
|
||
description: "Error/destructive actions",
|
||
},
|
||
{
|
||
name: "Border",
|
||
variable: "--border",
|
||
value: "oklch(0.922 0.004 106.423)",
|
||
description: "Border color",
|
||
},
|
||
],
|
||
}
|
||
|
||
export default function StyleGuidePage() {
|
||
const [copiedCode, setCopiedCode] = useState<string | null>(null)
|
||
const [isNavOpen, setIsNavOpen] = useState(false)
|
||
|
||
const copyToClipboard = (text: string, id: string) => {
|
||
navigator.clipboard.writeText(text)
|
||
setCopiedCode(id)
|
||
setTimeout(() => setCopiedCode(null), 2000)
|
||
}
|
||
|
||
const CodeBlock = ({ code, id }: { code: string; id: string }) => (
|
||
<div className="relative group">
|
||
<pre className="bg-muted p-4 rounded-lg overflow-x-auto text-sm">
|
||
<code>{code}</code>
|
||
</pre>
|
||
<button
|
||
onClick={() => copyToClipboard(code, id)}
|
||
className="absolute top-2 right-2 p-2 bg-background border border-border rounded hover:bg-accent transition-colors"
|
||
aria-label="Copy code"
|
||
>
|
||
{copiedCode === id ? (
|
||
<Check className="h-4 w-4 text-secondary" />
|
||
) : (
|
||
<Copy className="h-4 w-4" />
|
||
)}
|
||
</button>
|
||
</div>
|
||
)
|
||
|
||
const Section = ({
|
||
id,
|
||
title,
|
||
children,
|
||
}: {
|
||
id: string
|
||
title: string
|
||
children: React.ReactNode
|
||
}) => (
|
||
<section id={id} className="scroll-mt-24 py-12 md:py-16">
|
||
<h2 className="text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl mb-8 text-balance border-b border-border pb-4">
|
||
{title}
|
||
</h2>
|
||
{children}
|
||
</section>
|
||
)
|
||
|
||
const navItems = [
|
||
{ id: "colors", label: "Color Palette" },
|
||
{ id: "typography", label: "Typography" },
|
||
{ id: "buttons", label: "Buttons" },
|
||
{ id: "cards", label: "Cards" },
|
||
{ id: "badges", label: "Badges" },
|
||
{ id: "links", label: "Links" },
|
||
{ id: "inputs", label: "Form Inputs" },
|
||
{ id: "feedback", label: "Feedback Components" },
|
||
{ id: "overlays", label: "Overlay Components" },
|
||
{ id: "navigation", label: "Navigation Components" },
|
||
{ id: "data-display", label: "Data Display" },
|
||
{ id: "charts", label: "Charts & Graphs" },
|
||
{ id: "interactive", label: "Interactive Components" },
|
||
{ id: "layout", label: "Layout Components" },
|
||
{ id: "advanced", label: "Advanced Components" },
|
||
{ id: "spacing", label: "Spacing & Layout" },
|
||
{ id: "images", label: "Image Patterns" },
|
||
{ id: "sections", label: "Home Page Sections" },
|
||
{ id: "custom", label: "Custom Components" },
|
||
]
|
||
|
||
// Chart data and configurations
|
||
const lineChartData = [
|
||
{ month: "January", desktop: 186, mobile: 80 },
|
||
{ month: "February", desktop: 305, mobile: 200 },
|
||
{ month: "March", desktop: 237, mobile: 120 },
|
||
{ month: "April", desktop: 273, mobile: 190 },
|
||
{ month: "May", desktop: 209, mobile: 130 },
|
||
{ month: "June", desktop: 214, mobile: 140 },
|
||
]
|
||
|
||
const lineChartConfig = {
|
||
desktop: {
|
||
label: "Desktop",
|
||
color: "#F79611", // Brand orange
|
||
},
|
||
mobile: {
|
||
label: "Mobile",
|
||
color: "#54595F", // Secondary gray
|
||
},
|
||
}
|
||
|
||
const barChartData = [
|
||
{ month: "January", desktop: 186, mobile: 80 },
|
||
{ month: "February", desktop: 305, mobile: 200 },
|
||
{ month: "March", desktop: 237, mobile: 120 },
|
||
{ month: "April", desktop: 273, mobile: 190 },
|
||
{ month: "May", desktop: 209, mobile: 130 },
|
||
{ month: "June", desktop: 214, mobile: 140 },
|
||
]
|
||
|
||
const barChartConfig = {
|
||
desktop: {
|
||
label: "Desktop",
|
||
color: "#F79611", // Brand orange
|
||
},
|
||
mobile: {
|
||
label: "Mobile",
|
||
color: "#54595F", // Secondary gray
|
||
},
|
||
}
|
||
|
||
const areaChartData = [
|
||
{ month: "January", desktop: 186, mobile: 80 },
|
||
{ month: "February", desktop: 305, mobile: 200 },
|
||
{ month: "March", desktop: 237, mobile: 120 },
|
||
{ month: "April", desktop: 273, mobile: 190 },
|
||
{ month: "May", desktop: 209, mobile: 130 },
|
||
{ month: "June", desktop: 214, mobile: 140 },
|
||
]
|
||
|
||
const areaChartConfig = {
|
||
desktop: {
|
||
label: "Desktop",
|
||
color: "#F79611", // Brand orange
|
||
},
|
||
mobile: {
|
||
label: "Mobile",
|
||
color: "#54595F", // Secondary gray
|
||
},
|
||
}
|
||
|
||
const pieChartData = [
|
||
{ name: "Desktop", value: 186, fill: "#F79611" }, // Brand orange
|
||
{ name: "Mobile", value: 80, fill: "#FCBA09" }, // Custom yellow
|
||
{ name: "Tablet", value: 50, fill: "#54595F" }, // Secondary gray
|
||
{ name: "Other", value: 30, fill: "#29A047" }, // Primary green
|
||
]
|
||
|
||
const pieChartConfig = {
|
||
value: {
|
||
label: "Value",
|
||
},
|
||
}
|
||
|
||
const radarChartData = [
|
||
{ subject: "Math", A: 120, B: 110, fullMark: 150 },
|
||
{ subject: "Chinese", A: 98, B: 130, fullMark: 150 },
|
||
{ subject: "English", A: 86, B: 130, fullMark: 150 },
|
||
{ subject: "Geography", A: 99, B: 100, fullMark: 150 },
|
||
{ subject: "Physics", A: 85, B: 90, fullMark: 150 },
|
||
{ subject: "History", A: 65, B: 85, fullMark: 150 },
|
||
]
|
||
|
||
const radarChartConfig = {
|
||
A: {
|
||
label: "Student A",
|
||
color: "#F79611", // Brand orange
|
||
},
|
||
B: {
|
||
label: "Student B",
|
||
color: "#54595F", // Secondary gray
|
||
},
|
||
}
|
||
|
||
const { toast } = useToast()
|
||
|
||
return (
|
||
<>
|
||
{/* Sticky Navigation */}
|
||
<nav className="sticky top-20 z-30 bg-background/95 backdrop-blur border-b border-border shadow-sm">
|
||
<div className="container mx-auto px-4">
|
||
<div className="flex items-center justify-between py-4">
|
||
<div className="text-xl font-bold">
|
||
Rocky Mountain Vending Style Guide
|
||
</div>
|
||
<div className="hidden md:flex gap-4 overflow-x-auto">
|
||
{navItems.map((item) => (
|
||
<a
|
||
key={item.id}
|
||
href={`#${item.id}`}
|
||
className="text-sm font-medium whitespace-nowrap hover:text-secondary transition-colors"
|
||
>
|
||
{item.label}
|
||
</a>
|
||
))}
|
||
</div>
|
||
<button
|
||
onClick={() => setIsNavOpen(!isNavOpen)}
|
||
className="md:hidden p-2"
|
||
aria-label="Toggle navigation"
|
||
>
|
||
{isNavOpen ? (
|
||
<X className="h-5 w-5" />
|
||
) : (
|
||
<Menu className="h-5 w-5" />
|
||
)}
|
||
</button>
|
||
</div>
|
||
{isNavOpen && (
|
||
<div className="md:hidden pb-4 space-y-2">
|
||
{navItems.map((item) => (
|
||
<a
|
||
key={item.id}
|
||
href={`#${item.id}`}
|
||
onClick={() => setIsNavOpen(false)}
|
||
className="block text-sm font-medium py-2 hover:text-secondary transition-colors"
|
||
>
|
||
{item.label}
|
||
</a>
|
||
))}
|
||
</div>
|
||
)}
|
||
</div>
|
||
</nav>
|
||
|
||
<div className="container mx-auto px-4 py-8 md:py-12 max-w-7xl">
|
||
{/* Introduction */}
|
||
<div className="mb-16">
|
||
<h1 className="text-4xl md:text-5xl font-bold mb-4">
|
||
Rocky Mountain Vending Style Guide
|
||
</h1>
|
||
<p className="text-lg text-muted-foreground text-pretty leading-relaxed max-w-3xl">
|
||
This style guide showcases all components, styles, and design
|
||
patterns used throughout the Rocky Mountain Vending website. Use
|
||
this as a reference when building new pages or components.
|
||
</p>
|
||
</div>
|
||
|
||
{/* Color Palette */}
|
||
<Section id="colors" title="Color Palette">
|
||
<div className="space-y-12">
|
||
<div>
|
||
<h3 className="text-2xl font-semibold mb-3 text-foreground">
|
||
Primary Colors
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-6 leading-relaxed">
|
||
Core brand colors used throughout the application for primary
|
||
actions, backgrounds, and text.
|
||
</p>
|
||
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
|
||
{colorPalette.primary.map((color) => {
|
||
// Handle CSS variables - use the variable directly for display
|
||
const colorValue = color.value.startsWith("var(")
|
||
? `var(${color.variable})`
|
||
: color.value
|
||
|
||
return (
|
||
<Card
|
||
key={color.variable}
|
||
className="border-border/50 hover:border-border transition-colors shadow-sm"
|
||
>
|
||
<CardContent className="p-6">
|
||
<div
|
||
className="w-full h-32 rounded-lg mb-4 border-2 border-border/50 shadow-inner"
|
||
style={{
|
||
backgroundColor: colorValue,
|
||
minHeight: "8rem",
|
||
}}
|
||
/>
|
||
<div className="space-y-2">
|
||
<div className="text-base font-semibold text-foreground">
|
||
{color.name}
|
||
</div>
|
||
<div className="text-xs text-muted-foreground font-mono bg-muted px-2 py-1 rounded">
|
||
{color.variable}
|
||
</div>
|
||
<div className="text-xs font-mono text-foreground bg-muted px-2 py-1 rounded break-all">
|
||
{color.value}
|
||
</div>
|
||
<div className="text-xs text-muted-foreground leading-relaxed pt-1">
|
||
{color.description}
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
)
|
||
})}
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-2xl font-semibold mb-3 text-foreground">
|
||
Link & Accent Colors
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-6 leading-relaxed">
|
||
Colors used for links, hover states, and accent elements. Links
|
||
use red hover color for brand consistency.
|
||
</p>
|
||
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
|
||
{colorPalette.links.map((color) => {
|
||
// Handle CSS variables and rgba values
|
||
const colorValue = color.value.startsWith("var(")
|
||
? `var(${color.variable})`
|
||
: color.value
|
||
|
||
return (
|
||
<Card
|
||
key={color.variable}
|
||
className="border-border/50 hover:border-border transition-colors shadow-sm"
|
||
>
|
||
<CardContent className="p-6">
|
||
<div
|
||
className="w-full h-32 rounded-lg mb-4 border-2 border-border/50 shadow-inner"
|
||
style={{
|
||
backgroundColor: colorValue,
|
||
minHeight: "8rem",
|
||
}}
|
||
/>
|
||
<div className="space-y-2">
|
||
<div className="text-base font-semibold text-foreground">
|
||
{color.name}
|
||
</div>
|
||
<div className="text-xs text-muted-foreground font-mono bg-muted px-2 py-1 rounded">
|
||
{color.variable}
|
||
</div>
|
||
<div className="text-xs font-mono text-foreground bg-muted px-2 py-1 rounded break-all">
|
||
{color.value}
|
||
</div>
|
||
<div className="text-xs text-muted-foreground leading-relaxed pt-1">
|
||
{color.description}
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
)
|
||
})}
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-2xl font-semibold mb-3 text-foreground">
|
||
Custom Colors
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-6 leading-relaxed">
|
||
Custom brand colors including yellow and orange accents used for
|
||
special highlights and decorative elements.
|
||
</p>
|
||
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
|
||
{colorPalette.custom.map((color) => (
|
||
<Card
|
||
key={color.variable}
|
||
className="border-border/50 hover:border-border transition-colors shadow-sm"
|
||
>
|
||
<CardContent className="p-6">
|
||
<div
|
||
className="w-full h-32 rounded-lg mb-4 border-2 border-border/50 shadow-inner"
|
||
style={{
|
||
backgroundColor: color.value,
|
||
minHeight: "8rem",
|
||
}}
|
||
/>
|
||
<div className="space-y-2">
|
||
<div className="text-base font-semibold text-foreground">
|
||
{color.name}
|
||
</div>
|
||
<div className="text-xs text-muted-foreground font-mono bg-muted px-2 py-1 rounded">
|
||
{color.variable}
|
||
</div>
|
||
<div className="text-xs font-mono text-foreground bg-muted px-2 py-1 rounded break-all">
|
||
{color.value}
|
||
</div>
|
||
<div className="text-xs text-muted-foreground leading-relaxed pt-1">
|
||
{color.description}
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-2xl font-semibold mb-3 text-foreground">
|
||
Semantic Colors
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-6 leading-relaxed">
|
||
Semantic color tokens for muted backgrounds, borders, and
|
||
destructive actions. These provide consistent meaning across the
|
||
UI.
|
||
</p>
|
||
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
|
||
{colorPalette.semantic.map((color) => {
|
||
const getColorValue = (val: string) => {
|
||
if (val.startsWith("oklch(")) return val
|
||
return val
|
||
}
|
||
|
||
return (
|
||
<Card
|
||
key={color.variable}
|
||
className="border-border/50 hover:border-border transition-colors shadow-sm"
|
||
>
|
||
<CardContent className="p-6">
|
||
<div
|
||
className="w-full h-32 rounded-lg mb-4 border-2 border-border/50 shadow-inner"
|
||
style={{
|
||
backgroundColor: getColorValue(color.value),
|
||
minHeight: "8rem",
|
||
}}
|
||
/>
|
||
<div className="space-y-2">
|
||
<div className="text-base font-semibold text-foreground">
|
||
{color.name}
|
||
</div>
|
||
<div className="text-xs text-muted-foreground font-mono bg-muted px-2 py-1 rounded">
|
||
{color.variable}
|
||
</div>
|
||
<div className="text-xs font-mono text-foreground bg-muted px-2 py-1 rounded break-all">
|
||
{color.value}
|
||
</div>
|
||
<div className="text-xs text-muted-foreground leading-relaxed pt-1">
|
||
{color.description}
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
)
|
||
})}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Typography */}
|
||
<Section id="typography" title="Typography">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">
|
||
Page Headers with Gradient Divider
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Header pattern with centered title and gradient divider line,
|
||
commonly used on service pages.
|
||
</p>
|
||
<div className="mb-6">
|
||
<header className="text-center mb-8">
|
||
<h1 className="text-4xl md:text-5xl font-bold tracking-tight text-balance mb-4">
|
||
Page Title
|
||
</h1>
|
||
<div className="w-24 h-1 bg-gradient-to-r from-[var(--link-hover-color)] to-[var(--link-hover-color-dark)] mx-auto rounded-full" />
|
||
</header>
|
||
</div>
|
||
<CodeBlock
|
||
id="header-gradient-divider-code"
|
||
code={`<header className="text-center mb-12 md:mb-16">
|
||
<h1 className="text-4xl md:text-5xl font-bold tracking-tight text-balance mb-4">
|
||
Page Title
|
||
</h1>
|
||
<div className="w-24 h-1 bg-gradient-to-r from-[var(--link-hover-color)] to-[var(--link-hover-color-dark)] mx-auto rounded-full" />
|
||
</header>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Font Families</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Typography system using Inter for body text and UI elements, and
|
||
Geist Mono for code and technical content.
|
||
</p>
|
||
<div className="grid gap-4 md:grid-cols-2">
|
||
<Card className="border-border/50">
|
||
<CardContent className="p-6">
|
||
<div
|
||
className="text-2xl font-sans mb-2"
|
||
style={{ fontFamily: "var(--font-inter)" }}
|
||
>
|
||
Inter (Sans-serif)
|
||
</div>
|
||
<div className="text-sm text-muted-foreground font-mono">
|
||
--font-inter
|
||
</div>
|
||
<p className="text-sm text-muted-foreground mt-2">
|
||
Used for body text and UI elements
|
||
</p>
|
||
</CardContent>
|
||
</Card>
|
||
<Card className="border-border/50">
|
||
<CardContent className="p-6">
|
||
<div
|
||
className="text-2xl font-mono mb-2"
|
||
style={{ fontFamily: "var(--font-geist-mono)" }}
|
||
>
|
||
Geist Mono (Monospace)
|
||
</div>
|
||
<div className="text-sm text-muted-foreground font-mono">
|
||
--font-geist-mono
|
||
</div>
|
||
<p className="text-sm text-muted-foreground mt-2">
|
||
Used for code and technical content
|
||
</p>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Headings</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Heading hierarchy with responsive sizing. H1 is used for page
|
||
titles, H2 for section headers, and H3-H4 for subsections.
|
||
</p>
|
||
<div className="space-y-6">
|
||
<div>
|
||
<h1 className="text-4xl md:text-5xl font-bold mb-2">
|
||
Heading 1 (H1)
|
||
</h1>
|
||
<CodeBlock
|
||
id="h1-code"
|
||
code={`<h1 className="text-4xl md:text-5xl font-bold mb-4">Heading 1</h1>`}
|
||
/>
|
||
<p className="text-sm text-muted-foreground mt-2">
|
||
Used for page titles (only one per page)
|
||
</p>
|
||
</div>
|
||
<div>
|
||
<h2 className="text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl mb-2 text-balance">
|
||
Heading 2 (H2) - Section Header
|
||
</h2>
|
||
<CodeBlock
|
||
id="h2-code"
|
||
code={`<h2 className="text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl mb-4 text-balance">Section Header</h2>`}
|
||
/>
|
||
<p className="text-sm text-muted-foreground mt-2">
|
||
Used for section headers (centered)
|
||
</p>
|
||
</div>
|
||
<div>
|
||
<h2 className="text-2xl md:text-3xl font-semibold mb-2">
|
||
Heading 2 (H2) - Page Header
|
||
</h2>
|
||
<CodeBlock
|
||
id="h2-page-code"
|
||
code={`<h2 className="text-2xl md:text-3xl font-semibold mb-6">Page Header</h2>`}
|
||
/>
|
||
<p className="text-sm text-muted-foreground mt-2">
|
||
Used for page headers (left-aligned)
|
||
</p>
|
||
</div>
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-2">Heading 3 (H3)</h3>
|
||
<CodeBlock
|
||
id="h3-code"
|
||
code={`<h3 className="text-xl font-semibold mb-2">Heading 3</h3>`}
|
||
/>
|
||
</div>
|
||
<div>
|
||
<h4 className="text-lg font-semibold mb-2">Heading 4 (H4)</h4>
|
||
<CodeBlock
|
||
id="h4-code"
|
||
code={`<h4 className="text-lg font-semibold mb-2">Heading 4</h4>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Paragraph Styles</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Standard paragraph text styles with consistent sizing, line
|
||
height, and color for optimal readability.
|
||
</p>
|
||
<div className="space-y-4">
|
||
<div>
|
||
<p className="text-lg text-muted-foreground text-pretty leading-relaxed mb-2">
|
||
Standard paragraph text with text-lg, text-muted-foreground,
|
||
text-pretty, and leading-relaxed classes.
|
||
</p>
|
||
<CodeBlock
|
||
id="p-standard-code"
|
||
code={`<p className="text-lg text-muted-foreground text-pretty leading-relaxed">Standard paragraph</p>`}
|
||
/>
|
||
</div>
|
||
<div>
|
||
<p className="text-sm text-muted-foreground mb-2">
|
||
Small text with text-sm and text-muted-foreground classes.
|
||
</p>
|
||
<CodeBlock
|
||
id="p-small-code"
|
||
code={`<p className="text-sm text-muted-foreground">Small text</p>`}
|
||
/>
|
||
</div>
|
||
<div>
|
||
<p className="text-lg text-muted-foreground max-w-2xl mx-auto text-pretty leading-relaxed mb-2">
|
||
Centered paragraph with max-w-2xl mx-auto for centered
|
||
content.
|
||
</p>
|
||
<CodeBlock
|
||
id="p-centered-code"
|
||
code={`<p className="text-lg text-muted-foreground max-w-2xl mx-auto text-pretty leading-relaxed">Centered paragraph</p>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Buttons */}
|
||
<Section id="buttons" title="Buttons">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Button Variants</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Different button styles for various use cases. The brand variant
|
||
uses the primary red color for important CTAs.
|
||
</p>
|
||
<div className="flex flex-wrap gap-4 mb-6">
|
||
<Button variant="default">Default</Button>
|
||
<Button variant="secondary">Secondary</Button>
|
||
<Button variant="destructive">Destructive</Button>
|
||
<Button variant="outline">Outline</Button>
|
||
<Button variant="ghost">Ghost</Button>
|
||
<Button variant="link">Link</Button>
|
||
<Button variant="brand">Brand</Button>
|
||
</div>
|
||
<CodeBlock
|
||
id="button-variants-code"
|
||
code={`<Button variant="default">Default</Button>
|
||
<Button variant="secondary">Secondary</Button>
|
||
<Button variant="destructive">Destructive</Button>
|
||
<Button variant="outline">Outline</Button>
|
||
<Button variant="ghost">Ghost</Button>
|
||
<Button variant="link">Link</Button>
|
||
<Button variant="brand">Brand</Button>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Button Sizes</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Button size options from small to large, plus icon-only buttons
|
||
for compact interfaces.
|
||
</p>
|
||
<div className="flex flex-wrap items-center gap-4 mb-6">
|
||
<Button size="sm">Small</Button>
|
||
<Button size="default">Default</Button>
|
||
<Button size="lg">Large</Button>
|
||
<Button size="icon" aria-label="Icon button">
|
||
<Star className="h-4 w-4" />
|
||
</Button>
|
||
</div>
|
||
<CodeBlock
|
||
id="button-sizes-code"
|
||
code={`<Button size="sm">Small</Button>
|
||
<Button size="default">Default</Button>
|
||
<Button size="lg">Large</Button>
|
||
<Button size="icon" aria-label="Icon button">
|
||
<Star className="h-4 w-4" />
|
||
</Button>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Button States</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Button states including normal, disabled, and link variants.
|
||
Buttons can also be used as links with the asChild prop.
|
||
</p>
|
||
<div className="flex flex-wrap gap-4 mb-6">
|
||
<Button>Normal</Button>
|
||
<Button disabled>Disabled</Button>
|
||
<Button asChild>
|
||
<Link href="#buttons">As Link</Link>
|
||
</Button>
|
||
</div>
|
||
<CodeBlock
|
||
id="button-states-code"
|
||
code={`<Button>Normal</Button>
|
||
<Button disabled>Disabled</Button>
|
||
<Button asChild>
|
||
<Link href="#buttons">As Link</Link>
|
||
</Button>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Cards */}
|
||
<Section id="cards" title="Cards">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Standard Card</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Basic card component with header, content, and footer sections.
|
||
Includes hover effects for interactivity.
|
||
</p>
|
||
<Card className="border-border/50 hover:border-secondary/50 transition-colors mb-6">
|
||
<CardHeader>
|
||
<CardTitle>Card Title</CardTitle>
|
||
<CardDescription>
|
||
Card description text goes here
|
||
</CardDescription>
|
||
</CardHeader>
|
||
<CardContent>
|
||
<p className="text-sm text-muted-foreground">
|
||
Card content area with padding and proper spacing.
|
||
</p>
|
||
</CardContent>
|
||
<CardFooter>
|
||
<Button size="sm">Action</Button>
|
||
</CardFooter>
|
||
</Card>
|
||
<CodeBlock
|
||
id="card-standard-code"
|
||
code={`<Card className="border-border/50 hover:border-secondary/50 transition-colors">
|
||
<CardHeader>
|
||
<CardTitle>Card Title</CardTitle>
|
||
<CardDescription>Card description</CardDescription>
|
||
</CardHeader>
|
||
<CardContent>
|
||
<p>Card content</p>
|
||
</CardContent>
|
||
<CardFooter>
|
||
<Button size="sm">Action</Button>
|
||
</CardFooter>
|
||
</Card>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Card with Image</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Card layout with an image header using aspect-video ratio.
|
||
Perfect for product cards and feature showcases.
|
||
</p>
|
||
<Card className="border-border/50 overflow-hidden hover:border-secondary/50 transition-colors mb-6">
|
||
<div className="aspect-video relative bg-muted">
|
||
<div className="absolute inset-0 flex items-center justify-center text-muted-foreground">
|
||
Image Placeholder
|
||
</div>
|
||
</div>
|
||
<CardContent className="p-6">
|
||
<h3 className="text-xl font-semibold mb-2">
|
||
Card with Image
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground leading-relaxed">
|
||
Card content below image.
|
||
</p>
|
||
</CardContent>
|
||
</Card>
|
||
<CodeBlock
|
||
id="card-image-code"
|
||
code={`<Card className="border-border/50 overflow-hidden hover:border-secondary/50 transition-colors">
|
||
<div className="aspect-video relative bg-muted">
|
||
<Image src="/image.jpg" alt="Description" fill className="object-cover" />
|
||
</div>
|
||
<CardContent className="p-6">
|
||
<h3 className="text-xl font-semibold mb-2">Title</h3>
|
||
<p className="text-sm text-muted-foreground">Content</p>
|
||
</CardContent>
|
||
</Card>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Gradient CTA Card</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
A call-to-action card with gradient background, typically used
|
||
for important CTAs on service pages.
|
||
</p>
|
||
<Card className="border-2 shadow-lg [&>div]:!bg-transparent bg-gradient-to-r from-[var(--primary)] to-[#1d7a35] mb-6">
|
||
<CardContent className="p-10 md:p-12 text-center">
|
||
<h2 className="text-2xl md:text-3xl font-bold text-white mb-4 tracking-tight text-balance">
|
||
Ready to Get Started?
|
||
</h2>
|
||
<p className="text-white/90 mb-8 max-w-2xl mx-auto text-lg leading-relaxed">
|
||
Contact us today to learn more about our free vending
|
||
machine services and how we can help your business.
|
||
</p>
|
||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||
<Button
|
||
asChild
|
||
size="lg"
|
||
className="bg-white text-[var(--primary)] hover:bg-white/90 text-lg h-12 px-8 font-semibold"
|
||
>
|
||
<Link href="#cards">Contact Us</Link>
|
||
</Button>
|
||
<Button
|
||
asChild
|
||
size="lg"
|
||
variant="outline"
|
||
className="bg-transparent border-2 border-white text-white hover:bg-white/10 text-lg h-12 px-8 font-semibold"
|
||
>
|
||
<Link href="#cards">Get Free Machine</Link>
|
||
</Button>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
<CodeBlock
|
||
id="card-gradient-cta-code"
|
||
code={`<Card className="border-2 shadow-lg [&>div]:!bg-transparent bg-gradient-to-r from-[var(--primary)] to-[#1d7a35]">
|
||
<CardContent className="p-10 md:p-12 text-center">
|
||
<h2 className="text-2xl md:text-3xl font-bold text-white mb-4 tracking-tight text-balance">
|
||
Ready to Get Started?
|
||
</h2>
|
||
<p className="text-white/90 mb-8 max-w-2xl mx-auto text-lg leading-relaxed">
|
||
Contact us today to learn more about our services.
|
||
</p>
|
||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||
<Button asChild size="lg" className="bg-white text-[var(--primary)] hover:bg-white/90">
|
||
<Link href="/contact-us">Contact Us</Link>
|
||
</Button>
|
||
<Button asChild size="lg" variant="outline" className="bg-transparent border-2 border-white text-white hover:bg-white/10">
|
||
<Link href="/#request-machine">Get Free Machine</Link>
|
||
</Button>
|
||
</div>
|
||
</CardContent>
|
||
</Card>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">
|
||
Card with Icon Grid
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Cards arranged in a grid with icons, commonly used for benefits
|
||
or features sections.
|
||
</p>
|
||
<div className="grid gap-6 md:grid-cols-2 mb-6">
|
||
<Card className="border-border/50 hover:border-secondary/50 transition-colors">
|
||
<CardContent className="p-6">
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2 text-foreground">
|
||
100% FREE Service
|
||
</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
No upfront costs, installation fees, or monthly
|
||
charges
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
<Card className="border-border/50 hover:border-secondary/50 transition-colors">
|
||
<CardContent className="p-6">
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2 text-foreground">
|
||
Regular Maintenance
|
||
</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
We stock, service, and maintain all machines at no
|
||
cost to you
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
<CodeBlock
|
||
id="card-icon-grid-code"
|
||
code={`<div className="grid gap-6 md:grid-cols-2">
|
||
<Card className="border-border/50 hover:border-secondary/50 transition-colors">
|
||
<CardContent className="p-6">
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2">Feature Title</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
Feature description text goes here.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">
|
||
Card with Secondary Background
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Card with subtle secondary color background for emphasis. Ideal
|
||
for highlighting important information or callouts.
|
||
</p>
|
||
<Card className="border-secondary/20 bg-secondary/5 mb-6">
|
||
<CardContent className="p-6 md:p-8">
|
||
<p className="text-base md:text-lg leading-relaxed">
|
||
This card uses a subtle secondary color background for
|
||
emphasis. Perfect for highlighting important information or
|
||
anecdotes.
|
||
</p>
|
||
</CardContent>
|
||
</Card>
|
||
<CodeBlock
|
||
id="card-secondary-bg-code"
|
||
code={`<Card className="border-secondary/20 bg-secondary/5">
|
||
<CardContent className="p-6 md:p-8">
|
||
<p className="text-base md:text-lg leading-relaxed">
|
||
Content with subtle background emphasis.
|
||
</p>
|
||
</CardContent>
|
||
</Card>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Badges */}
|
||
<Section id="badges" title="Badges">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Badge Variants</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Badge components for labels, status indicators, and tags.
|
||
Available in multiple variants for different contexts.
|
||
</p>
|
||
<div className="flex flex-wrap gap-4 mb-6">
|
||
<Badge variant="default">Default</Badge>
|
||
<Badge variant="secondary">Secondary</Badge>
|
||
<Badge variant="destructive">Destructive</Badge>
|
||
<Badge variant="outline">Outline</Badge>
|
||
</div>
|
||
<CodeBlock
|
||
id="badge-variants-code"
|
||
code={`<Badge variant="default">Default</Badge>
|
||
<Badge variant="secondary">Secondary</Badge>
|
||
<Badge variant="destructive">Destructive</Badge>
|
||
<Badge variant="outline">Outline</Badge>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Links */}
|
||
<Section id="links" title="Link Styling">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Link States</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Link styling with automatic red hover color. All links use the
|
||
brand red (#c4142c) on hover for consistency.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<div>
|
||
<p className="mb-2">
|
||
Default link:{" "}
|
||
<a href="#links" className="transition-colors">
|
||
Example Link
|
||
</a>
|
||
</p>
|
||
</div>
|
||
<div>
|
||
<p className="mb-2">
|
||
Hover state (red):{" "}
|
||
<a
|
||
href="#links"
|
||
className="hover:text-[#c4142c] transition-colors"
|
||
>
|
||
Hover me
|
||
</a>
|
||
</p>
|
||
</div>
|
||
<div>
|
||
<p className="mb-2">
|
||
Next.js Link:{" "}
|
||
<Link href="#links" className="transition-colors">
|
||
Next.js Link Component
|
||
</Link>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="links-code"
|
||
code={`// Standard HTML link
|
||
<a href="/contact-us" className="transition-colors">Link Text</a>
|
||
|
||
// Next.js Link component
|
||
<Link href="/contact-us" className="transition-colors">Link Text</Link>
|
||
|
||
// All links automatically get red hover color via global CSS`}
|
||
/>
|
||
<p className="text-sm text-muted-foreground">
|
||
All links automatically use the red hover color (#c4142c)
|
||
defined in globals.css. No need to add hover classes manually.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Form Inputs */}
|
||
<Section id="inputs" title="Form Inputs">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Input Fields</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Text input fields with labels. Supports various input types
|
||
including text, email, and disabled states.
|
||
</p>
|
||
<div className="space-y-4 mb-6 max-w-md">
|
||
<div>
|
||
<Label htmlFor="text-input">Text Input</Label>
|
||
<Input
|
||
id="text-input"
|
||
type="text"
|
||
placeholder="Enter text..."
|
||
/>
|
||
</div>
|
||
<div>
|
||
<Label htmlFor="email-input">Email Input</Label>
|
||
<Input
|
||
id="email-input"
|
||
type="email"
|
||
placeholder="email@example.com"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<Label htmlFor="disabled-input">Disabled Input</Label>
|
||
<Input
|
||
id="disabled-input"
|
||
type="text"
|
||
placeholder="Disabled"
|
||
disabled
|
||
/>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="input-code"
|
||
code={`<div>
|
||
<Label htmlFor="text-input">Text Input</Label>
|
||
<Input id="text-input" type="text" placeholder="Enter text..." />
|
||
</div>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Select Dropdown</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Dropdown select component for choosing from a list of options.
|
||
Accessible and keyboard navigable.
|
||
</p>
|
||
<div className="mb-6 max-w-md">
|
||
<Label>Select Option</Label>
|
||
<Select>
|
||
<SelectTrigger>
|
||
<SelectValue placeholder="Select an option" />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
<SelectItem value="option1">Option 1</SelectItem>
|
||
<SelectItem value="option2">Option 2</SelectItem>
|
||
<SelectItem value="option3">Option 3</SelectItem>
|
||
</SelectContent>
|
||
</Select>
|
||
</div>
|
||
<CodeBlock
|
||
id="select-code"
|
||
code={`<Select>
|
||
<SelectTrigger>
|
||
<SelectValue placeholder="Select an option" />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
<SelectItem value="option1">Option 1</SelectItem>
|
||
<SelectItem value="option2">Option 2</SelectItem>
|
||
</SelectContent>
|
||
</Select>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">
|
||
Checkboxes & Radio Buttons
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Form controls for multiple selection (checkboxes) and single
|
||
selection (radio buttons) with labels.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<div className="flex items-center space-x-2">
|
||
<Checkbox id="checkbox1" />
|
||
<Label htmlFor="checkbox1">Checkbox option</Label>
|
||
</div>
|
||
<div className="flex items-center space-x-2">
|
||
<Checkbox id="checkbox2" checked />
|
||
<Label htmlFor="checkbox2">Checked checkbox</Label>
|
||
</div>
|
||
<RadioGroup defaultValue="option1">
|
||
<div className="flex items-center space-x-2">
|
||
<RadioGroupItem value="option1" id="radio1" />
|
||
<Label htmlFor="radio1">Radio option 1</Label>
|
||
</div>
|
||
<div className="flex items-center space-x-2">
|
||
<RadioGroupItem value="option2" id="radio2" />
|
||
<Label htmlFor="radio2">Radio option 2</Label>
|
||
</div>
|
||
</RadioGroup>
|
||
</div>
|
||
<CodeBlock
|
||
id="checkbox-radio-code"
|
||
code={`<div className="flex items-center space-x-2">
|
||
<Checkbox id="checkbox1" />
|
||
<Label htmlFor="checkbox1">Checkbox option</Label>
|
||
</div>
|
||
|
||
<RadioGroup defaultValue="option1">
|
||
<div className="flex items-center space-x-2">
|
||
<RadioGroupItem value="option1" id="radio1" />
|
||
<Label htmlFor="radio1">Radio option 1</Label>
|
||
</div>
|
||
</RadioGroup>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Tabs</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Tabs component for organizing content into multiple panels.
|
||
Supports default, card, and vertical variants.
|
||
</p>
|
||
<div className="space-y-8 mb-6">
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">Default Tabs</h4>
|
||
<Tabs defaultValue="account" className="w-full">
|
||
<TabsList className="grid w-full grid-cols-3">
|
||
<TabsTrigger value="account">Account</TabsTrigger>
|
||
<TabsTrigger value="password">Password</TabsTrigger>
|
||
<TabsTrigger value="settings">Settings</TabsTrigger>
|
||
</TabsList>
|
||
<TabsContent value="account" className="mt-4">
|
||
<Card>
|
||
<CardHeader>
|
||
<CardTitle>Account</CardTitle>
|
||
<CardDescription>
|
||
Make changes to your account here. Click save when
|
||
you're done.
|
||
</CardDescription>
|
||
</CardHeader>
|
||
<CardContent className="space-y-2">
|
||
<div>
|
||
<Label htmlFor="name">Name</Label>
|
||
<Input id="name" defaultValue="Pedro Duarte" />
|
||
</div>
|
||
<div>
|
||
<Label htmlFor="username">Username</Label>
|
||
<Input id="username" defaultValue="@peduarte" />
|
||
</div>
|
||
</CardContent>
|
||
<CardFooter>
|
||
<Button>Save changes</Button>
|
||
</CardFooter>
|
||
</Card>
|
||
</TabsContent>
|
||
<TabsContent value="password" className="mt-4">
|
||
<Card>
|
||
<CardHeader>
|
||
<CardTitle>Password</CardTitle>
|
||
<CardDescription>
|
||
Change your password here. After saving, you'll be
|
||
logged out.
|
||
</CardDescription>
|
||
</CardHeader>
|
||
<CardContent className="space-y-2">
|
||
<div>
|
||
<Label htmlFor="current">Current password</Label>
|
||
<Input id="current" type="password" />
|
||
</div>
|
||
<div>
|
||
<Label htmlFor="new">New password</Label>
|
||
<Input id="new" type="password" />
|
||
</div>
|
||
</CardContent>
|
||
<CardFooter>
|
||
<Button>Save password</Button>
|
||
</CardFooter>
|
||
</Card>
|
||
</TabsContent>
|
||
<TabsContent value="settings" className="mt-4">
|
||
<Card>
|
||
<CardHeader>
|
||
<CardTitle>Settings</CardTitle>
|
||
<CardDescription>
|
||
Manage your account settings and preferences.
|
||
</CardDescription>
|
||
</CardHeader>
|
||
<CardContent className="space-y-2">
|
||
<div className="flex items-center space-x-2">
|
||
<Switch id="notifications" />
|
||
<Label htmlFor="notifications">
|
||
Enable notifications
|
||
</Label>
|
||
</div>
|
||
<div className="flex items-center space-x-2">
|
||
<Switch id="marketing" />
|
||
<Label htmlFor="marketing">Marketing emails</Label>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</TabsContent>
|
||
</Tabs>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="tabs-code"
|
||
code={`<Tabs defaultValue="account" className="w-full">
|
||
<TabsList>
|
||
<TabsTrigger value="account">Account</TabsTrigger>
|
||
<TabsTrigger value="password">Password</TabsTrigger>
|
||
<TabsTrigger value="settings">Settings</TabsTrigger>
|
||
</TabsList>
|
||
<TabsContent value="account">
|
||
<Card>
|
||
<CardHeader>
|
||
<CardTitle>Account</CardTitle>
|
||
<CardDescription>Description</CardDescription>
|
||
</CardHeader>
|
||
<CardContent>
|
||
{/* Content */}
|
||
</CardContent>
|
||
</Card>
|
||
</TabsContent>
|
||
<TabsContent value="password">
|
||
{/* Content */}
|
||
</TabsContent>
|
||
</Tabs>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Accordion</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Collapsible content sections for organizing information.
|
||
Supports single or multiple open items.
|
||
</p>
|
||
<Accordion type="single" collapsible className="mb-6">
|
||
<AccordionItem value="item-1">
|
||
<AccordionTrigger>Accordion Item 1</AccordionTrigger>
|
||
<AccordionContent>
|
||
Content for accordion item 1 goes here.
|
||
</AccordionContent>
|
||
</AccordionItem>
|
||
<AccordionItem value="item-2">
|
||
<AccordionTrigger>Accordion Item 2</AccordionTrigger>
|
||
<AccordionContent>
|
||
Content for accordion item 2 goes here.
|
||
</AccordionContent>
|
||
</AccordionItem>
|
||
</Accordion>
|
||
<CodeBlock
|
||
id="accordion-code"
|
||
code={`<Accordion type="single" collapsible>
|
||
<AccordionItem value="item-1">
|
||
<AccordionTrigger>Item 1</AccordionTrigger>
|
||
<AccordionContent>Content 1</AccordionContent>
|
||
</AccordionItem>
|
||
</Accordion>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Textarea</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Multi-line text input for longer content like messages,
|
||
comments, or descriptions.
|
||
</p>
|
||
<div className="mb-6 max-w-md">
|
||
<Label htmlFor="textarea-example">Message</Label>
|
||
<Textarea
|
||
id="textarea-example"
|
||
placeholder="Enter your message here..."
|
||
rows={4}
|
||
/>
|
||
</div>
|
||
<CodeBlock
|
||
id="textarea-code"
|
||
code={`<Textarea placeholder="Enter your message..." rows={4} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Field Components</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Field components provide a structured way to build forms with
|
||
labels, descriptions, and error messages.
|
||
</p>
|
||
<div className="mb-6 max-w-md">
|
||
<FieldSet>
|
||
<FieldLegend>Personal Information</FieldLegend>
|
||
<FieldDescription>
|
||
Enter your personal details below. All fields are required.
|
||
</FieldDescription>
|
||
<FieldGroup>
|
||
<Field>
|
||
<FieldLabel>First Name</FieldLabel>
|
||
<Input placeholder="John" />
|
||
<FieldDescription>Enter your first name</FieldDescription>
|
||
</Field>
|
||
<Field>
|
||
<FieldLabel>Last Name</FieldLabel>
|
||
<Input placeholder="Doe" />
|
||
<FieldDescription>Enter your last name</FieldDescription>
|
||
</Field>
|
||
<Field>
|
||
<FieldLabel>Email</FieldLabel>
|
||
<Input type="email" placeholder="john@example.com" />
|
||
<FieldDescription>
|
||
We'll never share your email
|
||
</FieldDescription>
|
||
<FieldError>Email is required</FieldError>
|
||
</Field>
|
||
</FieldGroup>
|
||
</FieldSet>
|
||
</div>
|
||
<CodeBlock
|
||
id="field-code"
|
||
code={`<FieldSet>
|
||
<FieldLegend>Form Title</FieldLegend>
|
||
<FieldDescription>Form description text</FieldDescription>
|
||
<FieldGroup>
|
||
<Field>
|
||
<FieldLabel>Label</FieldLabel>
|
||
<Input placeholder="Enter value" />
|
||
<FieldDescription>Helper text</FieldDescription>
|
||
<FieldError>Error message</FieldError>
|
||
</Field>
|
||
</FieldGroup>
|
||
</FieldSet>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Feedback Components */}
|
||
<Section id="feedback" title="Feedback Components">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Alert</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Alert components for displaying important messages, warnings,
|
||
and notifications to users.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<Alert>
|
||
<AlertCircle className="h-4 w-4" />
|
||
<AlertTitle>Default Alert</AlertTitle>
|
||
<AlertDescription>
|
||
This is a default alert message.
|
||
</AlertDescription>
|
||
</Alert>
|
||
<Alert variant="destructive">
|
||
<AlertCircle className="h-4 w-4" />
|
||
<AlertTitle>Destructive Alert</AlertTitle>
|
||
<AlertDescription>
|
||
This is a destructive alert message.
|
||
</AlertDescription>
|
||
</Alert>
|
||
</div>
|
||
<CodeBlock
|
||
id="alert-code"
|
||
code={`<Alert>
|
||
<AlertCircle className="h-4 w-4" />
|
||
<AlertTitle>Alert Title</AlertTitle>
|
||
<AlertDescription>Alert description text.</AlertDescription>
|
||
</Alert>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Alert Dialog</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Modal dialog for critical confirmations and destructive actions.
|
||
Requires user interaction to dismiss.
|
||
</p>
|
||
<AlertDialog>
|
||
<AlertDialogTrigger asChild>
|
||
<Button variant="outline">Open Alert Dialog</Button>
|
||
</AlertDialogTrigger>
|
||
<AlertDialogContent>
|
||
<AlertDialogHeader>
|
||
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
|
||
<AlertDialogDescription>
|
||
This action cannot be undone. This will permanently delete
|
||
your data.
|
||
</AlertDialogDescription>
|
||
</AlertDialogHeader>
|
||
<AlertDialogFooter>
|
||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||
<AlertDialogAction>Continue</AlertDialogAction>
|
||
</AlertDialogFooter>
|
||
</AlertDialogContent>
|
||
</AlertDialog>
|
||
<CodeBlock
|
||
id="alert-dialog-code"
|
||
code={`<AlertDialog>
|
||
<AlertDialogTrigger asChild>
|
||
<Button>Open</Button>
|
||
</AlertDialogTrigger>
|
||
<AlertDialogContent>
|
||
<AlertDialogHeader>
|
||
<AlertDialogTitle>Title</AlertDialogTitle>
|
||
<AlertDialogDescription>Description</AlertDialogDescription>
|
||
</AlertDialogHeader>
|
||
<AlertDialogFooter>
|
||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||
<AlertDialogAction>Continue</AlertDialogAction>
|
||
</AlertDialogFooter>
|
||
</AlertDialogContent>
|
||
</AlertDialog>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Skeleton</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Loading placeholders that mimic content structure while data is
|
||
being fetched.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<div className="flex items-center space-x-4">
|
||
<Skeleton className="h-12 w-12 rounded-full" />
|
||
<div className="space-y-2">
|
||
<Skeleton className="h-4 w-[250px]" />
|
||
<Skeleton className="h-4 w-[200px]" />
|
||
</div>
|
||
</div>
|
||
<Skeleton className="h-32 w-full rounded-lg" />
|
||
</div>
|
||
<CodeBlock
|
||
id="skeleton-code"
|
||
code={`<Skeleton className="h-12 w-12 rounded-full" />
|
||
<Skeleton className="h-4 w-[250px]" />
|
||
<Skeleton className="h-32 w-full rounded-lg" />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Progress</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Progress bar component for showing completion status, upload
|
||
progress, or loading states.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<Progress value={33} />
|
||
<Progress value={66} />
|
||
<Progress value={100} />
|
||
</div>
|
||
<CodeBlock
|
||
id="progress-code"
|
||
code={`<Progress value={33} />
|
||
<Progress value={66} />
|
||
<Progress value={100} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Spinner</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Loading spinner component available in multiple sizes for
|
||
indicating async operations.
|
||
</p>
|
||
<div className="flex items-center gap-4 mb-6">
|
||
<Spinner className="h-4 w-4" />
|
||
<Spinner className="h-6 w-6" />
|
||
<Spinner className="h-8 w-8" />
|
||
</div>
|
||
<CodeBlock
|
||
id="spinner-code"
|
||
code={`<Spinner className="h-4 w-4" />
|
||
<Spinner className="h-6 w-6" />
|
||
<Spinner className="h-8 w-8" />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Toast</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Toast notifications for temporary messages, success
|
||
confirmations, and error alerts.
|
||
</p>
|
||
<div className="flex flex-wrap gap-4 mb-6">
|
||
<Button
|
||
onClick={() =>
|
||
toast({
|
||
title: "Toast Title",
|
||
description: "This is a toast notification.",
|
||
})
|
||
}
|
||
>
|
||
Show Toast
|
||
</Button>
|
||
<Button
|
||
onClick={() =>
|
||
toast({
|
||
title: "Destructive Toast",
|
||
description: "This is a destructive toast.",
|
||
variant: "destructive",
|
||
})
|
||
}
|
||
variant="destructive"
|
||
>
|
||
Show Destructive Toast
|
||
</Button>
|
||
</div>
|
||
<CodeBlock
|
||
id="toast-code"
|
||
code={`const { toast } = useToast()
|
||
|
||
toast({
|
||
title: "Toast Title",
|
||
description: "This is a toast notification.",
|
||
})`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Overlay Components */}
|
||
<Section id="overlays" title="Overlay Components">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Dialog</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Modal dialog component for focused interactions, forms, and
|
||
important content that requires user attention.
|
||
</p>
|
||
<Dialog>
|
||
<DialogTrigger asChild>
|
||
<Button variant="outline">Open Dialog</Button>
|
||
</DialogTrigger>
|
||
<DialogContent>
|
||
<DialogHeader>
|
||
<DialogTitle>Dialog Title</DialogTitle>
|
||
<DialogDescription>
|
||
This is a dialog description. It can contain any content.
|
||
</DialogDescription>
|
||
</DialogHeader>
|
||
<p className="text-sm text-muted-foreground">
|
||
Dialog content goes here.
|
||
</p>
|
||
</DialogContent>
|
||
</Dialog>
|
||
<CodeBlock
|
||
id="dialog-code"
|
||
code={`<Dialog>
|
||
<DialogTrigger asChild>
|
||
<Button>Open</Button>
|
||
</DialogTrigger>
|
||
<DialogContent>
|
||
<DialogHeader>
|
||
<DialogTitle>Title</DialogTitle>
|
||
<DialogDescription>Description</DialogDescription>
|
||
</DialogHeader>
|
||
<p>Content</p>
|
||
</DialogContent>
|
||
</Dialog>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Sheet</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Sheet component that slides in from different sides. Perfect for
|
||
mobile menus, sidebars, and detail views.
|
||
</p>
|
||
<div className="flex flex-wrap gap-4 mb-6">
|
||
<Sheet>
|
||
<SheetTrigger asChild>
|
||
<Button variant="outline">Open Right Sheet</Button>
|
||
</SheetTrigger>
|
||
<SheetContent side="right">
|
||
<SheetHeader>
|
||
<SheetTitle>Right Side Sheet</SheetTitle>
|
||
<SheetDescription>
|
||
This sheet slides in from the right side. Perfect for
|
||
detail views and forms.
|
||
</SheetDescription>
|
||
</SheetHeader>
|
||
<div className="mt-6 space-y-4">
|
||
<div>
|
||
<Label htmlFor="sheet-name">Name</Label>
|
||
<Input
|
||
id="sheet-name"
|
||
placeholder="Enter name"
|
||
className="mt-2"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<Label htmlFor="sheet-email">Email</Label>
|
||
<Input
|
||
id="sheet-email"
|
||
type="email"
|
||
placeholder="Enter email"
|
||
className="mt-2"
|
||
/>
|
||
</div>
|
||
<Button className="w-full">Save Changes</Button>
|
||
</div>
|
||
</SheetContent>
|
||
</Sheet>
|
||
<Sheet>
|
||
<SheetTrigger asChild>
|
||
<Button variant="outline">Open Left Sheet</Button>
|
||
</SheetTrigger>
|
||
<SheetContent side="left">
|
||
<SheetHeader>
|
||
<SheetTitle>Left Side Sheet</SheetTitle>
|
||
<SheetDescription>
|
||
This sheet slides in from the left side. Great for
|
||
navigation menus.
|
||
</SheetDescription>
|
||
</SheetHeader>
|
||
<nav className="mt-6 space-y-2">
|
||
<a
|
||
href="#"
|
||
className="block py-2 hover:text-secondary transition-colors"
|
||
>
|
||
Home
|
||
</a>
|
||
<a
|
||
href="#"
|
||
className="block py-2 hover:text-secondary transition-colors"
|
||
>
|
||
About
|
||
</a>
|
||
<a
|
||
href="#"
|
||
className="block py-2 hover:text-secondary transition-colors"
|
||
>
|
||
Services
|
||
</a>
|
||
<a
|
||
href="#"
|
||
className="block py-2 hover:text-secondary transition-colors"
|
||
>
|
||
Contact
|
||
</a>
|
||
</nav>
|
||
</SheetContent>
|
||
</Sheet>
|
||
<Sheet>
|
||
<SheetTrigger asChild>
|
||
<Button variant="outline">Open Top Sheet</Button>
|
||
</SheetTrigger>
|
||
<SheetContent side="top">
|
||
<SheetHeader>
|
||
<SheetTitle>Top Sheet</SheetTitle>
|
||
<SheetDescription>
|
||
This sheet slides in from the top. Useful for
|
||
notifications and filters.
|
||
</SheetDescription>
|
||
</SheetHeader>
|
||
</SheetContent>
|
||
</Sheet>
|
||
<Sheet>
|
||
<SheetTrigger asChild>
|
||
<Button variant="outline">Open Bottom Sheet</Button>
|
||
</SheetTrigger>
|
||
<SheetContent side="bottom">
|
||
<SheetHeader>
|
||
<SheetTitle>Bottom Sheet</SheetTitle>
|
||
<SheetDescription>
|
||
This sheet slides in from the bottom. Perfect for mobile
|
||
actions.
|
||
</SheetDescription>
|
||
</SheetHeader>
|
||
</SheetContent>
|
||
</Sheet>
|
||
</div>
|
||
<CodeBlock
|
||
id="sheet-code"
|
||
code={`<Sheet>
|
||
<SheetTrigger asChild>
|
||
<Button variant="outline">Open Sheet</Button>
|
||
</SheetTrigger>
|
||
<SheetContent side="right">
|
||
<SheetHeader>
|
||
<SheetTitle>Sheet Title</SheetTitle>
|
||
<SheetDescription>Description text</SheetDescription>
|
||
</SheetHeader>
|
||
<div className="mt-6">
|
||
{/* Your content here */}
|
||
</div>
|
||
</SheetContent>
|
||
</Sheet>
|
||
|
||
// Available sides: "top" | "right" | "bottom" | "left"`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Drawer</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Bottom drawer component for mobile-friendly interactions,
|
||
filters, and additional content.
|
||
</p>
|
||
<Drawer>
|
||
<DrawerTrigger asChild>
|
||
<Button variant="outline">Open Drawer</Button>
|
||
</DrawerTrigger>
|
||
<DrawerContent>
|
||
<DrawerHeader>
|
||
<DrawerTitle>Drawer Title</DrawerTitle>
|
||
<DrawerDescription>
|
||
This is a drawer component.
|
||
</DrawerDescription>
|
||
</DrawerHeader>
|
||
<p className="text-sm text-muted-foreground px-4">
|
||
Drawer content goes here.
|
||
</p>
|
||
<DrawerFooter>
|
||
<Button>Submit</Button>
|
||
<DrawerClose asChild>
|
||
<Button variant="outline">Cancel</Button>
|
||
</DrawerClose>
|
||
</DrawerFooter>
|
||
</DrawerContent>
|
||
</Drawer>
|
||
<CodeBlock
|
||
id="drawer-code"
|
||
code={`<Drawer>
|
||
<DrawerTrigger asChild>
|
||
<Button>Open</Button>
|
||
</DrawerTrigger>
|
||
<DrawerContent>
|
||
<DrawerHeader>
|
||
<DrawerTitle>Title</DrawerTitle>
|
||
<DrawerDescription>Description</DrawerDescription>
|
||
</DrawerHeader>
|
||
<p>Content</p>
|
||
</DrawerContent>
|
||
</Drawer>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Popover</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Popover component for displaying additional information or
|
||
actions in a floating panel.
|
||
</p>
|
||
<Popover>
|
||
<PopoverTrigger asChild>
|
||
<Button variant="outline">Open Popover</Button>
|
||
</PopoverTrigger>
|
||
<PopoverContent>
|
||
<div className="space-y-2">
|
||
<h4 className="font-medium">Popover Title</h4>
|
||
<p className="text-sm text-muted-foreground">
|
||
This is a popover component.
|
||
</p>
|
||
</div>
|
||
</PopoverContent>
|
||
</Popover>
|
||
<CodeBlock
|
||
id="popover-code"
|
||
code={`<Popover>
|
||
<PopoverTrigger asChild>
|
||
<Button>Open</Button>
|
||
</PopoverTrigger>
|
||
<PopoverContent>
|
||
<h4>Title</h4>
|
||
<p>Content</p>
|
||
</PopoverContent>
|
||
</Popover>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Tooltip</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Tooltip component for showing helpful hints and additional
|
||
context on hover or focus.
|
||
</p>
|
||
<TooltipProvider>
|
||
<Tooltip>
|
||
<TooltipTrigger asChild>
|
||
<Button variant="outline">Hover for tooltip</Button>
|
||
</TooltipTrigger>
|
||
<TooltipContent>
|
||
<p>This is a tooltip</p>
|
||
</TooltipContent>
|
||
</Tooltip>
|
||
</TooltipProvider>
|
||
<CodeBlock
|
||
id="tooltip-code"
|
||
code={`<TooltipProvider>
|
||
<Tooltip>
|
||
<TooltipTrigger asChild>
|
||
<Button>Hover me</Button>
|
||
</TooltipTrigger>
|
||
<TooltipContent>
|
||
<p>Tooltip text</p>
|
||
</TooltipContent>
|
||
</Tooltip>
|
||
</TooltipProvider>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Hover Card</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Rich hover card for displaying detailed information about users,
|
||
items, or entities on hover.
|
||
</p>
|
||
<HoverCard>
|
||
<HoverCardTrigger asChild>
|
||
<Button variant="link">@username</Button>
|
||
</HoverCardTrigger>
|
||
<HoverCardContent>
|
||
<div className="space-y-2">
|
||
<h4 className="text-sm font-semibold">User Name</h4>
|
||
<p className="text-sm text-muted-foreground">
|
||
User description goes here.
|
||
</p>
|
||
</div>
|
||
</HoverCardContent>
|
||
</HoverCard>
|
||
<CodeBlock
|
||
id="hover-card-code"
|
||
code={`<HoverCard>
|
||
<HoverCardTrigger asChild>
|
||
<Button variant="link">@username</Button>
|
||
</HoverCardTrigger>
|
||
<HoverCardContent>
|
||
<h4>Title</h4>
|
||
<p>Content</p>
|
||
</HoverCardContent>
|
||
</HoverCard>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Navigation Components */}
|
||
<Section id="navigation" title="Navigation Components">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Breadcrumb</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Breadcrumb navigation for showing the current page location
|
||
within the site hierarchy.
|
||
</p>
|
||
<Breadcrumb className="mb-6">
|
||
<BreadcrumbList>
|
||
<BreadcrumbItem>
|
||
<BreadcrumbLink href="#">Home</BreadcrumbLink>
|
||
</BreadcrumbItem>
|
||
<BreadcrumbSeparator />
|
||
<BreadcrumbItem>
|
||
<BreadcrumbLink href="#">Components</BreadcrumbLink>
|
||
</BreadcrumbItem>
|
||
<BreadcrumbSeparator />
|
||
<BreadcrumbItem>
|
||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
||
</BreadcrumbItem>
|
||
</BreadcrumbList>
|
||
</Breadcrumb>
|
||
<CodeBlock
|
||
id="breadcrumb-code"
|
||
code={`<Breadcrumb>
|
||
<BreadcrumbList>
|
||
<BreadcrumbItem>
|
||
<BreadcrumbLink href="#">Home</BreadcrumbLink>
|
||
</BreadcrumbItem>
|
||
<BreadcrumbSeparator />
|
||
<BreadcrumbItem>
|
||
<BreadcrumbPage>Current</BreadcrumbPage>
|
||
</BreadcrumbItem>
|
||
</BreadcrumbList>
|
||
</Breadcrumb>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Pagination</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Pagination component for navigating through pages of content.
|
||
Supports ellipsis for large page counts.
|
||
</p>
|
||
<div className="space-y-6 mb-6">
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">Basic Pagination</h4>
|
||
<Pagination>
|
||
<PaginationContent>
|
||
<PaginationItem>
|
||
<PaginationPrevious href="#" />
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#">1</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#" isActive>
|
||
2
|
||
</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#">3</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationNext href="#" />
|
||
</PaginationItem>
|
||
</PaginationContent>
|
||
</Pagination>
|
||
</div>
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">
|
||
Pagination with Ellipsis
|
||
</h4>
|
||
<Pagination>
|
||
<PaginationContent>
|
||
<PaginationItem>
|
||
<PaginationPrevious href="#" />
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#">1</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#" isActive>
|
||
2
|
||
</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#">3</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<span className="px-2">...</span>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#">10</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationNext href="#" />
|
||
</PaginationItem>
|
||
</PaginationContent>
|
||
</Pagination>
|
||
</div>
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">
|
||
Compact Pagination
|
||
</h4>
|
||
<Pagination>
|
||
<PaginationContent>
|
||
<PaginationItem>
|
||
<PaginationPrevious href="#" />
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#" isActive>
|
||
1
|
||
</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationNext href="#" />
|
||
</PaginationItem>
|
||
</PaginationContent>
|
||
</Pagination>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="pagination-code"
|
||
code={`<Pagination>
|
||
<PaginationContent>
|
||
<PaginationItem>
|
||
<PaginationPrevious href="#" />
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#">1</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#" isActive>2</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationLink href="#">3</PaginationLink>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<span className="px-2">...</span>
|
||
</PaginationItem>
|
||
<PaginationItem>
|
||
<PaginationNext href="#" />
|
||
</PaginationItem>
|
||
</PaginationContent>
|
||
</Pagination>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Dropdown Menu</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Dropdown menu component that appears on click. Perfect for user
|
||
menus, action menus, and navigation dropdowns.
|
||
</p>
|
||
<DropdownMenu>
|
||
<DropdownMenuTrigger asChild>
|
||
<Button variant="outline">Open Menu</Button>
|
||
</DropdownMenuTrigger>
|
||
<DropdownMenuContent>
|
||
<DropdownMenuItem>Profile</DropdownMenuItem>
|
||
<DropdownMenuItem>Settings</DropdownMenuItem>
|
||
<DropdownMenuItem>Logout</DropdownMenuItem>
|
||
</DropdownMenuContent>
|
||
</DropdownMenu>
|
||
<CodeBlock
|
||
id="dropdown-menu-code"
|
||
code={`<DropdownMenu>
|
||
<DropdownMenuTrigger asChild>
|
||
<Button>Open</Button>
|
||
</DropdownMenuTrigger>
|
||
<DropdownMenuContent>
|
||
<DropdownMenuItem>Item 1</DropdownMenuItem>
|
||
<DropdownMenuItem>Item 2</DropdownMenuItem>
|
||
</DropdownMenuContent>
|
||
</DropdownMenu>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Context Menu</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Right-click context menu for displaying contextual actions.
|
||
Appears on right-click or long-press on mobile devices.
|
||
</p>
|
||
<ContextMenu>
|
||
<ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
|
||
Right click here
|
||
</ContextMenuTrigger>
|
||
<ContextMenuContent>
|
||
<ContextMenuItem>Back</ContextMenuItem>
|
||
<ContextMenuItem>Forward</ContextMenuItem>
|
||
<ContextMenuItem>Reload</ContextMenuItem>
|
||
</ContextMenuContent>
|
||
</ContextMenu>
|
||
<CodeBlock
|
||
id="context-menu-code"
|
||
code={`<ContextMenu>
|
||
<ContextMenuTrigger>Right click here</ContextMenuTrigger>
|
||
<ContextMenuContent>
|
||
<ContextMenuItem>Item 1</ContextMenuItem>
|
||
<ContextMenuItem>Item 2</ContextMenuItem>
|
||
</ContextMenuContent>
|
||
</ContextMenu>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Data Display */}
|
||
<Section id="data-display" title="Data Display">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Avatar</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Avatar component for displaying user profile pictures with
|
||
fallback initials when no image is available.
|
||
</p>
|
||
<div className="flex items-center gap-4 mb-6">
|
||
<Avatar>
|
||
<AvatarImage
|
||
src="https://github.com/shadcn.png"
|
||
alt="@shadcn"
|
||
/>
|
||
<AvatarFallback>CN</AvatarFallback>
|
||
</Avatar>
|
||
<Avatar>
|
||
<AvatarFallback>JD</AvatarFallback>
|
||
</Avatar>
|
||
<Avatar>
|
||
<AvatarFallback>AB</AvatarFallback>
|
||
</Avatar>
|
||
</div>
|
||
<CodeBlock
|
||
id="avatar-code"
|
||
code={`<Avatar>
|
||
<AvatarImage src="/image.jpg" alt="User" />
|
||
<AvatarFallback>CN</AvatarFallback>
|
||
</Avatar>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Table</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Table component for displaying structured data. Supports
|
||
headers, footers, and responsive layouts.
|
||
</p>
|
||
<div className="space-y-6 mb-6">
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">Basic Table</h4>
|
||
<div className="border rounded-lg overflow-hidden">
|
||
<Table>
|
||
<TableCaption>A list of recent invoices.</TableCaption>
|
||
<TableHeader>
|
||
<TableRow>
|
||
<TableHead className="w-[100px]">Invoice</TableHead>
|
||
<TableHead>Status</TableHead>
|
||
<TableHead>Method</TableHead>
|
||
<TableHead className="text-right">Amount</TableHead>
|
||
</TableRow>
|
||
</TableHeader>
|
||
<TableBody>
|
||
<TableRow>
|
||
<TableCell className="font-medium">INV001</TableCell>
|
||
<TableCell>
|
||
<Badge variant="outline">Paid</Badge>
|
||
</TableCell>
|
||
<TableCell>Credit Card</TableCell>
|
||
<TableCell className="text-right">$250.00</TableCell>
|
||
</TableRow>
|
||
<TableRow>
|
||
<TableCell className="font-medium">INV002</TableCell>
|
||
<TableCell>
|
||
<Badge variant="secondary">Pending</Badge>
|
||
</TableCell>
|
||
<TableCell>PayPal</TableCell>
|
||
<TableCell className="text-right">$150.00</TableCell>
|
||
</TableRow>
|
||
<TableRow>
|
||
<TableCell className="font-medium">INV003</TableCell>
|
||
<TableCell>
|
||
<Badge variant="outline">Paid</Badge>
|
||
</TableCell>
|
||
<TableCell>Bank Transfer</TableCell>
|
||
<TableCell className="text-right">$350.00</TableCell>
|
||
</TableRow>
|
||
<TableRow>
|
||
<TableCell className="font-medium">INV004</TableCell>
|
||
<TableCell>
|
||
<Badge variant="destructive">Failed</Badge>
|
||
</TableCell>
|
||
<TableCell>Credit Card</TableCell>
|
||
<TableCell className="text-right">$450.00</TableCell>
|
||
</TableRow>
|
||
</TableBody>
|
||
<TableFooter>
|
||
<TableRow>
|
||
<TableCell colSpan={3}>Total</TableCell>
|
||
<TableCell className="text-right">
|
||
$1,200.00
|
||
</TableCell>
|
||
</TableRow>
|
||
</TableFooter>
|
||
</Table>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">Compact Table</h4>
|
||
<div className="border rounded-lg overflow-hidden">
|
||
<Table>
|
||
<TableHeader>
|
||
<TableRow>
|
||
<TableHead>Product</TableHead>
|
||
<TableHead>Price</TableHead>
|
||
<TableHead>Stock</TableHead>
|
||
</TableRow>
|
||
</TableHeader>
|
||
<TableBody>
|
||
<TableRow>
|
||
<TableCell className="font-medium">
|
||
Vending Machine A
|
||
</TableCell>
|
||
<TableCell>$1,200.00</TableCell>
|
||
<TableCell>
|
||
<Badge variant="outline">In Stock</Badge>
|
||
</TableCell>
|
||
</TableRow>
|
||
<TableRow>
|
||
<TableCell className="font-medium">
|
||
Vending Machine B
|
||
</TableCell>
|
||
<TableCell>$950.00</TableCell>
|
||
<TableCell>
|
||
<Badge variant="secondary">Low Stock</Badge>
|
||
</TableCell>
|
||
</TableRow>
|
||
</TableBody>
|
||
</Table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="table-code"
|
||
code={`<Table>
|
||
<TableCaption>A list of recent invoices.</TableCaption>
|
||
<TableHeader>
|
||
<TableRow>
|
||
<TableHead className="w-[100px]">Invoice</TableHead>
|
||
<TableHead>Status</TableHead>
|
||
<TableHead className="text-right">Amount</TableHead>
|
||
</TableRow>
|
||
</TableHeader>
|
||
<TableBody>
|
||
<TableRow>
|
||
<TableCell className="font-medium">INV001</TableCell>
|
||
<TableCell>
|
||
<Badge variant="outline">Paid</Badge>
|
||
</TableCell>
|
||
<TableCell className="text-right">$250.00</TableCell>
|
||
</TableRow>
|
||
</TableBody>
|
||
<TableFooter>
|
||
<TableRow>
|
||
<TableCell colSpan={2}>Total</TableCell>
|
||
<TableCell className="text-right">$250.00</TableCell>
|
||
</TableRow>
|
||
</TableFooter>
|
||
</Table>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Empty State</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Empty state component for displaying helpful messages when
|
||
there's no content to show.
|
||
</p>
|
||
<Empty className="mb-6">
|
||
<EmptyMedia variant="icon">
|
||
<Package className="h-8 w-8" />
|
||
</EmptyMedia>
|
||
<EmptyHeader>
|
||
<EmptyTitle>No items found</EmptyTitle>
|
||
<EmptyDescription>
|
||
There are no items to display at this time.
|
||
</EmptyDescription>
|
||
</EmptyHeader>
|
||
<EmptyContent>
|
||
<Button>Add Item</Button>
|
||
</EmptyContent>
|
||
</Empty>
|
||
<CodeBlock
|
||
id="empty-code"
|
||
code={`<Empty>
|
||
<EmptyMedia variant="icon">
|
||
<Package className="h-8 w-8" />
|
||
</EmptyMedia>
|
||
<EmptyHeader>
|
||
<EmptyTitle>No items</EmptyTitle>
|
||
<EmptyDescription>Description</EmptyDescription>
|
||
</EmptyHeader>
|
||
<EmptyContent>
|
||
<Button>Action</Button>
|
||
</EmptyContent>
|
||
</Empty>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Keyboard (Kbd)</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Keyboard key indicator component for displaying keyboard
|
||
shortcuts and key combinations.
|
||
</p>
|
||
<div className="flex items-center gap-2 mb-6">
|
||
<Kbd>⌘</Kbd>
|
||
<span>+</span>
|
||
<Kbd>K</Kbd>
|
||
</div>
|
||
<CodeBlock id="kbd-code" code={`<Kbd>⌘</Kbd> + <Kbd>K</Kbd>`} />
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Charts & Graphs */}
|
||
<Section id="charts" title="Charts & Graphs">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Line Chart</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Line charts are perfect for showing trends over time.
|
||
</p>
|
||
<div className="mb-6">
|
||
<ChartContainer
|
||
config={lineChartConfig}
|
||
className="h-[300px] w-full"
|
||
>
|
||
<LineChart data={lineChartData}>
|
||
<CartesianGrid
|
||
strokeDasharray="3 3"
|
||
className="stroke-muted"
|
||
/>
|
||
<XAxis
|
||
dataKey="month"
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
tickFormatter={(value) => value.slice(0, 3)}
|
||
/>
|
||
<YAxis
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
tickFormatter={(value) => `${value}`}
|
||
/>
|
||
<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>
|
||
</div>
|
||
<CodeBlock
|
||
id="line-chart-code"
|
||
code={`import { LineChart, Line, XAxis, YAxis, CartesianGrid } from "recharts"
|
||
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
|
||
|
||
const chartConfig = {
|
||
desktop: { label: "Desktop", color: "#F79611" }, // Brand orange
|
||
mobile: { label: "Mobile", color: "#54595F" }, // Secondary gray
|
||
}
|
||
|
||
<ChartContainer config={chartConfig} className="h-[300px]">
|
||
<LineChart data={data}>
|
||
<CartesianGrid strokeDasharray="3 3" />
|
||
<XAxis dataKey="month" />
|
||
<YAxis />
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Line dataKey="desktop" stroke="var(--color-desktop)" />
|
||
<Line dataKey="mobile" stroke="var(--color-mobile)" />
|
||
</LineChart>
|
||
</ChartContainer>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Bar Chart</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Bar charts are great for comparing values across categories.
|
||
</p>
|
||
<div className="mb-6">
|
||
<ChartContainer
|
||
config={barChartConfig}
|
||
className="h-[300px] w-full"
|
||
>
|
||
<BarChart data={barChartData}>
|
||
<CartesianGrid
|
||
strokeDasharray="3 3"
|
||
className="stroke-muted"
|
||
/>
|
||
<XAxis
|
||
dataKey="month"
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
tickFormatter={(value) => value.slice(0, 3)}
|
||
/>
|
||
<YAxis
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
tickFormatter={(value) => `${value}`}
|
||
/>
|
||
<ChartTooltip
|
||
cursor={false}
|
||
content={<ChartTooltipContent />}
|
||
/>
|
||
<Bar
|
||
dataKey="desktop"
|
||
fill="var(--color-desktop)"
|
||
radius={4}
|
||
/>
|
||
<Bar
|
||
dataKey="mobile"
|
||
fill="var(--color-mobile)"
|
||
radius={4}
|
||
/>
|
||
</BarChart>
|
||
</ChartContainer>
|
||
</div>
|
||
<CodeBlock
|
||
id="bar-chart-code"
|
||
code={`import { BarChart, Bar, XAxis, YAxis, CartesianGrid } from "recharts"
|
||
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
|
||
|
||
const chartConfig = {
|
||
desktop: { label: "Desktop", color: "#F79611" }, // Brand orange
|
||
mobile: { label: "Mobile", color: "#54595F" }, // Secondary gray
|
||
}
|
||
|
||
<ChartContainer config={chartConfig} className="h-[300px]">
|
||
<BarChart data={data}>
|
||
<CartesianGrid strokeDasharray="3 3" />
|
||
<XAxis dataKey="month" />
|
||
<YAxis />
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
|
||
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
|
||
</BarChart>
|
||
</ChartContainer>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Area Chart</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Area charts show the magnitude of change over time, similar to
|
||
line charts but with filled areas.
|
||
</p>
|
||
<div className="mb-6">
|
||
<ChartContainer
|
||
config={areaChartConfig}
|
||
className="h-[300px] w-full"
|
||
>
|
||
<AreaChart data={areaChartData}>
|
||
<CartesianGrid
|
||
strokeDasharray="3 3"
|
||
className="stroke-muted"
|
||
/>
|
||
<XAxis
|
||
dataKey="month"
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
tickFormatter={(value) => value.slice(0, 3)}
|
||
/>
|
||
<YAxis
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
tickFormatter={(value) => `${value}`}
|
||
/>
|
||
<ChartTooltip
|
||
cursor={false}
|
||
content={<ChartTooltipContent />}
|
||
/>
|
||
<Area
|
||
dataKey="desktop"
|
||
type="monotone"
|
||
fill="var(--color-desktop)"
|
||
fillOpacity={0.4}
|
||
stroke="var(--color-desktop)"
|
||
strokeWidth={2}
|
||
/>
|
||
<Area
|
||
dataKey="mobile"
|
||
type="monotone"
|
||
fill="var(--color-mobile)"
|
||
fillOpacity={0.4}
|
||
stroke="var(--color-mobile)"
|
||
strokeWidth={2}
|
||
/>
|
||
</AreaChart>
|
||
</ChartContainer>
|
||
</div>
|
||
<CodeBlock
|
||
id="area-chart-code"
|
||
code={`import { AreaChart, Area, XAxis, YAxis, CartesianGrid } from "recharts"
|
||
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
|
||
|
||
const chartConfig = {
|
||
desktop: { label: "Desktop", color: "#F79611" }, // Brand orange
|
||
mobile: { label: "Mobile", color: "#54595F" }, // Secondary gray
|
||
}
|
||
|
||
<ChartContainer config={chartConfig} className="h-[300px]">
|
||
<AreaChart data={data}>
|
||
<CartesianGrid strokeDasharray="3 3" />
|
||
<XAxis dataKey="month" />
|
||
<YAxis />
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Area dataKey="desktop" fill="var(--color-desktop)" stroke="var(--color-desktop)" />
|
||
<Area dataKey="mobile" fill="var(--color-mobile)" stroke="var(--color-mobile)" />
|
||
</AreaChart>
|
||
</ChartContainer>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Pie Chart</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Pie charts are ideal for showing proportions and percentages of
|
||
a whole.
|
||
</p>
|
||
<div className="mb-6">
|
||
<ChartContainer
|
||
config={pieChartConfig}
|
||
className="h-[300px] w-full"
|
||
>
|
||
<PieChart>
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Pie
|
||
data={pieChartData}
|
||
dataKey="value"
|
||
nameKey="name"
|
||
cx="50%"
|
||
cy="50%"
|
||
outerRadius={80}
|
||
label
|
||
>
|
||
{pieChartData.map((entry, index) => (
|
||
<Cell key={`cell-${index}`} fill={entry.fill} />
|
||
))}
|
||
</Pie>
|
||
</PieChart>
|
||
</ChartContainer>
|
||
</div>
|
||
<CodeBlock
|
||
id="pie-chart-code"
|
||
code={`import { PieChart, Pie, Cell } from "recharts"
|
||
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
|
||
|
||
const data = [
|
||
{ name: "Desktop", value: 186, fill: "#F79611" }, // Brand orange
|
||
{ name: "Mobile", value: 80, fill: "#FCBA09" }, // Custom yellow
|
||
]
|
||
|
||
<ChartContainer config={chartConfig} className="h-[300px]">
|
||
<PieChart>
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Pie data={data} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={80}>
|
||
{data.map((entry, index) => (
|
||
<Cell key={\`cell-\${index}\`} fill={entry.fill} />
|
||
))}
|
||
</Pie>
|
||
</PieChart>
|
||
</ChartContainer>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Radar Chart</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Radar charts are useful for displaying multivariate data in a
|
||
way that makes it easy to compare multiple variables.
|
||
</p>
|
||
<div className="mb-6">
|
||
<ChartContainer
|
||
config={radarChartConfig}
|
||
className="h-[300px] w-full"
|
||
>
|
||
<RadarChart data={radarChartData}>
|
||
<PolarGrid />
|
||
<PolarAngleAxis dataKey="subject" />
|
||
<PolarRadiusAxis angle={90} domain={[0, 150]} />
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Radar
|
||
name="Student A"
|
||
dataKey="A"
|
||
stroke="var(--color-A)"
|
||
fill="var(--color-A)"
|
||
fillOpacity={0.6}
|
||
/>
|
||
<Radar
|
||
name="Student B"
|
||
dataKey="B"
|
||
stroke="var(--color-B)"
|
||
fill="var(--color-B)"
|
||
fillOpacity={0.6}
|
||
/>
|
||
</RadarChart>
|
||
</ChartContainer>
|
||
</div>
|
||
<CodeBlock
|
||
id="radar-chart-code"
|
||
code={`import { RadarChart, Radar, PolarGrid, PolarAngleAxis, PolarRadiusAxis } from "recharts"
|
||
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
|
||
|
||
const chartConfig = {
|
||
A: { label: "Student A", color: "#F79611" }, // Brand orange
|
||
B: { label: "Student B", color: "#54595F" }, // Secondary gray
|
||
}
|
||
|
||
<ChartContainer config={chartConfig} className="h-[300px]">
|
||
<RadarChart data={data}>
|
||
<PolarGrid />
|
||
<PolarAngleAxis dataKey="subject" />
|
||
<PolarRadiusAxis />
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Radar dataKey="A" stroke="var(--color-A)" fill="var(--color-A)" fillOpacity={0.6} />
|
||
<Radar dataKey="B" stroke="var(--color-B)" fill="var(--color-B)" fillOpacity={0.6} />
|
||
</RadarChart>
|
||
</ChartContainer>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Composed Chart</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Composed charts combine multiple chart types (like bars and
|
||
lines) in a single visualization.
|
||
</p>
|
||
<div className="mb-6">
|
||
<ChartContainer
|
||
config={lineChartConfig}
|
||
className="h-[300px] w-full"
|
||
>
|
||
<ComposedChart data={lineChartData}>
|
||
<CartesianGrid
|
||
strokeDasharray="3 3"
|
||
className="stroke-muted"
|
||
/>
|
||
<XAxis
|
||
dataKey="month"
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
tickFormatter={(value) => value.slice(0, 3)}
|
||
/>
|
||
<YAxis
|
||
yAxisId="left"
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
/>
|
||
<YAxis
|
||
yAxisId="right"
|
||
orientation="right"
|
||
tickLine={false}
|
||
axisLine={false}
|
||
tickMargin={8}
|
||
/>
|
||
<ChartTooltip
|
||
cursor={false}
|
||
content={<ChartTooltipContent />}
|
||
/>
|
||
<Bar
|
||
yAxisId="left"
|
||
dataKey="desktop"
|
||
fill="var(--color-desktop)"
|
||
radius={4}
|
||
/>
|
||
<Line
|
||
yAxisId="right"
|
||
type="monotone"
|
||
dataKey="mobile"
|
||
stroke="var(--color-mobile)"
|
||
strokeWidth={2}
|
||
dot={false}
|
||
/>
|
||
</ComposedChart>
|
||
</ChartContainer>
|
||
</div>
|
||
<CodeBlock
|
||
id="composed-chart-code"
|
||
code={`import { ComposedChart, Bar, Line, XAxis, YAxis, CartesianGrid } from "recharts"
|
||
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
|
||
|
||
const chartConfig = {
|
||
desktop: { label: "Desktop", color: "#F79611" }, // Brand orange
|
||
mobile: { label: "Mobile", color: "#54595F" }, // Secondary gray
|
||
}
|
||
|
||
<ChartContainer config={chartConfig} className="h-[300px]">
|
||
<ComposedChart data={data}>
|
||
<CartesianGrid strokeDasharray="3 3" />
|
||
<XAxis dataKey="month" />
|
||
<YAxis yAxisId="left" />
|
||
<YAxis yAxisId="right" orientation="right" />
|
||
<ChartTooltip content={<ChartTooltipContent />} />
|
||
<Bar yAxisId="left" dataKey="desktop" fill="var(--color-desktop)" />
|
||
<Line yAxisId="right" type="monotone" dataKey="mobile" stroke="var(--color-mobile)" />
|
||
</ComposedChart>
|
||
</ChartContainer>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Interactive Components */}
|
||
<Section id="interactive" title="Interactive Components">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Switch</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Toggle switch component for binary on/off settings. More
|
||
visually distinct than checkboxes for important settings.
|
||
</p>
|
||
<div className="flex items-center space-x-2 mb-6">
|
||
<Switch id="switch-example" />
|
||
<Label htmlFor="switch-example">Enable notifications</Label>
|
||
</div>
|
||
<CodeBlock
|
||
id="switch-code"
|
||
code={`<div className="flex items-center space-x-2">
|
||
<Switch id="switch" />
|
||
<Label htmlFor="switch">Label</Label>
|
||
</div>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Slider</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Slider component for selecting a value from a range. Supports
|
||
single value or range selection with customizable steps.
|
||
</p>
|
||
<div className="space-y-4 mb-6 max-w-md">
|
||
<Slider defaultValue={[50]} max={100} step={1} />
|
||
<Slider defaultValue={[25, 75]} max={100} step={1} />
|
||
</div>
|
||
<CodeBlock
|
||
id="slider-code"
|
||
code={`<Slider defaultValue={[50]} max={100} step={1} />
|
||
<Slider defaultValue={[25, 75]} max={100} step={1} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Toggle</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Toggle button component that can be pressed to toggle a state.
|
||
Useful for toolbar buttons and inline formatting controls.
|
||
</p>
|
||
<div className="flex items-center gap-4 mb-6">
|
||
<Toggle aria-label="Toggle italic">
|
||
<span>Bold</span>
|
||
</Toggle>
|
||
<Toggle variant="outline" aria-label="Toggle italic">
|
||
<span>Italic</span>
|
||
</Toggle>
|
||
</div>
|
||
<CodeBlock
|
||
id="toggle-code"
|
||
code={`<Toggle aria-label="Toggle">
|
||
<span>Bold</span>
|
||
</Toggle>
|
||
<Toggle variant="outline">
|
||
<span>Italic</span>
|
||
</Toggle>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Toggle Group</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Group of toggle buttons that work together. Supports single
|
||
selection (radio-like) or multiple selection (checkbox-like).
|
||
</p>
|
||
<ToggleGroup type="single" defaultValue="center" className="mb-6">
|
||
<ToggleGroupItem value="left" aria-label="Left aligned">
|
||
<span>Left</span>
|
||
</ToggleGroupItem>
|
||
<ToggleGroupItem value="center" aria-label="Center aligned">
|
||
<span>Center</span>
|
||
</ToggleGroupItem>
|
||
<ToggleGroupItem value="right" aria-label="Right aligned">
|
||
<span>Right</span>
|
||
</ToggleGroupItem>
|
||
</ToggleGroup>
|
||
<CodeBlock
|
||
id="toggle-group-code"
|
||
code={`<ToggleGroup type="single" defaultValue="center">
|
||
<ToggleGroupItem value="left">Left</ToggleGroupItem>
|
||
<ToggleGroupItem value="center">Center</ToggleGroupItem>
|
||
<ToggleGroupItem value="right">Right</ToggleGroupItem>
|
||
</ToggleGroup>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Collapsible</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Collapsible content component for showing and hiding content.
|
||
Similar to accordion but without the accordion styling.
|
||
</p>
|
||
<Collapsible className="mb-6">
|
||
<CollapsibleTrigger asChild>
|
||
<Button variant="outline">Toggle</Button>
|
||
</CollapsibleTrigger>
|
||
<CollapsibleContent className="mt-2 p-4 border rounded-md">
|
||
<p className="text-sm text-muted-foreground">
|
||
This is collapsible content that can be shown or hidden.
|
||
</p>
|
||
</CollapsibleContent>
|
||
</Collapsible>
|
||
<CodeBlock
|
||
id="collapsible-code"
|
||
code={`<Collapsible>
|
||
<CollapsibleTrigger asChild>
|
||
<Button>Toggle</Button>
|
||
</CollapsibleTrigger>
|
||
<CollapsibleContent>
|
||
<p>Content</p>
|
||
</CollapsibleContent>
|
||
</Collapsible>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Layout Components */}
|
||
<Section id="layout" title="Layout Components">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Aspect Ratio</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Aspect ratio component for maintaining consistent image and
|
||
video dimensions. Prevents layout shift during loading.
|
||
</p>
|
||
<div className="max-w-md mb-6">
|
||
<AspectRatio
|
||
ratio={16 / 9}
|
||
className="bg-muted rounded-lg overflow-hidden"
|
||
>
|
||
<div className="flex items-center justify-center h-full text-muted-foreground">
|
||
16:9 Aspect Ratio
|
||
</div>
|
||
</AspectRatio>
|
||
</div>
|
||
<CodeBlock
|
||
id="aspect-ratio-component-code"
|
||
code={`<AspectRatio ratio={16 / 9} className="bg-muted">
|
||
<Image src="/image.jpg" alt="Description" fill className="object-cover" />
|
||
</AspectRatio>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Scroll Area</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Custom scrollable area component with styled scrollbars.
|
||
Provides consistent cross-browser scrolling behavior.
|
||
</p>
|
||
<ScrollArea className="h-32 w-full border rounded-md p-4 mb-6">
|
||
<div className="space-y-2">
|
||
{Array.from({ length: 10 }).map((_, i) => (
|
||
<p key={i} className="text-sm">
|
||
Item {i + 1}
|
||
</p>
|
||
))}
|
||
</div>
|
||
</ScrollArea>
|
||
<CodeBlock
|
||
id="scroll-area-code"
|
||
code={`<ScrollArea className="h-32 w-full">
|
||
<div>Content that scrolls</div>
|
||
</ScrollArea>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Resizable Panels</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Resizable panel group for creating adjustable layouts. Users can
|
||
drag to resize panels horizontally or vertically.
|
||
</p>
|
||
<ResizablePanelGroup
|
||
direction="horizontal"
|
||
className="max-w-md border rounded-lg mb-6"
|
||
>
|
||
<ResizablePanel defaultSize={50}>
|
||
<div className="flex h-[200px] items-center justify-center p-6">
|
||
<span className="font-semibold">Panel 1</span>
|
||
</div>
|
||
</ResizablePanel>
|
||
<ResizableHandle />
|
||
<ResizablePanel defaultSize={50}>
|
||
<div className="flex h-[200px] items-center justify-center p-6">
|
||
<span className="font-semibold">Panel 2</span>
|
||
</div>
|
||
</ResizablePanel>
|
||
</ResizablePanelGroup>
|
||
<CodeBlock
|
||
id="resizable-code"
|
||
code={`<ResizablePanelGroup direction="horizontal">
|
||
<ResizablePanel defaultSize={50}>
|
||
<div>Panel 1</div>
|
||
</ResizablePanel>
|
||
<ResizableHandle />
|
||
<ResizablePanel defaultSize={50}>
|
||
<div>Panel 2</div>
|
||
</ResizablePanel>
|
||
</ResizablePanelGroup>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Advanced Components */}
|
||
<Section id="advanced" title="Advanced Components">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Carousel</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Carousel component for displaying a set of items in a scrollable
|
||
container. Supports multiple items per view, navigation arrows,
|
||
and autoplay.
|
||
</p>
|
||
<div className="space-y-8 mb-6">
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">
|
||
Single Item Carousel
|
||
</h4>
|
||
<Carousel className="w-full max-w-xs mx-auto">
|
||
<CarouselContent>
|
||
{Array.from({ length: 5 }).map((_, index) => (
|
||
<CarouselItem key={index}>
|
||
<div className="p-1">
|
||
<Card>
|
||
<CardContent className="flex aspect-square items-center justify-center p-6">
|
||
<span className="text-4xl font-semibold">
|
||
{index + 1}
|
||
</span>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</CarouselItem>
|
||
))}
|
||
</CarouselContent>
|
||
<CarouselPrevious />
|
||
<CarouselNext />
|
||
</Carousel>
|
||
</div>
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">
|
||
Multiple Items Carousel
|
||
</h4>
|
||
<Carousel
|
||
opts={{
|
||
align: "start",
|
||
}}
|
||
className="w-full max-w-5xl mx-auto"
|
||
>
|
||
<CarouselContent>
|
||
{Array.from({ length: 10 }).map((_, index) => (
|
||
<CarouselItem
|
||
key={index}
|
||
className="md:basis-1/2 lg:basis-1/3"
|
||
>
|
||
<div className="p-1">
|
||
<Card>
|
||
<CardContent className="flex aspect-square items-center justify-center p-6">
|
||
<span className="text-2xl font-semibold">
|
||
Item {index + 1}
|
||
</span>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</CarouselItem>
|
||
))}
|
||
</CarouselContent>
|
||
<CarouselPrevious />
|
||
<CarouselNext />
|
||
</Carousel>
|
||
</div>
|
||
<div>
|
||
<h4 className="text-sm font-medium mb-2">Image Carousel</h4>
|
||
<Carousel className="w-full max-w-2xl mx-auto">
|
||
<CarouselContent>
|
||
{Array.from({ length: 4 }).map((_, index) => (
|
||
<CarouselItem key={index}>
|
||
<div className="p-1">
|
||
<Card>
|
||
<CardContent className="flex aspect-video items-center justify-center p-6 bg-muted">
|
||
<div className="text-center">
|
||
<div className="text-6xl mb-2">🖼️</div>
|
||
<p className="text-sm text-muted-foreground">
|
||
Image {index + 1}
|
||
</p>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</CarouselItem>
|
||
))}
|
||
</CarouselContent>
|
||
<CarouselPrevious />
|
||
<CarouselNext />
|
||
</Carousel>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="carousel-code"
|
||
code={`<Carousel className="w-full max-w-xs">
|
||
<CarouselContent>
|
||
<CarouselItem>
|
||
<div className="p-1">
|
||
<Card>
|
||
<CardContent>Item 1</CardContent>
|
||
</Card>
|
||
</div>
|
||
</CarouselItem>
|
||
<CarouselItem>
|
||
<div className="p-1">
|
||
<Card>
|
||
<CardContent>Item 2</CardContent>
|
||
</Card>
|
||
</div>
|
||
</CarouselItem>
|
||
</CarouselContent>
|
||
<CarouselPrevious />
|
||
<CarouselNext />
|
||
</Carousel>
|
||
|
||
// Multiple items per view
|
||
<Carousel opts={{ align: "start" }} className="w-full">
|
||
<CarouselContent>
|
||
<CarouselItem className="md:basis-1/2 lg:basis-1/3">
|
||
{/* Item */}
|
||
</CarouselItem>
|
||
</CarouselContent>
|
||
<CarouselPrevious />
|
||
<CarouselNext />
|
||
</Carousel>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Calendar</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Calendar component for date selection. Supports single date,
|
||
date range, and multiple date selection modes.
|
||
</p>
|
||
<div className="max-w-fit mb-6">
|
||
<Calendar mode="single" className="rounded-md border" />
|
||
</div>
|
||
<CodeBlock
|
||
id="calendar-code"
|
||
code={`<Calendar mode="single" className="rounded-md border" />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Input OTP</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
One-time password input component with individual slots for each
|
||
digit. Perfect for verification codes.
|
||
</p>
|
||
<div className="mb-6">
|
||
<InputOTP maxLength={6}>
|
||
<InputOTPGroup>
|
||
<InputOTPSlot index={0} />
|
||
<InputOTPSlot index={1} />
|
||
<InputOTPSlot index={2} />
|
||
<InputOTPSlot index={3} />
|
||
<InputOTPSlot index={4} />
|
||
<InputOTPSlot index={5} />
|
||
</InputOTPGroup>
|
||
</InputOTP>
|
||
</div>
|
||
<CodeBlock
|
||
id="input-otp-code"
|
||
code={`<InputOTP maxLength={6}>
|
||
<InputOTPGroup>
|
||
<InputOTPSlot index={0} />
|
||
<InputOTPSlot index={1} />
|
||
<InputOTPSlot index={2} />
|
||
</InputOTPGroup>
|
||
</InputOTP>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Command Palette</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Command palette component for quick actions and search. Similar
|
||
to VS Code's command palette, accessible via keyboard shortcut.
|
||
</p>
|
||
<Command className="rounded-lg border shadow-md max-w-md mb-6">
|
||
<CommandInput placeholder="Type a command or search..." />
|
||
<CommandList>
|
||
<CommandEmpty>No results found.</CommandEmpty>
|
||
<CommandGroup heading="Suggestions">
|
||
<CommandItem>
|
||
<span>Calendar</span>
|
||
</CommandItem>
|
||
<CommandItem>
|
||
<span>Search Emoji</span>
|
||
</CommandItem>
|
||
<CommandItem>
|
||
<span>Calculator</span>
|
||
</CommandItem>
|
||
</CommandGroup>
|
||
</CommandList>
|
||
</Command>
|
||
<CodeBlock
|
||
id="command-code"
|
||
code={`<Command>
|
||
<CommandInput placeholder="Search..." />
|
||
<CommandList>
|
||
<CommandEmpty>No results</CommandEmpty>
|
||
<CommandGroup heading="Items">
|
||
<CommandItem>Item 1</CommandItem>
|
||
</CommandGroup>
|
||
</CommandList>
|
||
</Command>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Spacing & Layout */}
|
||
<Section id="spacing" title="Spacing & Layout">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Container Patterns</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Standard container patterns for page layouts with consistent
|
||
max-widths and padding.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<Card className="border-border/50">
|
||
<CardContent className="p-6">
|
||
<div className="bg-muted/50 p-4 rounded">
|
||
<p className="text-sm font-mono mb-2">
|
||
Standard: container mx-auto px-4 py-8 md:py-12 max-w-4xl
|
||
</p>
|
||
<p className="text-xs text-muted-foreground">
|
||
Used for most content pages
|
||
</p>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
<Card className="border-border/50">
|
||
<CardContent className="p-6">
|
||
<div className="bg-muted/50 p-4 rounded">
|
||
<p className="text-sm font-mono mb-2">
|
||
Wide: container mx-auto px-4 py-8 md:py-12 max-w-6xl
|
||
</p>
|
||
<p className="text-xs text-muted-foreground">
|
||
Used for wider content layouts
|
||
</p>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
<Card className="border-border/50">
|
||
<CardContent className="p-6">
|
||
<div className="bg-muted/50 p-4 rounded">
|
||
<p className="text-sm font-mono mb-2">
|
||
Full-width: container mx-auto px-4 py-8 md:py-12
|
||
</p>
|
||
<p className="text-xs text-muted-foreground">
|
||
No max-width constraint
|
||
</p>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Section Padding</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Standard vertical padding patterns for sections. Responsive
|
||
padding increases on larger screens.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<div className="bg-muted/30 py-20 md:py-28 rounded-lg border border-border">
|
||
<p className="text-center text-sm font-mono">
|
||
py-20 md:py-28 (Standard sections)
|
||
</p>
|
||
</div>
|
||
<div className="bg-muted/30 py-16 md:py-24 rounded-lg border border-border">
|
||
<p className="text-center text-sm font-mono">
|
||
py-16 md:py-24 (Compact sections)
|
||
</p>
|
||
</div>
|
||
<div className="bg-muted/30 py-20 md:py-32 rounded-lg border border-border">
|
||
<p className="text-center text-sm font-mono">
|
||
py-20 md:py-32 (Hero sections)
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Grid Layouts</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Responsive grid layouts that adapt from single column on mobile
|
||
to multiple columns on larger screens.
|
||
</p>
|
||
<div className="space-y-6 mb-6">
|
||
<div className="grid gap-4 md:grid-cols-2">
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">
|
||
2 columns
|
||
</div>
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">
|
||
2 columns
|
||
</div>
|
||
</div>
|
||
<div className="grid gap-4 md:grid-cols-3">
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">
|
||
3 columns
|
||
</div>
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">
|
||
3 columns
|
||
</div>
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">
|
||
3 columns
|
||
</div>
|
||
</div>
|
||
<div className="grid gap-4 md:grid-cols-4">
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">
|
||
4 columns
|
||
</div>
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">
|
||
4 columns
|
||
</div>
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">
|
||
4 columns
|
||
</div>
|
||
<div className="bg-muted/50 p-4 rounded text-center text-sm">
|
||
4 columns
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="grid-code"
|
||
code={`<div className="grid gap-4 md:grid-cols-2">2 columns</div>
|
||
<div className="grid gap-4 md:grid-cols-3">3 columns</div>
|
||
<div className="grid gap-4 md:grid-cols-4">4 columns</div>`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
|
||
{/* Image Patterns */}
|
||
<Section id="images" title="Image Patterns">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Aspect Ratios</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Common aspect ratio patterns for images and media. Ensures
|
||
consistent sizing and prevents layout shift.
|
||
</p>
|
||
<div className="grid gap-6 md:grid-cols-3 mb-6">
|
||
<Card className="border-border/50 overflow-hidden">
|
||
<div className="aspect-square relative bg-muted">
|
||
<div className="absolute inset-0 flex items-center justify-center text-muted-foreground text-sm">
|
||
Square (aspect-square)
|
||
</div>
|
||
</div>
|
||
<CardContent className="p-4">
|
||
<p className="text-xs text-muted-foreground">1:1 Ratio</p>
|
||
</CardContent>
|
||
</Card>
|
||
<Card className="border-border/50 overflow-hidden">
|
||
<div className="aspect-video relative bg-muted">
|
||
<div className="absolute inset-0 flex items-center justify-center text-muted-foreground text-sm">
|
||
Video (aspect-video)
|
||
</div>
|
||
</div>
|
||
<CardContent className="p-4">
|
||
<p className="text-xs text-muted-foreground">16:9 Ratio</p>
|
||
</CardContent>
|
||
</Card>
|
||
<Card className="border-border/50 overflow-hidden">
|
||
<div className="aspect-[4/3] relative bg-muted">
|
||
<div className="absolute inset-0 flex items-center justify-center text-muted-foreground text-sm">
|
||
Custom (aspect-[4/3])
|
||
</div>
|
||
</div>
|
||
<CardContent className="p-4">
|
||
<p className="text-xs text-muted-foreground">4:3 Ratio</p>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
<CodeBlock
|
||
id="aspect-ratio-code"
|
||
code={`<div className="aspect-square relative bg-muted">
|
||
<Image src="/image.jpg" alt="Description" fill className="object-cover" />
|
||
</div>
|
||
|
||
<div className="aspect-video relative bg-muted">
|
||
<Image src="/image.jpg" alt="Description" fill className="object-cover" />
|
||
</div>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">
|
||
Image Sizing Standards
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Recommended maximum image dimensions for optimal performance.
|
||
Grid/card images: 300px, full-width: 600px.
|
||
</p>
|
||
<div className="space-y-4 mb-6">
|
||
<Card className="border-border/50">
|
||
<CardContent className="p-6">
|
||
<p className="text-sm font-semibold mb-2">
|
||
Grid/Card Images
|
||
</p>
|
||
<p className="text-xs text-muted-foreground mb-4">
|
||
Maximum 300px per dimension
|
||
</p>
|
||
<div className="max-w-xs mx-auto">
|
||
<div className="relative w-full overflow-hidden rounded-lg bg-muted shadow-sm aspect-square">
|
||
<div className="absolute inset-0 flex items-center justify-center text-xs text-muted-foreground">
|
||
Max 300px
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
<Card className="border-border/50">
|
||
<CardContent className="p-6">
|
||
<p className="text-sm font-semibold mb-2">
|
||
Full-width Images
|
||
</p>
|
||
<p className="text-xs text-muted-foreground mb-4">
|
||
Maximum 600px per dimension
|
||
</p>
|
||
<div className="max-w-md mx-auto">
|
||
<div className="relative w-full overflow-hidden rounded-lg bg-muted shadow-sm aspect-video">
|
||
<div className="absolute inset-0 flex items-center justify-center text-xs text-muted-foreground">
|
||
Max 600px
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
<Separator className="my-12" />
|
||
</div>
|
||
|
||
{/* Home Page Sections - Full Width */}
|
||
<section id="sections" className="scroll-mt-24">
|
||
<div className="container mx-auto px-4 max-w-7xl py-12 md:py-16">
|
||
<h2 className="text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl mb-8 text-balance border-b border-border pb-4">
|
||
Home Page Sections
|
||
</h2>
|
||
<p className="text-sm text-muted-foreground mb-8">
|
||
These sections are displayed at full width, matching the homepage
|
||
layout. Each section has its own background and internal container.
|
||
</p>
|
||
</div>
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6">
|
||
<h3 className="text-xl font-semibold mb-2">Hero Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
The hero section includes a badge, main heading, description,
|
||
feature list, and CTA buttons.
|
||
</p>
|
||
</div>
|
||
<HeroSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">Stats Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Displays key statistics in a grid layout with large numbers.
|
||
</p>
|
||
</div>
|
||
<StatsSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">Features Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Shows key features with icons in a card grid layout.
|
||
</p>
|
||
</div>
|
||
<FeaturesSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">
|
||
Product Showcase Section
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Displays products with images in a card grid.
|
||
</p>
|
||
</div>
|
||
<ProductShowcaseSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">How It Works Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Step-by-step process cards with numbered indicators.
|
||
</p>
|
||
</div>
|
||
<HowItWorksSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">Services Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Service offerings with images and lists.
|
||
</p>
|
||
</div>
|
||
<ServicesSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">Service Areas Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Displays service area map and city listings.
|
||
</p>
|
||
</div>
|
||
<ServiceAreasSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">Reviews Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Customer reviews with rating badge.
|
||
</p>
|
||
</div>
|
||
<ReviewsSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">
|
||
Request Machine Section
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
CTA section with embedded form.
|
||
</p>
|
||
</div>
|
||
<RequestMachineSection />
|
||
|
||
<div className="container mx-auto px-4 max-w-7xl mb-6 mt-12">
|
||
<h3 className="text-xl font-semibold mb-2">Contact Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Contact information and detailed contact form.
|
||
</p>
|
||
</div>
|
||
<ContactSection />
|
||
</section>
|
||
|
||
<div className="container mx-auto px-4 py-8 md:py-12 max-w-7xl">
|
||
{/* Custom Components */}
|
||
<Section id="custom" title="Custom Components">
|
||
<div className="space-y-8">
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">
|
||
Benefits/Features Section
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Grid layout for displaying benefits or features with icons.
|
||
Commonly used on service pages.
|
||
</p>
|
||
<div className="mb-6">
|
||
<div className="text-center mb-12 md:mb-16">
|
||
<h2 className="text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl mb-4 text-balance">
|
||
Why Choose Us?
|
||
</h2>
|
||
<p className="text-lg text-muted-foreground max-w-2xl mx-auto text-pretty leading-relaxed">
|
||
We provide comprehensive solutions tailored to your specific
|
||
needs
|
||
</p>
|
||
</div>
|
||
<div className="grid gap-6 md:grid-cols-2">
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2 text-foreground">
|
||
100% FREE Service
|
||
</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
No upfront costs, installation fees, or monthly charges
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2 text-foreground">
|
||
Regular Maintenance
|
||
</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
We stock, service, and maintain all machines at no cost
|
||
to you
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2 text-foreground">
|
||
Modern Technology
|
||
</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
Cashless payment options and state-of-the-art equipment
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2 text-foreground">
|
||
Local Support
|
||
</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
Family-owned business with dedicated local customer
|
||
service
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="benefits-section-code"
|
||
code={`<div className="text-center mb-12 md:mb-16">
|
||
<h2 className="text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl mb-4 text-balance">
|
||
Why Choose Us?
|
||
</h2>
|
||
<p className="text-lg text-muted-foreground max-w-2xl mx-auto text-pretty leading-relaxed">
|
||
Description text
|
||
</p>
|
||
</div>
|
||
|
||
<div className="grid gap-6 md:grid-cols-2">
|
||
<div className="flex items-start gap-4">
|
||
<div className="flex-shrink-0 w-6 h-6 mt-1">
|
||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="font-semibold text-xl mb-2 text-foreground">Feature Title</h3>
|
||
<p className="text-muted-foreground leading-relaxed">
|
||
Feature description text
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">
|
||
Prose Content Styling
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Styling for rich text content from CMS or markdown, commonly
|
||
used for page content.
|
||
</p>
|
||
<div className="mb-6">
|
||
<div className="prose prose-lg max-w-none prose-headings:text-foreground prose-p:text-muted-foreground prose-a:text-foreground prose-a:transition-colors">
|
||
<div className="text-foreground leading-relaxed space-y-6 text-base md:text-lg">
|
||
<p>
|
||
This is a paragraph with proper styling. It uses the prose
|
||
classes to ensure consistent typography throughout the
|
||
content area. Links will automatically get the hover color
|
||
treatment.
|
||
</p>
|
||
<h2>This is a Heading 2</h2>
|
||
<p>
|
||
Another paragraph with some{" "}
|
||
<a href="#custom">linked text</a> that will have the
|
||
proper hover styling.
|
||
</p>
|
||
<ul>
|
||
<li>List item one</li>
|
||
<li>List item two</li>
|
||
<li>List item three</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<CodeBlock
|
||
id="prose-content-code"
|
||
code={`<div className="prose prose-lg max-w-none prose-headings:text-foreground prose-p:text-muted-foreground prose-a:text-foreground prose-a:transition-colors">
|
||
<div className="text-foreground leading-relaxed space-y-6 text-base md:text-lg">
|
||
{/* Your content here - can be from CMS, markdown, etc. */}
|
||
<p>Paragraph text</p>
|
||
<h2>Heading</h2>
|
||
<ul>
|
||
<li>List item</li>
|
||
</ul>
|
||
</div>
|
||
</div>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Product Card</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Custom component for displaying products with image, title,
|
||
description, and price.
|
||
</p>
|
||
<CodeBlock
|
||
id="product-card-code"
|
||
code={`import { ProductCard } from "@/components/product-card"
|
||
|
||
<ProductCard
|
||
id="product-id"
|
||
name="Product Name"
|
||
description="Product description"
|
||
price={29.99}
|
||
image="/product-image.jpg"
|
||
/>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">
|
||
Vending Machine Card
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Custom component for displaying vending machine information.
|
||
</p>
|
||
<CodeBlock
|
||
id="vending-machine-card-code"
|
||
code={`import { VendingMachineCard } from "@/components/vending-machine-card"
|
||
|
||
<VendingMachineCard
|
||
name="Machine Name"
|
||
description="Machine description"
|
||
image="/machine-image.jpg"
|
||
/>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Animated Number</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Component that animates numbers when they come into view.
|
||
</p>
|
||
<CodeBlock
|
||
id="animated-number-code"
|
||
code={`import { AnimatedNumber } from "@/components/animated-number"
|
||
|
||
<AnimatedNumber value={100} duration={2000} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Breadcrumbs</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Custom breadcrumb navigation component.
|
||
</p>
|
||
<CodeBlock
|
||
id="breadcrumbs-custom-code"
|
||
code={`import { Breadcrumbs } from "@/components/breadcrumbs"
|
||
|
||
<Breadcrumbs items={[
|
||
{ label: "Home", href: "/" },
|
||
{ label: "Products", href: "/products" },
|
||
{ label: "Current Page" }
|
||
]} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">FAQ Section</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Custom FAQ section component with accordion functionality.
|
||
</p>
|
||
<CodeBlock
|
||
id="faq-section-code"
|
||
code={`import { FAQSection } from "@/components/faq-section"
|
||
|
||
<FAQSection
|
||
faqs={[
|
||
{ question: "Question 1?", answer: "Answer 1" },
|
||
{ question: "Question 2?", answer: "Answer 2" }
|
||
]}
|
||
/>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Header Component</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Main site header with navigation, cart, and mobile menu. Note:
|
||
Header is already included in the root layout, so it appears at
|
||
the top of every page.
|
||
</p>
|
||
<CodeBlock
|
||
id="header-code"
|
||
code={`import { Header } from "@/components/header"
|
||
|
||
// Header is typically included in the root layout
|
||
<Header />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Footer Component</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Site footer with links, contact info, and social media. Note:
|
||
Footer is already included in the root layout, so it appears at
|
||
the bottom of every page.
|
||
</p>
|
||
<CodeBlock
|
||
id="footer-code"
|
||
code={`import { Footer } from "@/components/footer"
|
||
|
||
// Footer is typically included in the root layout
|
||
<Footer />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">
|
||
Get Free Machine Modal
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Modal dialog for requesting a free vending machine with embedded
|
||
form.
|
||
</p>
|
||
<CodeBlock
|
||
id="get-free-machine-modal-code"
|
||
code={`import { GetFreeMachineModal } from "@/components/get-free-machine-modal"
|
||
|
||
<GetFreeMachineModal open={isOpen} onOpenChange={setIsOpen} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Cart Components</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Shopping cart system with cart button, mobile cart button, and
|
||
cart sheet.
|
||
</p>
|
||
<div className="flex gap-4 mb-6">
|
||
<CartButton onClick={() => {}} />
|
||
<MobileCartButton onClick={() => {}} />
|
||
</div>
|
||
<CodeBlock
|
||
id="cart-components-code"
|
||
code={`import { Cart, CartButton, MobileCartButton } from "@/components/cart"
|
||
|
||
<CartButton onClick={handleCartClick} />
|
||
<MobileCartButton onClick={handleCartClick} />
|
||
<Cart isOpen={isCartOpen} onClose={() => setIsCartOpen(false)} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Product Grid</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Grid layout component for displaying products.
|
||
</p>
|
||
<CodeBlock
|
||
id="product-grid-code"
|
||
code={`import { ProductGrid } from "@/components/product-grid"
|
||
|
||
<ProductGrid products={products} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">
|
||
Vending Machines Showcase
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Showcase component displaying vending machines in a grid.
|
||
</p>
|
||
<div className="mb-6">
|
||
<VendingMachinesShowcase />
|
||
</div>
|
||
<CodeBlock
|
||
id="vending-machines-showcase-code"
|
||
code={`import { VendingMachinesShowcase } from "@/components/vending-machines-showcase"
|
||
|
||
<VendingMachinesShowcase />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Feature Card</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Reusable card component for displaying features with image,
|
||
title, and description. Used in a grid layout for multiple
|
||
features.
|
||
</p>
|
||
<div className="mb-6 grid md:grid-cols-2 gap-6">
|
||
<FeatureCard
|
||
image="https://rockymountainvending.com/wp-content/uploads/2024/01/Parlevel-Pay-Plus-247x300.jpg"
|
||
alt="Parlevel PayPlus credit card reader screen showing options for inserting, swiping, or tapping a card for payment."
|
||
title="Credit Card Readers"
|
||
description="Enhanced Payment Flexibility: Our vending machines are equipped with advanced NAYAX and Parlevel credit card readers, seamlessly integrated with Parlevel's Vending Management System (VMS). These cutting-edge readers use EMV chip technology to enhance transaction security, offering users greater peace of mind."
|
||
imageWidth={247}
|
||
imageHeight={300}
|
||
/>
|
||
<FeatureCard
|
||
image="https://rockymountainvending.com/wp-content/uploads/2024/10/Drop-Sensors-300x225.webp"
|
||
alt="Illustration of a vending machine drop sensor ensuring successful item delivery."
|
||
title="Guaranteed Delivery"
|
||
description="Purchase with Confidence: Our vending machines are equipped with highly sensitive sensors that ensure you receive the item you select. In the rare case that a product isn't dispensed, the machine is designed either to prevent the charge or to issue a prompt refund."
|
||
imageWidth={300}
|
||
imageHeight={225}
|
||
/>
|
||
</div>
|
||
<CodeBlock
|
||
id="feature-card-code"
|
||
code={`import { FeatureCard } from "@/components/feature-card"
|
||
|
||
<div className="grid md:grid-cols-2 gap-6">
|
||
<FeatureCard
|
||
image="/path/to/image.jpg"
|
||
alt="Image description"
|
||
title="Feature Title"
|
||
description="Feature description text here."
|
||
imageWidth={247}
|
||
imageHeight={300}
|
||
/>
|
||
</div>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">
|
||
Credit Card Reader Section
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Section component displaying credit card reader information with
|
||
image and description. Uses FeatureCard internally.
|
||
</p>
|
||
<div className="mb-6">
|
||
<CreditCardReaderSection />
|
||
</div>
|
||
<CodeBlock
|
||
id="credit-card-reader-section-code"
|
||
code={`import { CreditCardReaderSection } from "@/components/credit-card-reader-section"
|
||
|
||
<CreditCardReaderSection />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Manual Viewer</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
PDF manual viewer with parts panel integration.
|
||
</p>
|
||
<CodeBlock
|
||
id="manual-viewer-code"
|
||
code={`import { ManualViewer } from "@/components/manual-viewer"
|
||
|
||
<ManualViewer
|
||
manualUrl="/path/to/manual.pdf"
|
||
filename="manual.pdf"
|
||
isOpen={isOpen}
|
||
onClose={() => setIsOpen(false)}
|
||
/>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Parts Panel</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Panel component for displaying parts related to a manual.
|
||
</p>
|
||
<CodeBlock
|
||
id="parts-panel-code"
|
||
code={`import { PartsPanel } from "@/components/parts-panel"
|
||
|
||
<PartsPanel manualFilename="manual.pdf" />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Page Components</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Reusable page layout components.
|
||
</p>
|
||
<CodeBlock
|
||
id="page-components-code"
|
||
code={`import { AboutPage } from "@/components/about-page"
|
||
import { ContactPage } from "@/components/contact-page"
|
||
import { WhoWeServePage } from "@/components/who-we-serve-page"
|
||
import { RepairsPage } from "@/components/repairs-page"
|
||
import { PageWrapper, PageHeader } from "@/components/page-wrapper"
|
||
|
||
<PageWrapper maxWidth="6xl">
|
||
<PageHeader title="Page Title" subtitle="Subtitle" />
|
||
{/* Content */}
|
||
</PageWrapper>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Author Bio</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Author biography component with schema markup.
|
||
</p>
|
||
<CodeBlock
|
||
id="author-bio-code"
|
||
code={`import { AuthorBio } from "@/components/author-bio"
|
||
|
||
<AuthorBio showSchema={true} />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">
|
||
Moving Service Image
|
||
</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Image component with error handling for moving service pages.
|
||
</p>
|
||
<CodeBlock
|
||
id="moving-service-image-code"
|
||
code={`import { MovingServiceImage } from "@/components/moving-service-image"
|
||
|
||
<MovingServiceImage src="/image.jpg" alt="Description" />`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Form Components</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
React Hook Form integration components.
|
||
</p>
|
||
<CodeBlock
|
||
id="form-components-code"
|
||
code={`import { Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage } from "@/components/ui/form"
|
||
|
||
<Form {...form}>
|
||
<FormField
|
||
control={form.control}
|
||
name="fieldName"
|
||
render={({ field }) => (
|
||
<FormItem>
|
||
<FormLabel>Label</FormLabel>
|
||
<FormControl>
|
||
<Input {...field} />
|
||
</FormControl>
|
||
<FormDescription>Description</FormDescription>
|
||
<FormMessage />
|
||
</FormItem>
|
||
)}
|
||
/>
|
||
</Form>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Field Components</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Field components for form layouts.
|
||
</p>
|
||
<CodeBlock
|
||
id="field-components-code"
|
||
code={`import { FieldSet, FieldLegend, FieldGroup, Field, FieldLabel, FieldDescription } from "@/components/ui/field"
|
||
|
||
<FieldSet>
|
||
<FieldLegend>Field Group</FieldLegend>
|
||
<FieldGroup>
|
||
<Field>
|
||
<FieldLabel>Label</FieldLabel>
|
||
<FieldDescription>Description</FieldDescription>
|
||
</Field>
|
||
</FieldGroup>
|
||
</FieldSet>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Item Components</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Item components for lists and menus.
|
||
</p>
|
||
<CodeBlock
|
||
id="item-components-code"
|
||
code={`import { ItemGroup, Item, ItemMedia, ItemContent, ItemTitle, ItemDescription } from "@/components/ui/item"
|
||
|
||
<ItemGroup>
|
||
<Item>
|
||
<ItemMedia variant="icon">
|
||
<Icon />
|
||
</ItemMedia>
|
||
<ItemContent>
|
||
<ItemTitle>Title</ItemTitle>
|
||
<ItemDescription>Description</ItemDescription>
|
||
</ItemContent>
|
||
</Item>
|
||
</ItemGroup>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Input Group</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Input group component for combining inputs with addons and
|
||
buttons.
|
||
</p>
|
||
<CodeBlock
|
||
id="input-group-code"
|
||
code={`import { InputGroup, InputGroupAddon, InputGroupInput, InputGroupButton } from "@/components/ui/input-group"
|
||
|
||
<InputGroup>
|
||
<InputGroupAddon align="inline-start">$</InputGroupAddon>
|
||
<InputGroupInput placeholder="Amount" />
|
||
<InputGroupButton>Submit</InputGroupButton>
|
||
</InputGroup>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Button Group</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Button group component for grouping related buttons.
|
||
</p>
|
||
<CodeBlock
|
||
id="button-group-code"
|
||
code={`import { ButtonGroup, ButtonGroupText } from "@/components/ui/button-group"
|
||
|
||
<ButtonGroup orientation="horizontal">
|
||
<Button>Left</Button>
|
||
<Button>Center</Button>
|
||
<Button>Right</Button>
|
||
</ButtonGroup>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Sidebar</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Sidebar component for navigation and content organization.
|
||
</p>
|
||
<CodeBlock
|
||
id="sidebar-code"
|
||
code={`import { SidebarProvider, Sidebar, SidebarContent, SidebarHeader, SidebarMenu, SidebarMenuItem, SidebarMenuButton } from "@/components/ui/sidebar"
|
||
|
||
<SidebarProvider>
|
||
<Sidebar>
|
||
<SidebarHeader>Header</SidebarHeader>
|
||
<SidebarContent>
|
||
<SidebarMenu>
|
||
<SidebarMenuItem>
|
||
<SidebarMenuButton>Item</SidebarMenuButton>
|
||
</SidebarMenuItem>
|
||
</SidebarMenu>
|
||
</SidebarContent>
|
||
</Sidebar>
|
||
</SidebarProvider>`}
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="text-xl font-semibold mb-4">Sonner Toaster</h3>
|
||
<p className="text-sm text-muted-foreground mb-4">
|
||
Toast notifications using Sonner library.
|
||
</p>
|
||
<CodeBlock
|
||
id="sonner-code"
|
||
code={`import { Toaster } from "@/components/ui/sonner"
|
||
import { toast } from "sonner"
|
||
|
||
<Toaster />
|
||
// Usage: toast.success("Success message")`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
|
||
{/* Footer Note */}
|
||
<div className="mt-16 pt-8 border-t border-border">
|
||
<p className="text-center text-muted-foreground">
|
||
This style guide is a living document. Components and patterns may
|
||
be updated over time.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<Toaster />
|
||
</>
|
||
)
|
||
}
|