A powerful, flexible React-based prototyping environment for building and testing UI components with an interactive playground. Drag, drop, resize, and experiment with your designs in real-time. Built with React, TypeScript, Vite, and Tailwind CSS.
- 🖱️ Drag & Drop Interface - Intuitively position and rearrange components on the canvas
- 🌓 Theme Toggle - Seamlessly switch between light and dark modes with automatic theme-aware styling
- 📐 Adjustable Grid System - Fine-tune your layout with customizable grid sizes (8px - 64px)
- 📁 Media Upload - Upload and position images, videos, and GIFs directly on the canvas
- 🔧 Resizable Components - Dynamically resize media items with interactive handles
- 📦 Workspace Organization - Organize prototypes in dedicated workspaces for better project structure
- ⚡ Hot Module Replacement - Instant feedback with Vite's lightning-fast HMR
- 🎨 Flexible Styling - Use CSS, Tailwind CSS, or both together
- TypeScript First - Full type safety throughout the codebase
- Tailwind CSS v4 - Modern utility-first CSS framework with PostCSS integration
- Modern Build Tooling - Powered by Vite for optimal performance
- Modular Architecture - Clean separation between library code and playground
- Path Aliases - Convenient
@/alias for workspace imports - Dual Build System - Separate configs for library and playground builds
- CSS Custom Properties - Theme-aware CSS variables for consistent theming
- Node.js 18+
- pnpm (recommended) or npm/yarn
# Clone the repository
git clone <your-repo-url>
cd interface-prototyping-setup
# Install dependencies
pnpm installStart the development server:
pnpm devThe playground will automatically open at http://localhost:3000
pnpm build
pnpm build:playground
pnpm previewinterface-prototyping-setup/
├── playground/ # Development playground environment
│ ├── App.tsx # Main playground application
│ ├── App.css # Playground styles
│ ├── ConfigPanel.tsx # Configuration panel component
│ ├── ConfigPanel.css # Config panel styles
│ ├── Draggable.tsx # Drag & drop wrapper component
│ ├── MediaItem.tsx # Media display component
│ ├── MediaItem.css # Media item styles
│ ├── index.css # Global styles with Tailwind import
│ ├── index.html # HTML entry point
│ └── main.tsx # Playground entry point
│
├── src/ # Source code
│ ├── index.ts # Library entry point
│ └── workspaces/ # Prototype workspaces
│ └── workspace_1/ # Example workspace
│ ├── ExamplePrototype.tsx # CSS-based prototype
│ ├── ExamplePrototype2.tsx # Tailwind-based prototype
│ ├── Example.css # Custom CSS styles
│ └── index.ts # Workspace exports
│
├── tailwind.config.js # Tailwind CSS configuration
├── postcss.config.js # PostCSS configuration
├── vite.config.ts # Library build configuration
├── vite.playground.config.ts # Playground build configuration
└── tsconfig.*.json # TypeScript configurations
- Create a new workspace in
src/workspaces/:
mkdir -p src/workspaces/my_workspace- Create your prototype component (choose your styling approach):
// src/workspaces/my_workspace/MyPrototype.tsx
export const MyPrototype = () => {
return (
<div className="w-full p-6 max-w-md mx-auto bg-white dark:bg-gray-800 rounded-lg shadow-lg">
<h2 className="text-2xl font-bold text-gray-900 dark:text-white mb-4">
My Awesome Prototype
</h2>
<p className="text-gray-600 dark:text-gray-300 mb-6">
This uses Tailwind CSS utility classes!
</p>
<button className="px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-md transition-colors">
Click me!
</button>
</div>
);
};// src/workspaces/my_workspace/MyPrototype.tsx
import "./MyPrototype.css";
export const MyPrototype = () => {
return (
<div className="my-prototype">
<h1>My Awesome Prototype</h1>
<button>Click me!</button>
</div>
);
};/* src/workspaces/my_workspace/MyPrototype.css */
.my-prototype {
padding: 2rem;
background: var(--app-card-bg);
color: var(--app-text);
border-radius: 8px;
box-shadow: 0 2px 8px var(--app-shadow);
}You can combine Tailwind utilities with custom CSS classes for maximum flexibility!
- Export from workspace index:
// src/workspaces/my_workspace/index.ts
export { MyPrototype } from "./MyPrototype";- Import and use in playground:
// playground/App.tsx
import { MyPrototype } from "@/workspaces/my_workspace";
// In your App component:
<Draggable initialX={0} initialY={0}>
<MyPrototype />
</Draggable>- Import CSS in playground entry (only if using custom CSS):
// playground/main.tsx
import "@/workspaces/my_workspace/MyPrototype.css";Click the theme button in the config panel to switch between light and dark modes. The theme is applied globally using CSS custom properties and works seamlessly with Tailwind's dark: modifier.
- Click "Grid Size" in the config panel
- Adjust the slider to change grid size (8px - 64px)
- The grid helps align components precisely
- Click the "Upload" button in the config panel
- Select one or more image, video, or GIF files
- Media items appear on the canvas and can be:
- Dragged to reposition
- Resized using corner handles
- Removed using the delete button
- Click and drag any component wrapped in
<Draggable>to move it - Interactive elements (buttons, inputs, etc.) are excluded from drag behavior
- Components maintain their position during the session
The project includes Tailwind CSS v4 with PostCSS integration. You can use all Tailwind utility classes in your prototypes.
Tailwind's dark mode works automatically with the theme toggle:
<div className="bg-white dark:bg-gray-800 text-gray-900 dark:text-white">
Content that adapts to theme
</div>Customize Tailwind in tailwind.config.js:
export default {
content: ["./playground/**/*.{js,ts,jsx,tsx}", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {
// Add your custom theme extensions
},
},
plugins: [],
};The playground provides theme-aware CSS custom properties:
/* Light theme variables */
--app-bg: #f5f7fa;
--app-text: #333333;
--app-card-bg: #ffffff;
--app-border: #e0e0e0;
--app-shadow: rgba(0, 0, 0, 0.1);
--grid-color: rgba(0, 0, 0, 0.03);
--grid-size: 24px;
/* Dark theme variables */
--app-bg: #1a1a1a;
--app-text: #e0e0e0;
--app-card-bg: #2d2d2d;
--app-border: #404040;
--app-shadow: rgba(0, 0, 0, 0.3);
--grid-color: rgba(255, 255, 255, 0.03);Use them in your custom CSS:
.my-component {
background: var(--app-card-bg);
color: var(--app-text);
border: 1px solid var(--app-border);
box-shadow: 0 2px 8px var(--app-shadow);
}The grid size is controlled via CSS custom property --grid-size. It's automatically updated when you change the grid size in the config panel.
The @/ alias is configured to point to src/. Use it for clean imports:
import { MyComponent } from "@/workspaces/my_workspace";- Library build (
vite.config.ts): Configures the library build with TypeScript declarations - Playground build (
vite.playground.config.ts): Configures the development playground
Tailwind is configured to scan both playground/ and src/ directories. The configuration is in tailwind.config.js.
PostCSS is configured with:
@tailwindcss/postcss- Tailwind CSS v4 pluginautoprefixer- Automatic vendor prefixing
Change the playground port in vite.playground.config.ts:
server: {
port: 3000,
}pnpm buildOutputs:
dist/index.es.js- ES module builddist/index.umd.js- UMD builddist/index.d.ts- TypeScript declarationsdist/style.css- Compiled styles
pnpm build:playgroundOutputs a static site in playground/dist/ ready for deployment.
The project includes two example prototypes demonstrating different styling approaches:
- ExamplePrototype1 - Uses custom CSS with CSS custom properties
- ExamplePrototype2 - Uses Tailwind CSS utility classes
Both are available in src/workspaces/workspace_1/ and can be used as templates for your own prototypes.
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow TypeScript best practices
- Use meaningful component and variable names
- Add comments for complex logic
- Keep components focused and reusable
- Maintain consistent code formatting
- Choose the styling approach (CSS/Tailwind) that best fits your needs
| Command | Description |
|---|---|
pnpm dev |
Start development server |
pnpm build |
Build the library |
pnpm build:playground |
Build the playground |
pnpm preview |
Preview the built playground |
If port 3000 is already in use, change it in vite.playground.config.ts:
server: {
port: 3001,
}Ensure all workspace exports are properly typed and exported from their index.ts files.
- Custom CSS: Make sure to import CSS files in
playground/main.tsx - Tailwind: Ensure your classes are in files scanned by Tailwind (check
tailwind.config.jscontent paths)
- Verify your file is in the content paths in
tailwind.config.js - Check that
@import "tailwindcss";is inplayground/index.css - Restart the dev server after changing Tailwind config
MIT License - feel free to use this template for your projects!
Built with:
- React - UI library
- TypeScript - Type safety
- Vite - Build tool
- Tailwind CSS - Utility-first CSS framework
- PostCSS - CSS processing
- pnpm - Package manager
Happy Prototyping! 🚀
For questions, issues, or suggestions, please open an issue on GitHub.