Skip to main content

Project Setup

Setup Requirements

Project Structure Requirements

shadcn project structure

Tailwind CSS

TypeScript

Setup Instructions

1. Setting up shadcn project structure

npx create-next-app@latest my-app --typescript --tailwind --eslint

This creates a Next.js project with TypeScript, Tailwind CSS, and ESLint.

2. Install shadcn CLI

npm install -D @shadcn/ui

This installs the shadcn CLI as a development dependency.

3. Initialize shadcn

npx shadcn-ui@latest init

This initializes shadcn in your project and sets up the required configuration.

4. Create components/ui directory

mkdir -p components/ui

This creates the components/ui directory where shadcn components will be stored.

5. Create lib/utils.ts file

mkdir -p lib
touch lib/utils.ts

Add the following code to lib/utils.ts:

import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

Component Structure

The default path for components in a shadcn project is:

/components/ui

This directory structure is important because:

  • It separates UI components from other components
  • It follows the shadcn convention for component organization
  • It makes it easier to find and reuse components
  • It helps maintain a consistent project structure

Project Structure

shadcn Project Structure

The standard shadcn project structure follows these conventions:

my-app/
├── app/
│   ├── layout.tsx
│   └── page.tsx
├── components/
│   ├── ui/           # UI components from shadcn
│   └── [other]/      # Custom components
├── lib/
│   └── utils.ts      # Utility functions
├── styles/
│   └── globals.css   # Global styles
└── tailwind.config.js

Key Directories

  • components/ui/ - Contains all shadcn UI components

  • lib/utils.ts - Contains utility functions including the cn() function

  • styles/globals.css - Global CSS styles including Tailwind directives

Importance of /components/ui Directory

The /components/ui directory is crucial for several reasons:

  • Consistency: Follows shadcn's convention for component organization

  • Integration: shadcn CLI expects components to be in this directory

  • Separation: Clearly separates UI components from application-specific components

  • Reusability: Makes it easier to find and reuse components across the application

  • Updates: Makes it easier to update components when shadcn releases new versions

Component Integration Steps

  1. Create the components/ui directory if it doesn't exist:
    mkdir -p components/ui
  2. Create the lib/utils.ts file if it doesn't exist:
    mkdir -p lib touch lib/utils.ts
  3. Add the cn utility function to lib/utils.ts:
    import { type ClassValue, clsx } from "clsx"
    import { twMerge } from "tailwind-merge"
    
    export function cn(...inputs: ClassValue[]) {
      return twMerge(clsx(inputs))
    }
  4. Copy the CpuArchitecture component to components/ui/cpu-architecture.tsx
  5. Add the CSS animations to your globals.css file
  6. Create a demo page that imports and uses the component

Component Integration

Component Analysis

The CpuArchitecture component is an SVG-based visualization with the following characteristics:

Dependencies

  • React
  • cn utility from @/lib/utils
  • CSS animations in globals.css

Props

  • className, width, height - Styling props
  • text - CPU label text
  • Animation controls - animateText, animateLines, animateMarkers
  • showCpuConnections, lineMarkerSize - Visual customization

Integration Steps

1. Create the Component File

Create the file at /components/ui/cpu-architecture.tsx and paste the component code.

// components/ui/cpu-architecture.tsx
import { cn } from "@/lib/utils";
import React from "react";

export interface CpuArchitectureSvgProps {
  className?: string;
  width?: string;
  height?: string;
  text?: string;
  showCpuConnections?: boolean;
  lineMarkerSize?: number;
  animateText?: boolean;
  animateLines?: boolean;
  animateMarkers?: boolean;
}

// ... rest of the component code

2. Update globals.css

Add the required CSS animations to your globals.css file.

/* Add to globals.css */
.cpu-architecture {
  offset-anchor: 10px 0px;
  animation: animation-path;
  animation-iteration-count: infinite;
  animation-timing-function: cubic-bezier(0.75, -0.01, 0, 0.99);
}

.cpu-line-1 {
  offset-path: path("M 10 20 h 79.5 q 5 0 5 5 v 30");
  animation-duration: 5s;
  animation-delay: 1s;
}

/* ... rest of the CSS animations */

3. Create a Demo Page

Create a demo page to test the component:

// app/demo/page.tsx
"use client";

import { CpuArchitecture } from "@/components/ui/cpu-architecture"

export default function DemoPage() {
  return (
    
); }

Usage Examples

Basic Usage

import { CpuArchitecture } from "@/components/ui/cpu-architecture"

export default function Page() {
  return (
    
); }

Custom Configuration

import { CpuArchitecture } from "@/components/ui/cpu-architecture"

export default function Page() {
  return (
    
); }

Responsive Usage

import { CpuArchitecture } from "@/components/ui/cpu-architecture"

export default function Page() {
  return (
    
); }

Component Preview

