UNPKG

pishposh

Version:
465 lines (435 loc) 15.5 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Bootstrap Utility API Generator</title> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; background: #f8f9fa; } .container { background: white; border-radius: 8px; padding: 30px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } h1 { color: #212529; margin-bottom: 30px; text-align: center; } .config-section { margin-bottom: 30px; padding: 20px; background: #f8f9fa; border-radius: 6px; border-left: 4px solid #007bff; } .config-section h3 { margin-top: 0; color: #495057; } textarea { width: 100%; min-height: 200px; padding: 15px; border: 1px solid #ced4da; border-radius: 4px; font-family: 'Monaco', 'Consolas', monospace; font-size: 14px; resize: vertical; } button { background: #007bff; color: white; border: none; padding: 12px 24px; border-radius: 4px; cursor: pointer; font-size: 16px; margin: 10px 5px; } button:hover { background: #0056b3; } .output { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 4px; padding: 20px; margin-top: 20px; max-height: 400px; overflow-y: auto; } .demo-area { margin-top: 30px; padding: 20px; border: 2px dashed #dee2e6; border-radius: 6px; } .demo-box { background: linear-gradient(45deg, #007bff, #6610f2); color: white; padding: 20px; border-radius: 4px; margin: 10px 0; text-align: center; } .controls { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; } .status { padding: 10px; border-radius: 4px; margin: 10px 0; font-weight: 500; } .status.success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; } .status.error { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; } </style> </head> <body> <div class="container"> <h1>Bootstrap Utility API Generator</h1> <div class="config-section"> <h3>Utility Configuration</h3> <p>Define your utility classes using Bootstrap's Utility API format:</p> <textarea id="configInput" placeholder="Enter your utility configuration..."> { "margin": { "property": "margin", "class": "m", "values": { "0": "0", "1": "0.25rem", "2": "0.5rem", "3": "1rem", "4": "1.5rem", "5": "3rem", "auto": "auto" } }, "padding": { "property": "padding", "class": "p", "values": { "0": "0", "1": "0.25rem", "2": "0.5rem", "3": "1rem", "4": "1.5rem", "5": "3rem" } }, "width": { "property": "width", "class": "w", "values": { "25": "25%", "50": "50%", "75": "75%", "100": "100%", "auto": "auto" } }, "text-color": { "property": "color", "class": "text", "values": { "primary": "#007bff", "secondary": "#6c757d", "success": "#28a745", "danger": "#dc3545", "warning": "#ffc107", "info": "#17a2b8", "light": "#f8f9fa", "dark": "#343a40", "white": "#fff" } }, "background-color": { "property": "background-color", "class": "bg", "values": { "primary": "#007bff", "secondary": "#6c757d", "success": "#28a745", "danger": "#dc3545", "warning": "#ffc107", "info": "#17a2b8", "light": "#f8f9fa", "dark": "#343a40", "white": "#fff" } } } </textarea> </div> <div class="controls"> <button onclick="generateUtilities()">Generate CSS</button> <button onclick="loadPreset('spacing')">Load Spacing Preset</button> <button onclick="loadPreset('colors')">Load Colors Preset</button> <button onclick="loadPreset('layout')">Load Layout Preset</button> <button onclick="clearConfig()">Clear</button> </div> <div id="status"></div> <div class="config-section"> <h3>Generated CSS</h3> <textarea id="cssOutput" readonly placeholder="Generated CSS will appear here..."></textarea> </div> <div class="demo-area"> <h3>Live Demo</h3> <p>The generated CSS is automatically applied. Test your utilities:</p> <div class="demo-box m-3 p-4 bg-primary text-white w-50"> Demo Element - Try adding classes like: m-2, p-3, bg-success, text-white, w-75 </div> <input type="text" id="demoClasses" placeholder="Enter classes to apply (e.g., m-4 p-2 bg-danger text-white w-100)" style="width: 100%; padding: 10px; margin: 10px 0;"> <button onclick="applyDemoClasses()">Apply Classes</button> </div> </div> <script> class BootstrapUtilityGenerator { constructor() { this.generatedCSS = ''; this.styleElement = null; this.init(); } init() { // Create a style element to inject generated CSS this.styleElement = document.createElement('style'); this.styleElement.id = 'generated-utilities'; document.head.appendChild(this.styleElement); } generateUtilities(config) { let css = ''; for (const [utilityName, utilityConfig] of Object.entries(config)) { const { property, class: className, values, responsive = false, directional = false } = utilityConfig; // Generate base utility classes for (const [key, value] of Object.entries(values)) { const selector = `.${className}-${key}`; css += `${selector} { ${property}: ${value} !important; }\n`; } // Generate responsive variants if enabled if (responsive) { const breakpoints = { 'sm': '576px', 'md': '768px', 'lg': '992px', 'xl': '1200px', 'xxl': '1400px' }; for (const [breakpoint, minWidth] of Object.entries(breakpoints)) { css += `@media (min-width: ${minWidth}) {\n`; for (const [key, value] of Object.entries(values)) { const selector = `.${className}-${breakpoint}-${key}`; css += ` ${selector} { ${property}: ${value} !important; }\n`; } css += '}\n'; } } // Generate directional utilities for spacing if (directional || property === 'margin' || property === 'padding') { const directions = { 't': `${property}-top`, 'b': `${property}-bottom`, 's': `${property}-start`, 'e': `${property}-end`, 'x': [`${property}-start`, `${property}-end`], 'y': [`${property}-top`, `${property}-bottom`] }; for (const [direction, props] of Object.entries(directions)) { for (const [key, value] of Object.entries(values)) { const selector = `.${className}${direction}-${key}`; if (Array.isArray(props)) { css += `${selector} { `; props.forEach(prop => { css += `${prop}: ${value} !important; `; }); css += '}\n'; } else { css += `${selector} { ${props}: ${value} !important; }\n`; } } } } } return css; } applyCSS(css) { this.generatedCSS = css; this.styleElement.textContent = css; } showStatus(message, type = 'success') { const statusDiv = document.getElementById('status'); statusDiv.innerHTML = `<div class="status ${type}">${message}</div>`; setTimeout(() => { statusDiv.innerHTML = ''; }, 3000); } } // Initialize the generator const generator = new BootstrapUtilityGenerator(); // Preset configurations const presets = { spacing: { "margin": { "property": "margin", "class": "m", "values": { "0": "0", "1": "0.25rem", "2": "0.5rem", "3": "1rem", "4": "1.5rem", "5": "3rem", "auto": "auto" }, "responsive": true }, "padding": { "property": "padding", "class": "p", "values": { "0": "0", "1": "0.25rem", "2": "0.5rem", "3": "1rem", "4": "1.5rem", "5": "3rem" }, "responsive": true } }, colors: { "text-color": { "property": "color", "class": "text", "values": { "primary": "#007bff", "secondary": "#6c757d", "success": "#28a745", "danger": "#dc3545", "warning": "#ffc107", "info": "#17a2b8", "light": "#f8f9fa", "dark": "#343a40", "white": "#fff", "muted": "#6c757d" } }, "background-color": { "property": "background-color", "class": "bg", "values": { "primary": "#007bff", "secondary": "#6c757d", "success": "#28a745", "danger": "#dc3545", "warning": "#ffc107", "info": "#17a2b8", "light": "#f8f9fa", "dark": "#343a40", "white": "#fff", "transparent": "transparent" } } }, layout: { "display": { "property": "display", "class": "d", "values": { "none": "none", "inline": "inline", "inline-block": "inline-block", "block": "block", "flex": "flex", "inline-flex": "inline-flex", "grid": "grid", "table": "table" }, "responsive": true }, "width": { "property": "width", "class": "w", "values": { "25": "25%", "50": "50%", "75": "75%", "100": "100%", "auto": "auto" } }, "height": { "property": "height", "class": "h", "values": { "25": "25%", "50": "50%", "75": "75%", "100": "100%", "auto": "auto" } } } }; function generateUtilities() { try { const configText = document.getElementById('configInput').value; const config = JSON.parse(configText); const css = generator.generateUtilities(config); document.getElementById('cssOutput').value = css; generator.applyCSS(css); generator.showStatus('✅ Utilities generated successfully!'); } catch (error) { generator.showStatus(`❌ Error: ${error.message}`, 'error'); } } function loadPreset(presetName) { if (presets[presetName]) { document.getElementById('configInput').value = JSON.stringify(presets[presetName], null, 2); generator.showStatus(`📋 ${presetName.charAt(0).toUpperCase() + presetName.slice(1)} preset loaded!`); } } function clearConfig() { document.getElementById('configInput').value = ''; document.getElementById('cssOutput').value = ''; generator.applyCSS(''); generator.showStatus('🗑️ Configuration cleared!'); } function applyDemoClasses() { const classes = document.getElementById('demoClasses').value; const demoBox = document.querySelector('.demo-box'); // Reset classes demoBox.className = 'demo-box'; // Apply new classes if (classes.trim()) { demoBox.className += ' ' + classes.trim(); } generator.showStatus(`🎨 Applied classes: ${classes}`); } // Generate initial utilities on page load window.addEventListener('load', () => { generateUtilities(); }); </script> </body> </html>