This is a Canva Editor Template - a React/Next.js application that replicates the core interface and user experience of Canva's design editor. The template provides a foundation for building design tools, presentation editors, or any application that requires a Canva-like interface.
- Framework: Next.js 15.5.2 with React 19.0.0
- Styling: Tailwind CSS with custom Canva brand colors and gradients
- TypeScript: Full type safety throughout the application
- Fonts: Custom Canva Sans and Canva Display fonts
- Icons: Comprehensive icon system matching Canva's design language
- Purpose: Central workspace for design creation
- Features:
- Responsive canvas with aspect ratio preservation
- Click-to-deselect functionality
- Placeholder content area for designs
- Integration point for design elements
- Purpose: Curated icon library with 21 essential icons
- Structure: Single TypeScript file with all icon components
- Location:
src/icons.tsx - Usage: Direct named imports, consistent sizing, and accessibilitysential icons. All icons are defined in a single file (
src/icons.tsx) as React functional components. This project uses a simplified icon system with 21 essential icons. All icons are defined in a single file (src/icons.tsx) as React functional components. This project uses a simplified icon system with 21 essential icons. All icons are defined in a single file (src/icons.tsx) as React functional components. This project uses a simplified icon system with 21 essential icons. All icons are defined in a single file (src/icons.tsx) as React functional components. This project uses a simplified icon system with 21 essential icons. All icons are defined in a single file (src/icons.tsx) as React functional components. This project uses a simplified icon system with 21 essential icons. All icons are defined in a single file (src/icons.tsx) as React functional components.
The following icons are available:
PlusIcon- Add/create actionsUndoIcon- Undo actionRedoIcon- Redo actionChevronDownIcon- Dropdown indicatorChevronLeftIcon- Left navigationChevronRightIcon- Right navigationPencilIcon- Edit/writingMessageBubbleIcon- Comments/chatPlayFilledIcon- Play/presentAppsIcon- Grid/apps menuTextIcon- Typography/text toolUploadCloudIcon- Upload filesBoxIcon- Elements/shapesFolderIcon- Projects/foldersTimerIcon- Timer/durationBrandKitIcon- Brand assetsTemplateIcon- Design templatesGridIcon- Grid viewPagesIcon- Pages/documentsHelpCircleIcon- Help/supportMaximizeIcon- Fullscreen/expand Adding New Icons inicons.tsx
If you need to add a new icon:
import {
AppsIcon,
TextIcon,
UploadCloudIcon,
BrandKitIcon,
- Add new icons to `src/icons.tsx` when needed
FolderIcon,
TimerIcon,
BoxIconIf you need to add a new icon:
React.ComponentType<{ className?: string }>> = {
design: TemplateIcon,
elements: BoxIcon,
text: TextIcon,
uploads: UploadCloudIcon,
brand: BrandKitIcon,
projects: FolderIcon,
apps: AppsIcon,
"magic-media": TimerIcon,
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
{/* SVG path here */}
</svg>
PlusIcon,
ChevronDownIcon,
PencilIcon,
MessageBubbleIcon,
PlayFilledIcon
- Import and use:
import { MyNewIcon } from '@/icons';
<MyNewIcon className="w-5 h-5" />
<UndoIcon className="w-4 h-4" />
</button>
import { BoxIcon, FolderIcon, AppsIcon } from '@/icons';
- Add new icons to `src/icons.tsx` when needed
box: BoxIcon,
folder: FolderIcon,
### Adding New Icons in `icons.tsx`)
};
If you need to add a new icon:
function DynamicIcon({ type }: { type: string }) {
1. **Open `src/icons.tsx`**
2. **Add the icon component:**
```tsx
export function MyNewIcon({ className = "", strokeWidth = 2 }: IconProps) {
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
{/* SVG path here */}
</svg>
);
}n className="w-6 h-6" />- Import and use:
import { MyNewIcon } from '@/icons';
// Hover states
// Active/Selected states
<Icon className={w-5 h-5 ${isActive ? 'text-purple-600' : 'text-gray-500'}} />
// Disabled states
- Add new icons to
src/icons.tsxwhen needed
### Adding New Icons in `icons.tsx`)
If you need to add a new icon:
1. **Open `src/icons.tsx`**
2. **Add the icon component:**
```tsx
export function MyNewIcon({ className = "", strokeWidth = 2 }: IconProps) {
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
{/* SVG path here */}
</svg>
);
}
- Import and use:
import { MyNewIcon } from '@/icons'; <MyNewIcon className="w-5 h-5" />
✅ DO:
- Use direct named imports from
@/icons - Include size classes (
w-4 h-4,w-5 h-5, etc.) - Use descriptive icon names that match functionality
- Keep icon usage consistent across similar components
- Add new icons to
src/icons.tsxwhen needed
❌ DON'T:
- Hard-code SVG paths directly in components
- Use icons without size classes
- Create separate icon files (keep them in
icons.tsx)
When working with this template, AI agents should:
-
Use ONLY the Approved Canva Color Palette:
- Purple: Interactive elements, primary actions (
purple-100throughpurple-950) - Red: Critical moments, errors (
red-100throughred-950) - Green: Positive moments, success states (
green-100throughgreen-950) - Yellow: Wary moments, caution states (
yellow-100throughyellow-950) - Blue: Informational moments, secondary actions (
blue-100throughblue-950) - Gray: UI elements, neutral content (
gray-100throughgray-950) - Black: Text, borders with alpha variants (
black-100throughblack-950) - White: Backgrounds, cards with alpha variants (
white-100throughwhite-950)
- Purple: Interactive elements, primary actions (
-
Special Color Variants:
-
Purple Alpha: Use
purple-alpha-*for overlay states and subtle interactions -
Brand Colors: Use
canva-*namespace for explicit brand colors when needed -
Check the available icons list in this document
-
❌ Do NOT use:
slate,zinc,neutral,stone,orange,lime,emerald,cyan,sky,indigo,violet,fuchsia,pink,rose -
Always use direct named imports100-900) with Canva's custom values
-
-
Usage Examples:
// Primary actions <button className="bg-purple-600 text-white hover:bg-purple-700"> // Success states <div className="bg-green-100 text-green-800 border border-green-200"> // Error states <div className="bg-red-100 text-red-800 border border-red-200"> // Overlay states - Check the list of available icons in the Icon System Guide - If needed, add a new icon to `src/icons.tsx`
-
Semantic Tokens: Use component-specific semantic tokens for consistent UI patterns:
Action Tokens (buttons, CTAs, interactive elements):
// Primary actions (main purpose buttons) <button className="bg-action-primary-bg text-action-primary-fg hover:bg-action-primary-bg-hovered"> // Secondary actions (supporting buttons) <button className="bg-action-secondary-bg text-action-secondary-fg border-action-secondary-border"> // Critical actions (destructive/dangerous) <button className="bg-action-critical-bg text-action-critical-fg hover:bg-action-critical-bg-hovered"> // Selected states <button className="bg-action-selected-bg text-action-selected-fg border-action-selected-border">
Feedback Tokens (badges, alerts, status indicators):
// Success feedback <div className="bg-feedback-positive-bg text-feedback-positive-fg"> // Subtle success feedback <div className="bg-feedback-positive-subtle-bg text-feedback-positive-subtle-fg"> // Error feedback <div className="bg-feedback-critical-bg text-feedback-critical-fg"> // Warning feedback <div className="bg-feedback-warn-bg text-feedback-warn-fg">
UI Tokens (backgrounds, borders, overlays):
// Card backgrounds <div className="bg-ui-neutral-bg border-ui-border"> // Focus states <input className="border-ui-border-focused"> // Overlay backgrounds <div className="bg-ui-overlay-bg">
Content Tokens (text and icon colors):
- Check the available icons list in this document // Primary text
- Always use direct named imports
// Secondary text
// Placeholder text
// Status text Success!
**Control Tokens** (form elements): ```tsx - Check the list of available icons in the Icon System Guide - If needed, add a new icon to `src/icons.tsx`-border focus:border-control-border-focused"> // Error states <input className="border-control-critical-border"> // Selected states (toggles, checkboxes) <div className="bg-control-selected-bg text-control-selected-fg">Link Tokens (navigational elements):
// Standard links <a className="text-link-fg hover:text-link-fg-hovered"> // Critical links <a className="text-link-critical-fg hover:text-link-critical-fg-hovered">
-
When to Use Semantic Tokens vs Base Colors:
- Prefer semantic tokens when building standard UI components (buttons, forms, alerts)
- Use base colors (
purple-600,red-500) for custom designs that don't fit standard patterns - Combine tokens as needed for complex components
- Benefits: Consistency, maintainability, accessibility, and clear intent
-
Reference: See
COLOR_SYSTEM.mdfor detailed usage guidelines and accessibility requirements
This project uses custom typography tokens defined in globals.css that combine font family, size, weight, and line-height into single, reusable classes.
Available Typography Tokens:
Title Tokens (use Canva Display font):
.text-title-xlarge- 64px, bold, 125% line-height (Hero headings).text-title-large- 48px, bold, 125% line-height (Page titles).text-title-medium- 32px, bold, 125% line-height (Section headers).text-title-small- 24px, bold, 24px line-height (Subsection headers).text-title-xsmall- 14px, bold, 20px line-height (Small headings, labels).text-title-xxsmall- 12px, bold, 18px line-height (Tiny labels, tags)
Body Tokens (use Canva Sans font):
.text-body-xlarge- 21px, regular, 150% line-height (Large body text, descriptions).text-body-large- 16px, regular, 24px line-height (Standard body text).text-body-large-bold- 16px, semibold, 24px line-height (Emphasized body text).text-body-medium- 14px, regular, 22px line-height (Smaller body text, UI labels).text-body-medium-bold- 14px, semibold, 22px line-height (Emphasized UI labels).text-body-small- 12px, regular, 18px line-height (Fine print, captions).text-body-small-bold- 12px, semibold, 20px line-height (Small emphasized text).text-body-xsmall- 11px, medium, 16px line-height (Tiny UI text, metadata)
When to Use Typography Tokens:
✅ DO use typography tokens for:
- Headings and titles (use
.text-title-*classes) - Body copy and paragraphs (use
.text-body-*classes) - UI labels and descriptions
- Consistent text styling across the application
- Maintaining brand typography standards
// Page title
<h1 className="text-title-large text-content-fg">
Welcome to Canva
</h1>
// Section heading
<h2 className="text-title-medium text-content-fg">
Your Designs
</h2>
// Body text
<p className="text-body-large text-content-subtle-fg">
Start creating amazing designs with our intuitive editor.
</p>
// UI label
<span className="text-body-medium text-content-fg">
File name
</span>
// Small metadata
<span className="text-body-xsmall text-content-subtle-fg">
Last edited 2 hours ago
</span>❌ DON'T:
- Mix custom font sizes with typography tokens (use tokens consistently)
- Override font-family on typography tokens (they're designed as complete units)
- Use title tokens for body text or vice versa
Combining with Color Tokens:
Typography tokens handle font styling only. Always combine them with color tokens:
// Heading with semantic color
<h1 className="text-title-large text-content-fg">
// Body text with subtle color
<p className="text-body-large text-content-subtle-fg">
// Success message with positive color
<span className="text-body-medium-bold text-content-positive-fg">
// Error text with critical color
<span className="text-body-small text-feedback-critical-fg">Typography Hierarchy Best Practices:
-
Page Structure:
- Page title:
.text-title-largeor.text-title-xlarge - Section headings:
.text-title-medium - Subsections:
.text-title-small - Body content:
.text-body-large
- Page title:
-
UI Components:
- Button labels:
.text-body-mediumor.text-body-medium-bold - Form labels:
.text-body-medium-bold - Input placeholder:
.text-body-medium - Helper text:
.text-body-small - Tooltips:
.text-body-small
- Button labels:
-
Cards & Lists:
- Card title:
.text-title-smallor.text-body-large-bold - Card description:
.text-body-medium - Metadata:
.text-body-xsmall
- Card title:
-
Visual Hierarchy:
- Use proper contrast ratios for accessibility
- Maintain Canva's clean, modern aesthetic
- Follow the established spacing and sizing patterns
When extending or modifying components:
-
Maintain Brand Consistency:
- Use established color tokens from
tailwind.config.ts - Follow the existing component patterns
- Preserve the Canva-like interaction patterns
- Use established color tokens from
-
Icon Usage:
- Use the existing icon system from
@/icons(see Icon System Guide) - Check the available icons list in this document
- Maintain consistent sizing (16px, 20px, 24px standards)
- Always use direct named imports
- Use the existing icon system from
-
Layout Patterns:
- Maintain the 16px sidebar width for left navigation
- Use consistent padding and margins
- Follow the established responsive breakpoints
When adding new features or content:
-
Design Elements:
- Follow Canva's design principles: clean, modern, accessible
- Use appropriate gradients and color combinations
- Check the list of available icons in the Icon System Guide
- If needed, add a new icon to
src/icons.tsx
-
User Experience:
- Preserve the intuitive navigation patterns
- Maintain the hover states and interactions
- Follow Canva's established UX patterns
-
Pro Features:
- Use crown icons (
CrownPro) to indicate premium features - Maintain the upgrade prompts and branding
- Follow the established pro feature patterns
- Use crown icons (
assets/
├── icons/ # Source SVG files (669 icons)
src/
├── app/ # Next.js app router
│ ├── layout.tsx # Root layout with fonts
│ ├── page.tsx # Main canvas page
│ └── globals.css # Global styles
├── components/ # React components
│ ├── Navbar.tsx # Top navigation
│ ├── LeftSidebar.tsx # Left tool panel
│ ├── BottomToolbar.tsx # Bottom controls
│ ├── Dropdown.tsx # Dropdown menu component
│ └── HoverPanel.tsx # Contextual hover info
├── icons/ # Icon system
│ ├── components/ # Auto-generated icon components (669 files)
│ ├── manifest.json # Searchable icon index
│ ├── index.ts # Icon exports
│ └── ICON_SYSTEM.md # Icon documentation
└── public/fonts/ # Custom Canva fonts
- Next.js 15.5.2: App router, server components
- React 19.0.0: Latest React features
- Tailwind CSS 3.4.1: Utility-first styling
- TypeScript 5: Type safety
-
Component Development:
- Use TypeScript interfaces for props
- Follow React best practices (hooks, refs, etc.)
- Maintain accessibility standards
-
Styling:
- Use Tailwind utility classes
- Leverage the custom Canva color system
- Maintain responsive design principles
-
State Management:
- Use React hooks for local state
- Implement proper event handling
- Maintain clean component interfaces
- Check the list of available icons in the Icon System Guide
- If needed, add a new icon to
src/icons.tsxls in the main canvas area
- Content Management: Add new content types following the established patterns
- User Interactions: Maintain the hover states and click behaviors
- Brand Compliance: Always use the established color system and design patterns
- Colors: Modify
tailwind.config.tsfor brand customization - Icons: Add new icons directly to
src/icons.tsx - Layout: Maintain the responsive design principles
- Typography: Use the custom Canva fonts for brand consistency
When working with this template:
- Understand the Interface: Familiarize yourself with each component's purpose and functionality
- Follow Brand Guidelines: Use the established color system, typography, and design patterns
- Maintain Consistency: Preserve the Canva-like user experience and interaction patterns
- Extend Thoughtfully: Add new features while maintaining the existing design language
- Test Responsively: Ensure all modifications work across different screen sizes
This template provides a solid foundation for building design tools that feel native to the Canva ecosystem while maintaining the flexibility to customize and extend functionality as needed.
- Speed Over Perfection: Prioritize getting things working quickly over perfect code
- Iterative Development: Build, test, and refine rather than over-planning
- Direct Action: When given a task, start implementing immediately rather than discussing options
- Minimal Back-and-Forth: Reduce conversation overhead by taking action first
- Functional First: Focus on making things work, then optimize
- Clean Implementation: Write readable, maintainable code
- Follow Patterns: Use existing code patterns and conventions in the project
- TypeScript Best Practices: Maintain type safety and proper interfaces
- Canva Brand Compliance: Always maintain the established Canva design language
- Component Consistency: Follow existing component patterns and styling
- Responsive Design: Ensure all changes work across different screen sizes
- Accessibility: Maintain proper accessibility standards
- Action-Oriented: Prefer doing over discussing
- Solution-Focused: Present solutions with implementation rather than just ideas
- Efficiency First: Minimize time spent on planning and maximize time on building
- User-Centric: Always consider the end user experience in design decisions
- Graceful Degradation: Implement fallbacks for edge cases
- Clear Error Messages: Provide helpful feedback when things go wrong
- Quick Recovery: Focus on getting back to working state quickly
- Learning from Mistakes: Use errors as learning opportunities for better implementations
This approach ensures rapid development while maintaining high quality and user experience standards.
-
Find appropriate icon:
- Check the list of available icons in the Icon System Guide
- If needed, add a new icon to
src/icons.tsx
-
Update LeftSidebar.tsx:
// Add to imports import { YourToolIcon } from '@/icons'; // Add to ICON_MAP const ICON_MAP = { // ... existing icons "your-tool": YourToolIcon, }; // Add to sidebarItems array const sidebarItems = [ // ... existing items { id: "your-tool", label: "Your Tool", hoverText: "Description of your tool", isPro: false, // Set to true if it's a Pro feature }, ];
-
Test the implementation:
- Verify icon displays correctly
- Check hover panel shows proper text
- Ensure Pro badge appears if isPro is true
- Confirm click handler works
import { YourIcon } from '@/icons';
// Primary action button (most common)
<button className="px-4 py-2 bg-action-primary-bg text-action-primary-fg rounded-lg hover:bg-action-primary-bg-hovered transition-colors">
<YourIcon className="w-5 h-5" />
<span>Primary Action</span>
</button>
// Secondary action button
<button className="px-4 py-2 bg-action-secondary-bg text-action-secondary-fg border border-action-secondary-border rounded-lg hover:bg-gray-100 transition-colors">
<YourIcon className="w-5 h-5" />
<span>Secondary Action</span>
</button>
// Critical/destructive action button
<button className="px-4 py-2 bg-action-critical-bg text-action-critical-fg rounded-lg hover:bg-action-critical-bg-hovered transition-colors">
<YourIcon className="w-5 h-5" />
<span>Delete</span>
</button>
// Icon-only button (compact)
<button className="p-2 hover:bg-gray-100 rounded-lg transition-colors" aria-label="Description">
<YourIcon className="w-5 h-5 text-gray-700" />
</button>import { Dropdown } from '@/components/Dropdown';
import { ChevronDownIcon, Option1Icon, Option2Icon } from '@/icons';
<Dropdown
trigger={
<button className="px-3 py-2 hover:bg-gray-100 rounded-lg flex items-center gap-2">
<span>Menu</span>
<ChevronDownIcon className="w-4 h-4" />
</button>
}
items={[
{
label: "Option 1",
icon: <Option1Icon className="w-4 h-4" />,
onClick: () => handleOption1(),
},
{
label: "Option 2",
icon: <Option2Icon className="w-4 h-4" />,
onClick: () => handleOption2(),
shortcut: "⌘K",
},
{ type: "separator" },
{
label: "Danger Option",
icon: <TrashIcon className="w-4 h-4" />,
onClick: () => handleDelete(),
variant: "danger",
},
]}
align="right"
/>// Standard text input
<div className="flex flex-col gap-1">
<label className="text-sm font-medium text-content-fg">
Field Label
</label>
<input
type="text"
className="px-3 py-2 bg-control-bg border border-control-border rounded-lg focus:outline-none focus:border-control-border-focused transition-colors"
placeholder="Enter text..."
/>
<span className="text-xs text-content-subtle-fg">
Helper text goes here
</span>
</div>
// Input with error state
<div className="flex flex-col gap-1">
<label className="text-sm font-medium text-content-fg">
Field Label
</label>
<input
type="text"
className="px-3 py-2 bg-control-bg border border-control-critical-border rounded-lg focus:outline-none focus:border-control-critical-border transition-colors"
placeholder="Enter text..."
/>
<span className="text-xs text-feedback-critical-fg">
Error message goes here
</span>
</div>
// Input with success state
<div className="flex flex-col gap-1">
<label className="text-sm font-medium text-content-fg">
Field Label
</label>
<input
type="text"
className="px-3 py-2 bg-control-bg border border-green-500 rounded-lg focus:outline-none transition-colors"
placeholder="Enter text..."
/>
<span className="text-xs text-content-positive-fg flex items-center gap-1">
<CheckIcon className="w-3 h-3" />
Looks good!
</span>
</div>// Success badge
<div className="inline-flex items-center gap-2 px-3 py-1 bg-feedback-positive-subtle-bg text-feedback-positive-subtle-fg rounded-full text-sm">
<CheckCircleIcon className="w-4 h-4" />
<span>Success</span>
</div>
// Error badge
<div className="inline-flex items-center gap-2 px-3 py-1 bg-feedback-critical-bg text-feedback-critical-fg rounded-full text-sm">
<ErrorIcon className="w-4 h-4" />
<span>Error</span>
</div>
// Warning badge
<div className="inline-flex items-center gap-2 px-3 py-1 bg-feedback-warn-bg text-feedback-warn-fg rounded-full text-sm">
<WarningIcon className="w-4 h-4" />
<span>Warning</span>
</div>
// Info badge
<div className="inline-flex items-center gap-2 px-3 py-1 bg-feedback-info-bg text-feedback-info-fg rounded-full text-sm">
<InfoIcon className="w-4 h-4" />
<span>Info</span>
</div>Typography tokens provide consistent text styling across the application. Always combine them with color tokens.
// Page header with title and description
<div className="space-y-2">
<h1 className="text-title-large text-content-fg">
Your Design Projects
</h1>
<p className="text-body-large text-content-subtle-fg">
Browse and manage all your creative work in one place
</p>
</div>
// Section with heading and content
<section className="space-y-4">
<h2 className="text-title-medium text-content-fg">
Recent Designs
</h2>
<div className="grid grid-cols-3 gap-4">
{/* Card content */}
</div>
</section>
// Card with multiple text levels
<div className="bg-white-900 border border-ui-border rounded-lg p-4">
<h3 className="text-title-small text-content-fg mb-2">
Project Name
</h3>
<p className="text-body-medium text-content-subtle-fg mb-3">
A brief description of the project and its purpose.
</p>
<div className="flex items-center justify-between">
<span className="text-body-xsmall text-content-subtle-fg">
Updated 2 hours ago
</span>
<button className="text-body-medium-bold text-purple-600">
Open
</button>
</div>
</div>
// Form with labels and helper text
<div className="space-y-1">
<label className="text-body-medium-bold text-content-fg">
Project Name
</label>
<input
type="text"
className="w-full px-3 py-2 border border-control-border rounded-lg text-body-medium"
placeholder="Enter project name"
/>
<span className="text-body-small text-content-subtle-fg">
Choose a memorable name for your project
</span>
</div>
// Status message with appropriate typography
<div className="bg-feedback-positive-subtle-bg p-3 rounded-lg">
<h4 className="text-body-large-bold text-feedback-positive-subtle-fg mb-1">
Success!
</h4>
<p className="text-body-medium text-feedback-positive-subtle-fg">
Your design has been published successfully.
</p>
</div>
// Navigation or menu item
<button className="flex items-center gap-2 px-3 py-2 hover:bg-purple-alpha-20 rounded-lg">
<FolderIcon className="w-5 h-5" />
<span className="text-body-medium text-content-fg">
My Projects
</span>
</button>
// Empty state with hierarchy
<div className="text-center py-12">
<h3 className="text-title-medium text-content-fg mb-2">
No designs yet
</h3>
<p className="text-body-large text-content-subtle-fg mb-6">
Get started by creating your first design
</p>
<button className="bg-action-primary-bg text-action-primary-fg px-6 py-3 rounded-lg">
<span className="text-body-medium-bold">Create New Design</span>
</button>
</div>Typography Token Selection Guide:
| Use Case | Recommended Token | Example |
|---|---|---|
| Hero heading | .text-title-xlarge |
Landing page main title |
| Page title | .text-title-large |
Dashboard page header |
| Section heading | .text-title-medium |
"Recent Projects" |
| Card/Widget title | .text-title-small |
Card header |
| Badge label | .text-title-xxsmall |
"PRO" badge |
| Primary content | .text-body-large |
Article text, descriptions |
| UI labels | .text-body-medium |
Form labels, menu items |
| Button text | .text-body-medium-bold |
Primary/secondary buttons |
| Helper text | .text-body-small |
Form hints, captions |
| Metadata | .text-body-xsmall |
Timestamps, counts |
❌ Problem: Using Tailwind default colors that aren't in Canva system
<button className="bg-indigo-500"> // indigo not in Canva palette✅ Solution: Use Canva's approved colors
- **Icon System**: `/Users/danielfarrell/Documents/GitHub/canva-template-1/src/icons.tsx`❌ Problem: Trying to load icons dynamically
import { Icon } from '@/icons';
<Icon name="apps" /> // This doesn't work in Next.js✅ Solution: Use direct imports and mapping
import { AppsIcon, TextIcon } from '@/icons';
const iconMap = {
apps: AppsIcon,
text: TextIcon,
};
const IconComponent = iconMap[iconName];
<IconComponent className="w-5 h-5" />❌ Problem: Icon doesn't display because no size is specified
<AppsIcon /> // No size, might not be visible✅ Solution: Always include size classes
<AppsIcon className="w-5 h-5" /> // Properly sized❌ Problem: Creating custom button styles instead of using tokens
<button className="bg-purple-600 text-white hover:bg-purple-700">✅ Solution: Use semantic tokens for consistency
<button className="bg-action-primary-bg text-action-primary-fg hover:bg-action-primary-bg-hovered">❌ Problem: Creating custom gradients
<div className="bg-gradient-to-r from-purple-500 to-blue-500">✅ Solution: Use established Canva gradients
<div className="bg-grad-core-horizontal"> // Uses Canva's signature gradient❌ Problem: Icon buttons without labels
<button>
<CloseIcon className="w-5 h-5" />
</button>✅ Solution: Always include aria-label for icon-only buttons
- **Icon System**: `/Users/danielfarrell/Documents/GitHub/canva-template-1/src/icons.tsx`
<CloseIcon className="w-5 h-5" />
</button>❌ Problem: Typography token without color specification
<h1 className="text-title-large">Title</h1> // Inherits color, may not be what you want✅ Solution: Always combine typography with appropriate color tokens
<h1 className="text-title-large text-content-fg">Title</h1>
<p className="text-body-medium text-content-subtle-fg">Description</p>The Navbar follows a three-section layout:
<nav className="flex items-center justify-between px-4 py-2 bg-grad-core-horizontal">
{/* Left section - File controls */}
<div className="flex items-center gap-2">
{/* File menu, resize, etc. */}
</div>
{/* Center section - Editor controls */}
<div className="flex items-center gap-2">
{/* Undo/Redo, etc. */}
</div>
{/* Right section - User controls */}
<div className="flex items-center gap-2">
{/* Upgrade, Share, Profile, etc. */}
</div>
</nav>Each sidebar item follows this structure:
<button
className={`
relative w-16 h-16 flex flex-col items-center justify-center gap-1
hover:bg-purple-alpha-20 rounded-lg transition-colors
${isActive ? 'bg-purple-alpha-30' : ''}
`}
onMouseEnter={() => setHoveredItem(item.id)}
onMouseLeave={() => setHoveredItem(null)}
onClick={() => handleItemClick(item.id)}
>
<IconComponent className="w-6 h-6" />
<span className="text-xs">{item.label}</span>
{item.isPro && <CrownProIcon className="absolute top-1 right-1 w-4 h-4" />}
</button>Used throughout for contextual information:
<HoverPanel
isVisible={hoveredItem === item.id}
position="right"
offset={16}
>
<div className="p-3 bg-white-900 rounded-lg shadow-lg border border-gray-200">
<h3 className="font-semibold text-content-fg">{item.label}</h3>
<p className="text-sm text-content-subtle-fg">{item.hoverText}</p>
{item.isPro && (
<span className="text-xs text-purple-600 flex items-center gap-1 mt-1">
<CrownProIcon className="w-3 h-3" />
Pro feature
</span>
)}
</div>
</HoverPanel>
- **Icon System**: `/Users/danielfarrell/Documents/GitHub/canva-template-1/src/icons.tsx`
### Pattern 4: Dropdown Menu Items
Standard dropdown item structure:
```tsx
{
label: "Menu Item",
icon: <IconComponent className="w-4 h-4" />,
onClick: () => handleAction(),
shortcut: "⌘K", // Optional keyboard shortcut
1. Check if icon exists in `src/icons.tsx`al variant
}
3. Check the available icons list in this document
4. If icon is needed, add it to `src/icons.tsx`
## Testing Checklist for AI Agents
When implementing new features, verify:
### Visual Testing
- [ ] Component displays correctly in light mode
- [ ] Proper spacing and alignment with existing components
- [ ] Icons are properly sized and colored
- [ ] Hover states work as expected
- [ ] Active/selected states are visually distinct
- [ ] Text is readable with proper contrast
### Interaction Testing
- [ ] Click handlers trigger correctly
- [ ] Keyboard navigation works (Tab, Enter, Escape)
- [ ] Focus states are visible
- [ ] Hover panels appear at correct position
- [ ] Dropdowns open and close properly
### Responsive Testing
- [ ] Component works on mobile viewports
- [ ] Component works on tablet viewports
- [ ] Component works on desktop viewports
- [ ] No horizontal scrolling
- [ ] Text doesn't overflow containers
### Accessibility Testing
- [ ] All interactive elements have proper ARIA labels
- [ ] Keyboard navigation is logical and complete
- [ ] Color contrast meets WCAG standards
- [ ] Screen reader announces elements correctly
- [ ] Focus is managed properly in modals/dropdowns
### Brand Compliance Testing
- [ ] Uses only approved Canva colors
- [ ] Uses semantic tokens where appropriate
- [ ] Icons are from the icon system
- [ ] Typography uses typography tokens (`.text-title-*` or `.text-body-*`)
- [ ] Typography tokens are combined with color tokens
- [ ] Follows established design patterns
## Quick Reference: File Locations
### Components
- **Navbar**: `/Users/danielfarrell/Documents/GitHub/canva-template-1/src/components/Navbar.tsx`
- **LeftSidebar**: `/Users/danielfarrell/Documents/GitHub/canva-template-1/src/components/LeftSidebar.tsx`
- **BottomToolbar**: `/Users/danielfarrell/Documents/GitHub/canva-template-1/src/components/BottomToolbar.tsx`
- **Dropdown**: `/Users/danielfarrell/Documents/GitHub/canva-template-1/src/components/Dropdown.tsx`
- **HoverPanel**: `/Users/danielfarrell/Documents/GitHub/canva-template-1/src/components/HoverPanel.tsx`
### Configuration
- **Tailwind Config**: `/Users/danielfarrell/Documents/GitHub/canva-template-1/tailwind.config.ts`
- **Color System**: `/Users/danielfarrell/Documents/GitHub/canva-template-1/COLOR_SYSTEM.md`
- **Icon System**: `/Users/danielfarrell/Documents/GitHub/canva-template-1/src/icons.tsx`
### Layout
- **Root Layout**: `/Users/danielfarrell/Documents/GitHub/canva-template-1/src/app/layout.tsx`
- **Main Page**: `/Users/danielfarrell/Documents/GitHub/canva-template-1/src/app/page.tsx`
- **Global Styles**: `/Users/danielfarrell/Documents/GitHub/canva-template-1/src/app/globals.css`
## Troubleshooting Guide
### Issue: Icon not found during import
1. Check if icon exists in `src/icons.tsx`
2. Verify correct casing: Component names are PascalCase
3. Check the available icons list in this document
4. If icon is needed, add it to `src/icons.tsx`
### Issue: Colors look wrong
1. Verify you're using Canva color names (purple, red, green, etc.)
2. Check you're not using prohibited colors (indigo, cyan, etc.)
3. Review COLOR_SYSTEM.md for correct color usage
4. Consider using semantic tokens instead of base colors
### Issue: Component not showing up
1. Check if component is imported correctly
2. Verify className includes necessary display/position utilities
3. Check parent container has proper layout
4. Inspect z-index stacking if overlapping issues
### Issue: TypeScript errors
1. Ensure all props have proper TypeScript interfaces
2. Check import paths are correct (`@/icons`, `@/components`)
3. Verify React types are up to date
4. Check for any `any` types that should be specific
### Issue: Build errors
1. Clear `.next` folder: `rm -rf .next`
2. Delete `node_modules` and reinstall: `rm -rf node_modules && npm install`
3. Check for any circular dependencies
4. Verify all imports are valid
### Issue: Styling not applying
1. Check Tailwind class names are spelled correctly
2. Verify custom classes are defined in tailwind.config.ts
3. Check for conflicting classes
4. Ensure purge/content paths include your files
## Advanced Patterns
### Pattern: Conditional Rendering with Brand Elements
```tsx
<div className="relative">
{/* Main content */}
<div className="...">
Content here
</div>
{/* Pro badge overlay */}
{isPro && (
<div className="absolute -top-2 -right-2">
<CrownProIcon className="w-5 h-5 text-purple-600" />
</div>
)}
</div>{isLoading ? (
<div className="flex items-center justify-center p-4">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-purple-600" />
</div>
) : (
<div>{content}</div>
)}<div className="flex flex-col items-center justify-center p-8 text-center">
<EmptyStateIcon className="w-16 h-16 text-gray-400 mb-4" />
<h3 className="text-lg font-semibold text-content-fg mb-2">
No items yet
</h3>
<p className="text-sm text-content-subtle-fg mb-4">
Get started by creating your first item
</p>
<button className="bg-action-primary-bg text-action-primary-fg px-4 py-2 rounded-lg">
Create Item
</button>
</div><div className="bg-ui-neutral-bg border border-ui-border rounded-lg p-4 hover:shadow-md transition-shadow">
<div className="flex items-start justify-between mb-3">
<h3 className="font-semibold text-content-fg">Card Title</h3>
<button className="text-gray-500 hover:text-gray-700">
<MoreIcon className="w-5 h-5" />
</button>
</div>
<p className="text-sm text-content-subtle-fg mb-4">
Card description text goes here
</p>
<div className="flex items-center gap-2">
<button className="flex-1 bg-action-primary-bg text-action-primary-fg py-2 rounded-lg">
Primary
</button>
<button className="flex-1 border border-action-secondary-border text-action-secondary-fg py-2 rounded-lg">
Secondary
</button>
</div>
</div>When starting a new task:
- Read relevant component files to understand existing patterns
- Check available icons in
src/icons.tsx - Use typography tokens (
.text-title-*or.text-body-*) for all text - Use semantic color tokens for UI components
- Follow established component patterns
- Test across different states and viewports
- Verify brand compliance
Token Usage Quick Reference:
- Typography:
.text-title-large,.text-body-medium, etc. (always combine with color) - Colors: Use semantic tokens (
text-content-fg,bg-action-primary-bg) - Icons: Import directly from
@/iconsand include size classes
Remember:
- Speed matters, but maintain quality
- Use existing patterns and components (typography tokens, color tokens, icons)
- Follow the Canva design language
- Always combine typography tokens with color tokens
- Test thoroughly before considering done
- When in doubt, check existing code for examples
This guide provides all the knowledge needed to successfully work with this Canva Editor Template. Refer to specific sections as needed during development.