coder.env
v0.1.0
Published
A beautifully crafted React code editor component that replicates the aesthetic and functionality of v0.dev's interface. Built on top of CodeSandbox's Sandpack, this component provides a professional, dark-themed code editing experience with live preview
Downloads
4
Readme
V0 Style Sandpack Component
A beautifully crafted React code editor component that replicates the aesthetic and functionality of v0.dev's interface. Built on top of CodeSandbox's Sandpack, this component provides a professional, dark-themed code editing experience with live preview capabilities, custom scrollbars, and precise line number alignment.
🚀 Features
- 🎨 v0.dev-inspired Design: Pixel-perfect recreation of v0's dark theme interface
- 📝 Code Editor: Full-featured code editor with syntax highlighting and perfectly aligned line numbers
- 👀 Live Preview: Real-time preview of your React applications
- 📁 File Explorer: Compact file tree with modern icons and custom scrollbars
- 🖥️ Terminal Integration: Built-in terminal with console output
- ⚡ Hot Reload: Instant updates as you type
- 🎯 Tab Navigation: Seamless switching between Code and Preview modes with gradient effects
- 🔧 Highly Customizable: Extensive props and CSS classes for customization
- 🎭 Premium Visual Effects: Gradient borders, shimmer animations, and enhanced hover states
- 📏 Perfect Alignment: Precisely aligned line numbers regardless of code length or line count
📦 Installation
Prerequisites
Ensure you have React 18+ installed in your project:
```bash npm install react@^18.0.0 react-dom@^18.0.0 ```
Core Dependencies
Install the required dependencies:
```bash npm install @codesandbox/sandpack-react lucide-react ```
Optional Dependencies (for enhanced styling)
```bash npm install tailwindcss @tailwindcss/typography ```
TypeScript Support
If using TypeScript, install the type definitions:
```bash npm install -D @types/react @types/react-dom ```
🎯 Quick Start
Basic Implementation
```tsx import V0Sandpack from './components/v0-sandpack' import { defaultReactFiles } from './default-files'
function App() { return ( ) }
export default App ```
With Custom Files
```tsx const customFiles = { "/App.tsx": `import React, { useState } from 'react';
export default function App() { const [count, setCount] = useState(0);
return (
Counter: {count}
<button
onClick={() => setCount(count - 1)}
className="px-4 py-2 bg-red-500 text-white rounded"
>
Decrease
<button
onClick={() => setCount(count + 1)}
className="px-4 py-2 bg-blue-500 text-white rounded"
>
Increase
);
},
"/styles.css": body {
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
margin: 0;
background: #f0f0f0;
}`
}
function CustomApp() { return ( ) } ```
🔧 API Reference
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| files | Record<string, string> | defaultReactFiles | Object containing file paths and their content |
| template | SandpackTemplate | "react-ts" | Sandpack template ("react", "react-ts", "vanilla", "vue", etc.) |
| title | string | "React Sandbox" | Title for the sandbox (used internally) |
| showTerminal | boolean | true | Whether to show the terminal section in code view |
Supported Templates
"react"- React with JavaScript"react-ts"- React with TypeScript"vanilla"- Pure HTML, CSS, JavaScript"vue"- Vue.js application"angular"- Angular application"svelte"- Svelte application"solid"- SolidJS application
🎨 Customization Guide
1. CSS Classes for Styling
The component uses specific CSS classes that you can override:
Border Management
```css /* Main component borders / .v0-sandpack-borders { border: 1px solid rgba(59, 130, 246, 0.3); / Add your custom border styles */ }
/* Internal section borders */ .v0-internal-border { border: 1px solid rgba(59, 130, 246, 0.15); }
/* Section separators */ .v0-section-border { border-top: 1px solid rgba(59, 130, 246, 0.2); } ```
Preview Tab Gradient
```css /* Active preview tab with gradient effect / .v0-preview-tab-active { background: linear-gradient(135deg, rgba(59, 130, 246, 0.2) 0%, rgba(147, 51, 234, 0.15) 25%, rgba(16, 185, 129, 0.1) 50%, rgba(59, 130, 246, 0.15) 75%, rgba(147, 51, 234, 0.2) 100%); / Customize gradient colors */ } ```
2. Theme Customization
Custom Color Scheme
```tsx const customTheme = { colors: { surface1: "#1a1a1a", // Main background surface2: "#2d2d2d", // Secondary background surface3: "#404040", // Tertiary background base: "#ffffff", // Text color accent: "#00ff88", // Your brand color hover: "#333333", // Hover states // ... other colors }, syntax: { plain: "#ffffff", comment: { color: "#6b7280", fontStyle: "italic" }, keyword: "#your-keyword-color", string: "#your-string-color", // ... other syntax colors } }
// Apply custom theme ```
Font Customization
```css .cm-editor { font-family: 'Your Custom Font', 'SF Mono', monospace; font-size: 15px; line-height: 1.6; }
.cm-lineNumbers { font-family: 'Your Custom Font', 'SF Mono', monospace; font-size: 13px; } ```
3. Layout Customization
Adjust File Explorer Width
```tsx // In your CSS .v0-sandpack-borders .flex > div:first-child { width: 200px; /* Adjust from default 176px (w-44) */ } ```
Terminal Height
```tsx // In your CSS .v0-sandpack-borders .h-48 { height: 300px; /* Adjust from default 192px (h-48) */ } ```
Custom Container Size
```tsx
4. Advanced Customization Examples
Custom Border Colors
```css :root { --v0-border-primary: rgba(255, 0, 128, 0.3); --v0-border-secondary: rgba(255, 0, 128, 0.15); --v0-accent-color: #ff0080; }
.v0-sandpack-borders { border-color: var(--v0-border-primary); }
.v0-internal-border { border-color: var(--v0-border-secondary); }
.v0-preview-tab-active { background: linear-gradient(135deg, rgba(255, 0, 128, 0.2) 0%, rgba(128, 0, 255, 0.15) 50%, rgba(255, 0, 128, 0.2) 100%); } ```
Custom Scrollbar Colors
```css .cm-editor .cm-scroller::-webkit-scrollbar-thumb { background: linear-gradient(135deg, #ff0080, #8000ff); } ```
🔨 Integration Examples
1. Next.js Integration
```tsx // pages/editor.tsx or app/editor/page.tsx 'use client' // For App Router
import dynamic from 'next/dynamic' import { useState } from 'react'
const V0Sandpack = dynamic(() => import('../components/v0-sandpack'), { ssr: false, loading: () => })
export default function EditorPage() { const [files, setFiles] = useState(defaultReactFiles)
return ( Code Editor ) } ```
2. With State Management
```tsx import { create } from 'zustand'
interface EditorStore { files: Record<string, string> activeTemplate: string updateFile: (path: string, content: string) => void setTemplate: (template: string) => void }
const useEditorStore = create((set) => ({ files: defaultReactFiles, activeTemplate: 'react-ts', updateFile: (path, content) => set((state) => ({ files: { ...state.files, [path]: content } })), setTemplate: (template) => set({ activeTemplate: template }) }))
function EditorWithStore() { const { files, activeTemplate, updateFile } = useEditorStore()
return ( ) } ```
3. AI Integration Example
```tsx interface AICodeGenerator { generateCode: (prompt: string) => Promise<Record<string, string>> }
function AICodeEditor() { const [files, setFiles] = useState(defaultReactFiles) const [isGenerating, setIsGenerating] = useState(false)
const handleAIGenerate = async (prompt: string) => { setIsGenerating(true) try { const aiGenerator = new AICodeGenerator() const generatedFiles = await aiGenerator.generateCode(prompt) setFiles(generatedFiles) } catch (error) { console.error('AI generation failed:', error) } finally { setIsGenerating(false) } }
return ( <input type="text" placeholder="Describe what you want to build..." onKeyDown={(e) => { if (e.key === 'Enter') { handleAIGenerate(e.currentTarget.value) } }} className="w-full p-3 rounded-lg bg-gray-800 text-white" />
{isGenerating && (
<div className="mb-4 text-center text-gray-400">
Generating code with AI...
</div>
)}
<V0Sandpack
files={files}
template="react-ts"
showTerminal={true}
/>
</div>) } ```
4. Multi-Project Manager
```tsx interface Project { id: string name: string files: Record<string, string> template: string }
function ProjectManager() { const [projects, setProjects] = useState<Project[]>([]) const [activeProject, setActiveProject] = useState<string | null>(null)
const createProject = (name: string, template: string) => { const newProject: Project = { id: Date.now().toString(), name, files: getTemplateFiles(template), template } setProjects(prev => [...prev, newProject]) setActiveProject(newProject.id) }
const currentProject = projects.find(p => p.id === activeProject)
return (
{/* Project Sidebar */}
Projects
{projects.map(project => (
<div
key={project.id}
onClick={() => setActiveProject(project.id)}
className={p-2 rounded cursor-pointer mb-2 ${
activeProject === project.id ? 'bg-blue-600' : 'bg-gray-700'
}}
>
{project.name}
))}
<button
onClick={() => createProject('New Project', 'react-ts')}
className="w-full p-2 bg-green-600 text-white rounded"
>
New Project
{/* Editor */}
<div className="flex-1 p-4">
{currentProject ? (
<V0Sandpack
files={currentProject.files}
template={currentProject.template}
title={currentProject.name}
showTerminal={true}
/>
) : (
<div className="text-center text-gray-400 mt-20">
Select or create a project to start coding
</div>
)}
</div>
</div>) } ```
🎭 Visual Effects Guide
1. Border Animations
```css /* Pulsing border effect */ .v0-sandpack-borders.pulse { animation: borderPulse 2s infinite; }
@keyframes borderPulse { 0%, 100% { box-shadow: 0 0 0 1px rgba(59, 130, 246, 0.3); } 50% { box-shadow: 0 0 0 1px rgba(59, 130, 246, 0.6), 0 0 20px rgba(59, 130, 246, 0.3); } } ```
2. Loading States
```tsx function LoadingEditor() { const [isLoading, setIsLoading] = useState(true)
useEffect(() => { setTimeout(() => setIsLoading(false), 2000) }, [])
if (isLoading) { return ( Loading editor... ) }
return } ```
3. Custom Hover Effects
```css /* Enhanced button hover effects */ .v0-sandpack-borders button:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3); transition: all 0.2s ease; }
/* File explorer item hover */ .sp-file-explorer .sp-file:hover { background: linear-gradient(90deg, rgba(59, 130, 246, 0.1), rgba(59, 130, 246, 0.05)); border-left: 2px solid #3b82f6; } ```
🔍 Troubleshooting
Common Issues
1. Component Not Rendering
```tsx // ❌ Wrong - missing height container
// ✅ Correct - proper container
2. Files Not Updating
```tsx // ❌ Wrong - mutating state directly files['/App.tsx'] = newContent
// ✅ Correct - creating new object setFiles(prev => ({ ...prev, '/App.tsx': newContent })) ```
3. TypeScript Errors
```tsx // ❌ Wrong - missing file extensions const files = { 'App': 'content', 'utils': 'content' }
// ✅ Correct - proper file paths const files = { '/App.tsx': 'content', '/utils.ts': 'content' } ```
4. Styling Issues
```css /* ❌ Wrong - overriding without specificity */ .cm-editor { background: red; }
/* ✅ Correct - proper specificity */ .v0-sandpack-borders .cm-editor { background: linear-gradient(135deg, #0a0a0a 0%, #0f0f0f 100%); } ```
Performance Optimization
1. Code Splitting
```tsx import { lazy, Suspense } from 'react'
const V0Sandpack = lazy(() => import('./v0-sandpack'))
function App() { return ( <Suspense fallback={Loading editor...}> ) } ```
2. Memoization
```tsx import { memo, useMemo } from 'react'
const MemoizedEditor = memo(V0Sandpack)
function EditorContainer({ rawFiles }) { const processedFiles = useMemo(() => processFiles(rawFiles), [rawFiles] )
return } ```
🚀 Best Practices
1. File Organization
``` src/ ├── components/ │ ├── v0-sandpack.tsx │ └── ui/ ├── templates/ │ ├── default-files.ts │ ├── template-manager.ts │ └── ai-integration.ts ├── styles/ │ └── sandpack-custom.css └── hooks/ └── use-sandpack.ts ```
2. Error Handling
```tsx function SafeEditor({ files }) { const [error, setError] = useState(null)
const handleError = (error: Error) => { console.error('Sandpack error:', error) setError(error.message) }
if (error) { return ( Editor Error: {error} <button onClick={() => setError(null)} className="mt-4 px-4 py-2 bg-red-600 text-white rounded" > Retry ) }
return ( ) } ```
3. Accessibility
```tsx ```
📚 Advanced Features
1. Custom File Icons
```tsx const fileIcons = { '.tsx': '⚛️', '.ts': '📘', '.js': '📜', '.css': '🎨', '.json': '📋' }
// Implement in file explorer ```
2. Collaborative Features
```tsx interface CollaborativeEditor { roomId: string userId: string onUserJoin: (user: User) => void onCodeChange: (change: CodeChange) => void } ```
3. Version Control
```tsx interface VersionControl { commits: Commit[] currentBranch: string createCommit: (message: string) => void switchBranch: (branch: string) => void } ```
📄 License
This component is built on top of Sandpack by CodeSandbox. Please refer to their license for usage terms.
🤝 Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📞 Support
- 📧 Email: [email protected]
- 💬 Discord: [Your Discord Server]
- 📖 Documentation: [Your Docs URL]
- 🐛 Issues: [GitHub Issues URL]
Built with ❤️ for the developer community
