Components

Component Library

Design System

Our component library is built on top of shadcn/ui and follows these principles:

  • Accessibility first
  • Type-safe components
  • Consistent theming
  • Dark mode support

Core Components

Button

import { Button } from "@/components/ui/button"

// Primary button
<Button variant="default">Click me</Button>

// Secondary button
<Button variant="secondary">Cancel</Button>

// Destructive button
<Button variant="destructive">Delete</Button>

Input

import { Input } from "@/components/ui/input"

<Input
  type="email"
  placeholder="Email"
  required
/>

Card

import { Card } from "@/components/ui/card"

<Card>
  <CardHeader>
    <CardTitle>Project Name</CardTitle>
    <CardDescription>Project description here</CardDescription>
  </CardHeader>
  <CardContent>
    {/* Content */}
  </CardContent>
  <CardFooter>
    {/* Footer */}
  </CardFooter>
</Card>

Feature Components

ProjectCard

import { ProjectCard } from "@/features/projects/components"

<ProjectCard
  project={{
    id: "1",
    name: "My Project",
    description: "Project description",
    status: "active"
  }}
  onEdit={handleEdit}
  onDelete={handleDelete}
/>

VMStatus

import { VMStatus } from "@/features/vms/components"

<VMStatus
  vm={{
    id: "1",
    name: "VM-1",
    status: "running",
    metrics: {
      cpu: 45,
      memory: 60,
      disk: 30
    }
  }}
/>

Layout Components

AppLayout

import { AppLayout } from "@/components/layouts"

<AppLayout>
  {/* Page content */}
</AppLayout>
import { Sidebar } from "@/components/layouts"

<Sidebar
  items={[
    {
      label: "Dashboard",
      icon: <HomeIcon />,
      href: "/dashboard"
    }
  ]}
/>

Form Components

Form

import { Form } from "@/components/ui/form"

<Form
  onSubmit={handleSubmit}
  defaultValues={{
    name: "",
    description: ""
  }}
>
  <FormField
    name="name"
    label="Name"
    control={control}
    rules={{ required: true }}
  />
</Form>

Feedback Components

Toast

import { useToast } from "@/components/ui/toast"

const { toast } = useToast()

toast({
  title: "Success",
  description: "Project created successfully",
  variant: "success"
})

Best Practices

Component Structure

interface Props {
  // Props interface
}

export const Component = ({
  prop1,
  prop2
}: Props) => {
  // Component logic
  return (
    // JSX
  )
}

Error Handling

const ErrorBoundary = ({
  children,
  fallback
}: {
  children: React.ReactNode
  fallback: React.ReactNode
}) => {
  // Error boundary implementation
}

Loading States

const LoadingSpinner = () => (
  <div className="animate-spin">
    {/* Spinner content */}
  </div>
)

Component Development

Creating New Components

  1. Create component file
  2. Write TypeScript interfaces
  3. Implement component
  4. Add Storybook stories
  5. Write tests

Testing Components

import { render, screen } from "@testing-library/react"

test("Button renders correctly", () => {
  render(<Button>Click me</Button>)
  expect(screen.getByText("Click me")).toBeInTheDocument()
})