code-environ
v0.1.2
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
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
- ⚡ Hot Reload: Instant updates as you type with auto-refresh on preview
- 🎯 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, 3D button animations, and enhanced hover states
- 📏 Perfect Alignment: Precisely aligned line numbers regardless of code length or line count
📦 Installation
For NPM Package Usage
If you're using this as an NPM package in your vibecoding webapp:
npm install @your-org/v0-sandpack
# or
yarn add @your-org/v0-sandpack
# or
pnpm add @your-org/v0-sandpackPrerequisites
Ensure you have React 18+ installed in your project:
npm install react@^18.0.0 react-dom@^18.0.0Core Dependencies (Auto-installed with package)
The package includes:
@codesandbox/sandpack-react- Core editor functionalitylucide-react- Icon library
Optional Dependencies (for enhanced styling)
npm install tailwindcss @tailwindcss/typographyTypeScript Support
If using TypeScript, install type definitions:
npm install -D @types/react @types/react-dom🎯 Quick Start
Basic Implementation in Your Vibecoding Webapp
import V0Sandpack from '@your-org/v0-sandpack'
import { defaultReactFiles } from '@your-org/v0-sandpack/templates'
function CodeEditorPage() {
return (
<div className="min-h-screen bg-gray-900 p-8">
<V0Sandpack
files={defaultReactFiles}
template="react-ts"
/>
</div>
)
}
export default CodeEditorPageNext.js Integration (App Router)
'use client'
import dynamic from 'next/dynamic'
import { defaultReactFiles } from '@your-org/v0-sandpack/templates'
const V0Sandpack = dynamic(
() => import('@your-org/v0-sandpack'),
{
ssr: false,
loading: () => (
<div className="h-[600px] bg-gray-900 animate-pulse rounded-xl" />
),
}
)
export default function EditorPage() {
return (
<div className="min-h-screen bg-gray-900 p-8">
<V0Sandpack
files={defaultReactFiles}
template="react-ts"
/>
</div>
)
}Custom File Configuration
const customFiles = {
"/App.tsx": `import React, { useState } from 'react';
export default function App() {
const [count, setCount] = useState(0);
return (
<div className="p-8 text-center">
<h1 className="text-2xl font-bold mb-4">Counter: {count}</h1>
<div className="space-x-4">
<button
onClick={() => setCount(count - 1)}
className="px-4 py-2 bg-red-500 text-white rounded"
>
Decrease
</button>
<button
onClick={() => setCount(count + 1)}
className="px-4 py-2 bg-blue-500 text-white rounded"
>
Increase
</button>
</div>
</div>
);
}`,
"/styles.css": `body {
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
margin: 0;
background: #f0f0f0;
}`
}
export default function CustomApp() {
return (
<V0Sandpack
files={customFiles}
template="react-ts"
title="Counter Application"
/>
)
}🔧 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 for accessibility) |
| className | string | undefined | Additional CSS classes for the root container |
| theme | SandpackTheme | v0DarkTheme | Custom theme configuration |
| sidebarWidth | number | 200 | Width of the file explorer sidebar in pixels |
| mobileDrawerWidth | number | 320 | Width of mobile file drawer in pixels |
| defaultSidebarCollapsed | boolean | false | Initial sidebar collapse state |
| enableSidebarCollapse | boolean | true | Allow sidebar collapse functionality |
| enableKeyboardShortcut | boolean | true | Enable Ctrl/Cmd+B for sidebar toggle |
| filesLabel | string | "Files" | Custom label for file explorer |
| searchLabel | string | "Search" | Custom label for search input |
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
🎨 Integration with Vibecoding Webapp
User Workflow Integration
The V0Sandpack component seamlessly integrates into your vibecoding platform with these key user interaction points:
1. Code Editing Flow
- Users write or paste code in the editor panel
- Code automatically recompiles with hot reload (configurable delay: 300ms)
- Changes instantly reflect in the preview panel
- Auto-refresh triggers when switching to Preview tab
2. File Management
- Desktop: Sidebar shows file tree with collapse functionality (Ctrl/Cmd+B shortcut)
- Mobile: Drawer-based file explorer for compact viewing
- Click line numbers to select entire lines
- Copy button saves entire file content to clipboard
- Download button exports all files as JSON
3. Preview Modes
- Code Tab: Full-featured editor with syntax highlighting, line numbers, and scrollbars
- Preview Tab: Live render of React component with auto-refresh on tab switch
- Terminal: Built-in console output (optional, can be toggled)
Typical Vibecoding Webapp Page Structure
import { useState } from 'react'
import V0Sandpack from '@your-org/v0-sandpack'
import { CodeTemplates } from '@your-org/v0-sandpack/templates'
interface UserProject {
id: string
name: string
files: Record<string, string>
template: string
}
export default function UserProjectEditor() {
const [project, setProject] = useState<UserProject>({
id: '1',
name: 'My App',
files: CodeTemplates.defaultReactFiles,
template: 'react-ts'
})
const handleFileUpdate = (newFiles: Record<string, string>) => {
setProject(prev => ({
...prev,
files: newFiles
}))
}
return (
<div className="flex flex-col h-screen">
{/* Header */}
<header className="bg-gray-800 border-b border-gray-700 p-4">
<h1 className="text-2xl font-bold text-white">{project.name}</h1>
</header>
{/* Editor */}
<main className="flex-1 overflow-hidden p-4">
<V0Sandpack
files={project.files}
template={project.template}
title={project.name}
enableSidebarCollapse={true}
enableKeyboardShortcut={true}
/>
</main>
{/* Footer Actions */}
<footer className="bg-gray-800 border-t border-gray-700 p-4 flex gap-4">
<button className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
Save Project
</button>
<button className="px-4 py-2 bg-gray-700 text-white rounded hover:bg-gray-600">
Share
</button>
</footer>
</div>
)
}Data Persistence
To save user projects in your webapp:
const saveUserProject = async (projectId: string, files: Record<string, string>) => {
const response = await fetch(`/api/projects/${projectId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ files })
})
return response.json()
}🎨 Customization Guide
1. CSS Classes for Styling
The component uses specific CSS classes that you can override in your webapp:
Border Management
/* Main component borders */
.v0-sandpack-borders {
border: 1px solid rgba(59, 130, 246, 0.3);
}
/* Internal section borders */
.v0-internal-border {
border: 1px solid rgba(59, 130, 246, 0.15);
}Theme Customization
const customTheme = {
colors: {