| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Floral UI Builder</title> |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet"> |
| <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script> |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> |
| <script src="https://unpkg.com/feather-icons"></script> |
| <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&family=Open+Sans:wght@400;500&display=swap" rel="stylesheet"> |
| <style> |
| :root { |
| --primary-500: #4CAF50; |
| --primary-400: #8BC34A; |
| --primary-300: #AED581; |
| --accent-500: #FF80AB; |
| --accent-400: #FFB6C1; |
| --neutral-100: #F5F5F5; |
| --neutral-200: #EEEEEE; |
| --neutral-700: #616161; |
| --neutral-900: #212121; |
| } |
| |
| body { |
| font-family: 'Open Sans', sans-serif; |
| background-color: #f9fafb; |
| background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23aed581' fill-opacity='0.05' fill-rule='evenodd'/%3E%3C/svg%3E"); |
| } |
| |
| h1, h2, h3, h4, h5, h6 { |
| font-family: 'Poppins', sans-serif; |
| } |
| |
| .floral-divider { |
| position: relative; |
| height: 2px; |
| background: linear-gradient(90deg, transparent, var(--primary-300), transparent); |
| } |
| |
| .floral-divider::after { |
| content: "✿"; |
| position: absolute; |
| left: 50%; |
| top: 50%; |
| transform: translate(-50%, -50%); |
| background: #f9fafb; |
| padding: 0 10px; |
| color: var(--primary-500); |
| font-size: 14px; |
| } |
| |
| .component-item { |
| transition: all 0.2s ease; |
| border-left: 3px solid transparent; |
| } |
| |
| .component-item:hover { |
| background-color: rgba(76, 175, 80, 0.05); |
| border-left-color: var(--primary-500); |
| } |
| |
| .builder-canvas { |
| background-color: white; |
| box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); |
| min-height: 80vh; |
| } |
| |
| .toolbar-btn { |
| transition: all 0.2s ease; |
| } |
| |
| .toolbar-btn:hover { |
| background-color: rgba(76, 175, 80, 0.1); |
| } |
| |
| .droppable-area { |
| min-height: 100px; |
| border: 2px dashed var(--primary-300); |
| background-color: rgba(139, 195, 74, 0.05); |
| transition: all 0.2s ease; |
| } |
| |
| .droppable-area.highlight { |
| border-color: var(--primary-500); |
| background-color: rgba(139, 195, 74, 0.1); |
| } |
| </style> |
| </head> |
| <body class="h-screen flex flex-col"> |
| |
| <header class="bg-white border-b border-gray-200 px-4 py-3 flex items-center justify-between shadow-sm"> |
| <div class="flex items-center space-x-2"> |
| <div class="flex items-center"> |
| <i data-feather="cpu" class="text-green-500"></i> |
| <span class="ml-2 font-bold text-gray-800 text-lg">Floral UI Builder</span> |
| </div> |
| </div> |
| |
| <div class="flex items-center space-x-2"> |
| <button class="toolbar-btn flex items-center px-3 py-2 rounded-md text-gray-700 hover:text-green-600"> |
| <i data-feather="undo" class="w-4 h-4 mr-1"></i> |
| <span>Undo</span> |
| </button> |
| <button class="toolbar-btn flex items-center px-3 py-2 rounded-md text-gray-700 hover:text-green-600"> |
| <i data-feather="redo" class="w-4 h-4 mr-1"></i> |
| <span>Redo</span> |
| </button> |
| <div class="h-6 w-px bg-gray-300 mx-1"></div> |
| <button class="toolbar-btn flex items-center px-3 py-2 rounded-md text-gray-700 hover:text-green-600"> |
| <i data-feather="eye" class="w-4 h-4 mr-1"></i> |
| <span>Preview</span> |
| </button> |
| <button class="toolbar-btn flex items-center px-3 py-2 rounded-md bg-green-500 text-white hover:bg-green-600"> |
| <i data-feather="save" class="w-4 h-4 mr-1"></i> |
| <span>Save</span> |
| </button> |
| <button class="toolbar-btn flex items-center px-3 py-2 rounded-md bg-green-600 text-white hover:bg-green-700"> |
| <i data-feather="download" class="w-4 h-4 mr-1"></i> |
| <span>Export</span> |
| </button> |
| </div> |
| </header> |
| |
| <div class="flex flex-1 overflow-hidden"> |
| |
| <aside class="w-64 bg-white border-r border-gray-200 flex flex-col"> |
| <div class="px-4 py-3 border-b border-gray-200"> |
| <h3 class="font-medium text-gray-800 flex items-center"> |
| <i data-feather="grid" class="w-4 h-4 mr-2 text-green-500"></i> |
| Components |
| </h3> |
| </div> |
| |
| <div class="flex-1 overflow-y-auto p-2"> |
| <div class="mb-4"> |
| <h4 class="text-xs font-semibold text-gray-500 uppercase tracking-wider px-2 py-1">Basic</h4> |
| <div class="space-y-1 mt-1"> |
| <div class="component-item flex items-center px-3 py-2 rounded-md cursor-move"> |
| <i data-feather="type" class="w-4 h-4 mr-2 text-green-500"></i> |
| <span>Text</span> |
| </div> |
| <div class="component-item flex items-center px-3 py-2 rounded-md cursor-move"> |
| <i data-feather="image" class="w-4 h-4 mr-2 text-green-500"></i> |
| <span>Image</span> |
| </div> |
| <div class="component-item flex items-center px-3 py-2 rounded-md cursor-move"> |
| <i data-feather="square" class="w-4 h-4 mr-2 text-green-500"></i> |
| <span>Divider</span> |
| </div> |
| </div> |
| </div> |
| |
| <div class="mb-4"> |
| <h4 class="text-xs font-semibold text-gray-500 uppercase tracking-wider px-2 py-1">Forms</h4> |
| <div class="space-y-1 mt-1"> |
| <div class="component-item flex items-center px-3 py-2 rounded-md cursor-move"> |
| <i data-feather="edit" class="w-4 h-4 mr-2 text-green-500"></i> |
| <span>Input</span> |
| </div> |
| <div class="component-item flex items-center px-3 py-2 rounded-md cursor-move"> |
| <i data-feather="list" class="w-4 h-4 mr-2 text-green-500"></i> |
| <span>Select</span> |
| </div> |
| <div class="component-item flex items-center px-3 py-2 rounded-md cursor-move"> |
| <i data-feather="check-square" class="w-4 h-4 mr-2 text-green-500"></i> |
| <span>Checkbox</span> |
| </div> |
| <div class="component-item flex items-center px-3 py-2 rounded-md cursor-move"> |
| <i data-feather="toggle-left" class="w-4 h-4 mr-2 text-green-500"></i> |
| <span>Button</span> |
| </div> |
| </div> |
| </div> |
| |
| <div class="mb-4"> |
| <h4 class="text-xs font-semibold text-gray-500 uppercase tracking-wider px-2 py-1">Layout</h4> |
| <div class="space-y-1 mt-1"> |
| <div class="component-item flex items-center px-3 py-2 rounded-md cursor-move"> |
| <i data-feather="columns" class="w-4 h-4 mr-2 text-green-500"></i> |
| <span>Columns</span> |
| </div> |
| <div class="component-item flex items-center px-3 py-2 rounded-md cursor-move"> |
| <i data-feather="box" class="w-4 h-4 mr-2 text-green-500"></i> |
| <span>Container</span> |
| </div> |
| <div class="component-item flex items-center px-3 py-2 rounded-md cursor-move"> |
| <i data-feather="sidebar" class="w-4 h-4 mr-2 text-green-500"></i> |
| <span>Section</span> |
| </div> |
| </div> |
| </div> |
| |
| <div class="mb-4"> |
| <h4 class="text-xs font-semibold text-gray-500 uppercase tracking-wider px-2 py-1">Media</h4> |
| <div class="space-y-1 mt-1"> |
| <div class="component-item flex items-center px-3 py-2 rounded-md cursor-move"> |
| <i data-feather="video" class="w-4 h-4 mr-2 text-green-500"></i> |
| <span>Video</span> |
| </div> |
| <div class="component-item flex items-center px-3 py-2 rounded-md cursor-move"> |
| <i data-feather="map" class="w-4 h-4 mr-2 text-green-500"></i> |
| <span>Map</span> |
| </div> |
| <div class="component-item flex items-center px-3 py-2 rounded-md cursor-move"> |
| <i data-feather="sliders" class="w-4 h-4 mr-2 text-green-500"></i> |
| <span>Carousel</span> |
| </div> |
| </div> |
| </div> |
| </div> |
| </aside> |
| |
| |
| <main class="flex-1 overflow-auto bg-gray-50 p-6"> |
| <div class="max-w-6xl mx-auto"> |
| <div class="builder-canvas rounded-lg p-6"> |
| <div class="droppable-area rounded-lg p-4 mb-4"> |
| <p class="text-center text-gray-500">Drag components here to start building</p> |
| </div> |
| |
| |
| <div class="relative group mb-4 p-4 border border-gray-200 rounded-lg hover:border-green-300"> |
| <div class="absolute top-0 right-0 mt-2 mr-2 opacity-0 group-hover:opacity-100 flex space-x-1"> |
| <button class="p-1 rounded-full bg-white shadow text-gray-600 hover:text-green-500"> |
| <i data-feather="edit-2" class="w-3 h-3"></i> |
| </button> |
| <button class="p-1 rounded-full bg-white shadow text-gray-600 hover:text-red-500"> |
| <i data-feather="trash-2" class="w-3 h-3"></i> |
| </button> |
| </div> |
| <h2 class="text-2xl font-bold text-gray-800 mb-2">Welcome to Floral UI Builder</h2> |
| <p class="text-gray-600">Drag and drop components to create beautiful interfaces with our floral-inspired design system.</p> |
| </div> |
| |
| <div class="droppable-area rounded-lg p-4"> |
| <p class="text-center text-gray-500">Add more components below</p> |
| </div> |
| </div> |
| </div> |
| </main> |
| |
| |
| <aside class="w-72 bg-white border-l border-gray-200 p-4 overflow-y-auto"> |
| <div class="mb-6"> |
| <h3 class="font-medium text-gray-800 flex items-center"> |
| <i data-feather="sliders" class="w-4 h-4 mr-2 text-green-500"></i> |
| Properties |
| </h3> |
| <div class="floral-divider my-3"></div> |
| |
| <div class="space-y-4"> |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Background Color</label> |
| <div class="flex space-x-2"> |
| <div class="w-8 h-8 rounded-full bg-white border border-gray-300 cursor-pointer"></div> |
| <div class="w-8 h-8 rounded-full bg-green-50 border border-green-200 cursor-pointer"></div> |
| <div class="w-8 h-8 rounded-full bg-green-100 border border-green-300 cursor-pointer"></div> |
| <div class="w-8 h-8 rounded-full bg-pink-50 border border-pink-200 cursor-pointer"></div> |
| <div class="w-8 h-8 rounded-full bg-purple-50 border border-purple-200 cursor-pointer"></div> |
| </div> |
| </div> |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Padding</label> |
| <select class="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-green-500 focus:border-green-500 sm:text-sm rounded-md"> |
| <option>None</option> |
| <option selected>Small (16px)</option> |
| <option>Medium (24px)</option> |
| <option>Large (32px)</option> |
| </select> |
| </div> |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Border Radius</label> |
| <div class="flex items-center space-x-2"> |
| <input type="range" min="0" max="20" value="8" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer"> |
| <span class="text-xs text-gray-500 w-8">8px</span> |
| </div> |
| </div> |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Shadow</label> |
| <div class="grid grid-cols-3 gap-2"> |
| <button class="py-2 text-xs border rounded-md hover:border-green-300">None</button> |
| <button class="py-2 text-xs border rounded-md hover:border-green-300">Small</button> |
| <button class="py-2 text-xs border rounded-md bg-green-50 border-green-200 text-green-600">Medium</button> |
| <button class="py-2 text-xs border rounded-md hover:border-green-300">Large</button> |
| <button class="py-2 text-xs border rounded-md hover:border-green-300">XL</button> |
| <button class="py-2 text-xs border rounded-md hover:border-green-300">2XL</button> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| <div> |
| <h3 class="font-medium text-gray-800 flex items-center"> |
| <i data-feather="layers" class="w-4 h-4 mr-2 text-green-500"></i> |
| Layers |
| </h3> |
| <div class="floral-divider my-3"></div> |
| |
| <div class="space-y-2"> |
| <div class="flex items-center justify-between p-2 bg-green-50 rounded-md border border-green-200"> |
| <div class="flex items-center"> |
| <i data-feather="type" class="w-4 h-4 mr-2 text-green-600"></i> |
| <span class="text-sm">Heading Text</span> |
| </div> |
| <div class="flex space-x-1"> |
| <button class="p-1 text-gray-500 hover:text-green-600"> |
| <i data-feather="eye" class="w-3 h-3"></i> |
| </button> |
| <button class="p-1 text-gray-500 hover:text-green-600"> |
| <i data-feather="move" class="w-3 h-3"></i> |
| </button> |
| </div> |
| </div> |
| |
| <div class="flex items-center justify-between p-2 hover:bg-gray-50 rounded-md"> |
| <div class="flex items-center"> |
| <i data-feather="image" class="w-4 h-4 mr-2 text-blue-500"></i> |
| <span class="text-sm">Hero Image</span> |
| </div> |
| <div class="flex space-x-1"> |
| <button class="p-1 text-gray-500 hover:text-green-600"> |
| <i data-feather="eye" class="w-3 h-3"></i> |
| </button> |
| <button class="p-1 text-gray-500 hover:text-green-600"> |
| <i data-feather="move" class="w-3 h-3"></i> |
| </button> |
| </div> |
| </div> |
| |
| <div class="flex items-center justify-between p-2 hover:bg-gray-50 rounded-md"> |
| <div class="flex items-center"> |
| <i data-feather="columns" class="w-4 h-4 mr-2 text-purple-500"></i> |
| <span class="text-sm">Feature Grid</span> |
| </div> |
| <div class="flex space-x-1"> |
| <button class="p-1 text-gray-500 hover:text-green-600"> |
| <i data-feather="eye" class="w-3 h-3"></i> |
| </button> |
| <button class="p-1 text-gray-500 hover:text-green-600"> |
| <i data-feather="move" class="w-3 h-3"></i> |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
| </aside> |
| </div> |
|
|
| <script> |
| |
| AOS.init(); |
| |
| |
| feather.replace(); |
| |
| |
| document.addEventListener('DOMContentLoaded', function() { |
| const components = document.querySelectorAll('.component-item'); |
| const droppableAreas = document.querySelectorAll('.droppable-area'); |
| |
| components.forEach(component => { |
| component.addEventListener('dragstart', function(e) { |
| e.dataTransfer.setData('text/plain', component.querySelector('span').textContent); |
| setTimeout(() => { |
| component.classList.add('opacity-50'); |
| }, 0); |
| }); |
| |
| component.addEventListener('dragend', function() { |
| component.classList.remove('opacity-50'); |
| }); |
| }); |
| |
| droppableAreas.forEach(area => { |
| area.addEventListener('dragenter', function(e) { |
| e.preventDefault(); |
| this.classList.add('highlight'); |
| }); |
| |
| area.addEventListener('dragover', function(e) { |
| e.preventDefault(); |
| }); |
| |
| area.addEventListener('dragleave', function() { |
| this.classList.remove('highlight'); |
| }); |
| |
| area.addEventListener('drop', function(e) { |
| e.preventDefault(); |
| this.classList.remove('highlight'); |
| |
| const componentType = e.dataTransfer.getData('text/plain'); |
| const newComponent = createComponent(componentType); |
| |
| |
| if (this.querySelector('p')) { |
| this.insertBefore(newComponent, this.querySelector('p')); |
| } else { |
| this.appendChild(newComponent); |
| } |
| }); |
| }); |
| |
| function createComponent(type) { |
| const wrapper = document.createElement('div'); |
| wrapper.className = 'relative group mb-4 p-4 border border-gray-200 rounded-lg hover:border-green-300'; |
| wrapper.draggable = true; |
| wrapper.innerHTML = ` |
| <div class="absolute top-0 right-0 mt-2 mr-2 opacity-0 group-hover:opacity-100 flex space-x-1"> |
| <button class="p-1 rounded-full bg-white shadow text-gray-600 hover:text-green-500"> |
| <i data-feather="edit-2" class="w-3 h-3"></i> |
| </button> |
| <button class="p-1 rounded-full bg-white shadow text-gray-600 hover:text-red-500"> |
| <i data-feather="trash-2" class="w-3 h-3"></i> |
| </button> |
| </div> |
| <p class="text-gray-600">New ${type} component</p> |
| `; |
| |
| |
| wrapper.querySelector('button:nth-child(2)').addEventListener('click', function() { |
| wrapper.remove(); |
| }); |
| |
| return wrapper; |
| } |
| }); |
| </script> |
| </body> |
| </html> |
|
|