CPU Architecture Component Preview

(Interactive SVG with animations)

Component Features

  • Animated SVG visualization of CPU architecture
  • Customizable appearance and animations
  • Fully responsive with adjustable dimensions
  • Themeable through Tailwind's text-muted class

CSS Integration

Adding CSS Animations

The CpuArchitecture component requires specific CSS animations to be added to your globals.css file. These animations control the movement of the colored lights along the CPU architecture paths.

Steps to Add CSS

  1. Locate your globals.css file (typically in the styles directory)
  2. Open the file in your code editor
  3. Add the provided CSS code at the end of the file
  4. Save the file

CSS Animation Breakdown

Base Animation Class

.cpu-architecture {
  offset-anchor: 10px 0px;
  animation: animation-path;
  animation-iteration-count: infinite;
  animation-timing-function: cubic-bezier(0.75, -0.01, 0, 0.99);
}

This class sets up the base animation properties for all animated elements in the component.

Path-Specific Classes

.cpu-line-1 {
  offset-path: path("M 10 20 h 79.5 q 5 0 5 5 v 30");
  animation-duration: 5s;
  animation-delay: 1s;
}

.cpu-line-2 {
  offset-path: path("M 180 10 h -69.7 q -5 0 -5 5 v 40");
  animation-delay: 6s;
  animation-duration: 2s;
}

/* ... other path-specific classes */

Each of these classes defines a specific path for an animated element to follow, along with custom durations and delays.

Animation Keyframes

@keyframes animation-path {
  0% {
    offset-distance: 0%;
  }
  100% {
    offset-distance: 100%;
  }
}

This keyframe animation moves elements from the start (0%) to the end (100%) of their defined paths.

CSS Features Used

Motion Path Animation

Uses modern CSS Motion Path module to animate elements along SVG paths.

  • • offset-path: Defines the path for animation
  • • offset-distance: Controls position along the path
  • • offset-anchor: Sets the anchor point for the element

Animation Properties

Uses standard CSS animation properties for timing and behavior.

  • • animation-duration: Length of animation cycle
  • • animation-delay: Time before animation starts
  • • animation-iteration-count: Number of repetitions
  • • animation-timing-function: Speed curve of animation

Browser Compatibility

The CSS Motion Path module used in these animations has the following browser support:

Browser Support Notes
Chrome Yes (64+) Full support
Firefox Yes (72+) Full support
Safari Yes (15.4+) Recent versions only
Edge Yes (79+) Chromium-based versions
IE No Not supported

For older browsers, consider adding a fallback animation or a polyfill for the Motion Path module.

Troubleshooting

Common Issues

Missing Animations

If the animations are not working properly, check the following:

  • CSS animations not added to globals.css
  • animateLines, animateText, or animateMarkers props set to false
  • Browser doesn't support CSS Motion Path module
Solution:

Ensure the CSS is properly added to globals.css and check browser compatibility. For older browsers, consider adding a polyfill.

SVG Rendering Issues

If the SVG is not rendering correctly, check the following:

  • Component container has zero width or height
  • Conflicting IDs with other SVGs on the page
  • Missing cn utility function from @/lib/utils
Solution:

Ensure the container has explicit dimensions, check for ID conflicts, and verify the cn utility is properly imported.

Import Errors

If you're encountering import errors, check the following:

  • Incorrect file path in import statement
  • Missing lib/utils.ts file with cn function
  • Incorrect export name (should be CpuArchitecture)
Solution:

Verify import paths, ensure lib/utils.ts exists with the cn function, and check export names match import statements.

Browser Compatibility Issues

The component uses modern CSS features that may not be supported in all browsers:

Feature Issue Solution
CSS Motion Path Not supported in older browsers Add a polyfill or fallback animation
SVG Animations Limited support in IE11 Add static fallback for older browsers
SVG Masks Inconsistent implementation across browsers Test thoroughly in target browsers

For production applications, consider adding feature detection and fallbacks for browsers that don't support these features.

Performance Optimization

If you experience performance issues with the component, consider these optimizations:

  • Reduce animation complexity

    Set animateMarkers={false} to reduce the number of animated elements.

  • Lazy load the component

    Use dynamic imports to load the component only when needed.

  • Memoize the component

    Wrap the component with React.memo to prevent unnecessary re-renders.

  • Optimize SVG paths

    Consider simplifying SVG paths if performance is critical.

Example: Lazy Loading Implementation

// app/optimized-demo/page.tsx
"use client";

import dynamic from 'next/dynamic';
import { Suspense } from 'react';

// Lazy load the component
const CpuArchitecture = dynamic(
  () => import('@/components/ui/cpu-architecture').then(mod => mod.CpuArchitecture),
  { 
    ssr: false,
    loading: () => 
} ); export default function OptimizedDemoPage() { return (

Optimized CPU Architecture

}>
); }