Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Is Gradio Svelte?</title> | |
| <!-- Icons --> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| :root { | |
| --gradio-orange: #ff7c00; | |
| --gradio-dark: #1f1f1f; | |
| --svelte-color: #ff3e00; | |
| --python-blue: #306998; | |
| --bg-light: #f3f4f6; | |
| --bg-dark: #0f172a; | |
| --text-main: #333; | |
| --text-light: #fff; | |
| --card-bg: rgba(255, 255, 255, 0.95); | |
| --card-bg-dark: rgba(30, 30, 30, 0.9); | |
| --glass-border: 1px solid rgba(255, 255, 255, 0.1); | |
| } | |
| * { | |
| box-sizing: box-box; | |
| margin: 0; | |
| padding: 0; | |
| font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; | |
| } | |
| body { | |
| background-color: var(--bg-light); | |
| color: var(--text-main); | |
| line-height: 1.6; | |
| overflow-x: hidden; | |
| } | |
| /* Header */ | |
| header { | |
| background: var(--bg-dark); | |
| color: white; | |
| padding: 1rem 2rem; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| border-bottom: 4px solid var(--gradio-orange); | |
| box-shadow: 0 4px 12px rgba(0,0,0,0.1); | |
| } | |
| .brand { | |
| font-size: 1.5rem; | |
| font-weight: 700; | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .brand i { | |
| color: var(--gradio-orange); | |
| } | |
| .anycoder-link { | |
| background: rgba(255, 255, 255, 0.1); | |
| padding: 8px 16px; | |
| border-radius: 8px; | |
| color: white; | |
| text-decoration: none; | |
| font-size: 0.9rem; | |
| transition: all 0.3s ease; | |
| border: 1px solid transparent; | |
| } | |
| .anycoder-link:hover { | |
| background: var(--gradio-orange); | |
| transform: translateY(-2px); | |
| box-shadow: 0 4px 12px rgba(255, 122, 0, 0.4); | |
| } | |
| /* Main Layout */ | |
| main { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 2rem; | |
| } | |
| /* Hero Section */ | |
| .hero { | |
| text-align: center; | |
| padding: 4rem 1rem; | |
| background: linear-gradient(135deg, #fff 50%, #f0f0f0 100%); | |
| border-radius: 20px; | |
| margin-bottom: 3rem; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .hero h1 { | |
| font-size: 3.5rem; | |
| margin-bottom: 1rem; | |
| background: -webkit-linear-gradient(45deg, var(--gradio-orange), var(--svelte-color)); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| font-weight: 800; | |
| } | |
| .hero p { | |
| font-size: 1.2rem; | |
| color: #666; | |
| max-width: 600px; | |
| margin: 0 auto; | |
| } | |
| .badge-container { | |
| display: inline-flex; | |
| gap: 10px; | |
| margin-top: 2rem; | |
| } | |
| .badge { | |
| padding: 8px 16px; | |
| border-radius: 50px; | |
| font-weight: 600; | |
| font-size: 0.9rem; | |
| box-shadow: 0 2px 8px rgba(0,0,0,0.1); | |
| } | |
| .badge-gradio { background: var(--gradio-orange); color: white; } | |
| .badge-svelte { background: var(--svelte-color); color: white; } | |
| .badge-python { background: var(--python-blue); color: white; } | |
| /* Content Grid */ | |
| .grid-section { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 2rem; | |
| margin-bottom: 3rem; | |
| } | |
| @media (max-width: 768px) { | |
| .grid-section { | |
| grid-template-columns: 1fr; | |
| } | |
| .hero h1 { font-size: 2.5rem; } | |
| } | |
| /* Cards */ | |
| .card { | |
| background: var(--card-bg); | |
| padding: 2rem; | |
| border-radius: 16px; | |
| box-shadow: 0 10px 30px rgba(0,0,0,0.05); | |
| transition: transform 0.3s ease; | |
| border: 1px solid rgba(0,0,0,0.05); | |
| } | |
| .card:hover { | |
| transform: translateY(-5px); | |
| } | |
| .card h3 { | |
| margin-bottom: 1rem; | |
| font-size: 1.5rem; | |
| color: var(--gradio-dark); | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .card i { color: var(--gradio-orange); } | |
| /* Code Visualizer */ | |
| .code-container { | |
| background: #1e1e1e; | |
| color: #d4d4d4; | |
| padding: 1.5rem; | |
| border-radius: 12px; | |
| font-family: 'Courier New', monospace; | |
| font-size: 0.9rem; | |
| overflow-x: auto; | |
| position: relative; | |
| border-left: 4px solid var(--python-blue); | |
| } | |
| .code-header { | |
| display: flex; | |
| justify-content: space-between; | |
| margin-bottom: 1rem; | |
| border-bottom: 1px solid #333; | |
| padding-bottom: 0.5rem; | |
| } | |
| .code-tab { | |
| padding: 4px 12px; | |
| background: #333; | |
| border-radius: 4px; | |
| cursor: pointer; | |
| transition: 0.2s; | |
| } | |
| .code-tab.active { | |
| background: var(--python-blue); | |
| color: white; | |
| } | |
| .svelte-tab.active { | |
| background: var(--svelte-color); | |
| } | |
| /* Architecture Diagram */ | |
| .arch-diagram { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| background: white; | |
| padding: 2rem; | |
| border-radius: 16px; | |
| box-shadow: 0 10px 30px rgba(0,0,0,0.05); | |
| margin-top: 2rem; | |
| position: relative; | |
| } | |
| .arch-node { | |
| text-align: center; | |
| padding: 1rem 2rem; | |
| background: #fff; | |
| border: 2px solid #eee; | |
| border-radius: 12px; | |
| font-weight: bold; | |
| position: relative; | |
| z-index: 2; | |
| box-shadow: 0 4px 6px rgba(0,0,0,0.05); | |
| transition: all 0.3s; | |
| } | |
| .arch-node:hover { | |
| border-color: var(--gradio-orange); | |
| transform: scale(1.05); | |
| } | |
| .arch-arrow { | |
| flex-grow: 1; | |
| height: 2px; | |
| background: #ddd; | |
| position: relative; | |
| margin: 0 10px; | |
| } | |
| .arch-arrow::after { | |
| content: ''; | |
| position: absolute; | |
| right: 0; | |
| top: -4px; | |
| width: 0; | |
| height: 0; | |
| border-left: 5px solid transparent; | |
| border-right: 5px solid transparent; | |
| border-top: 10px solid #ddd; | |
| } | |
| /* Interactive Demo Section */ | |
| .demo-section { | |
| background: #fff; | |
| border-radius: 16px; | |
| padding: 2rem; | |
| border: 1px solid #eee; | |
| } | |
| .gradio-mock { | |
| background: #f9f9f9; | |
| padding: 20px; | |
| border-radius: 8px; | |
| border: 1px solid #e0e0e0; | |
| margin-top: 1rem; | |
| } | |
| .gradio-input { | |
| width: 100%; | |
| padding: 10px; | |
| border: 1px solid #ccc; | |
| border-radius: 4px; | |
| margin-bottom: 10px; | |
| background: white; | |
| } | |
| .gradio-btn { | |
| background: var(--gradio-orange); | |
| color: white; | |
| padding: 10px 20px; | |
| border: none; | |
| border-radius: 4px; | |
| cursor: pointer; | |
| font-weight: 600; | |
| width: 100%; | |
| transition: opacity 0.2s; | |
| } | |
| .gradio-btn:hover { opacity: 0.9; } | |
| .output-box { | |
| background: #eee; | |
| padding: 10px; | |
| border-radius: 4px; | |
| font-family: monospace; | |
| color: #555; | |
| margin-top: 10px; | |
| min-height: 40px; | |
| } | |
| /* Footer */ | |
| footer { | |
| text-align: center; | |
| padding: 2rem; | |
| color: #888; | |
| font-size: 0.9rem; | |
| margin-top: 4rem; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <header> | |
| <div class="brand"> | |
| <i class="fa-solid fa-chart-simple"></i> | |
| Gradio Explorer | |
| </div> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" class="anycoder-link" target="_blank"> | |
| Built with anycoder <i class="fa-solid fa-arrow-right"></i> | |
| </a> | |
| </header> | |
| <main> | |
| <!-- Hero Section --> | |
| <section class="hero"> | |
| <div class="badge-container"> | |
| <span class="badge badge-gradio">Gradio</span> | |
| <span class="badge badge-svelte">Svelte</span> | |
| </div> | |
| <h1>Yes, Gradio is Svelte!</h1> | |
| <p>Gradio is a Python library for building ML UIs, but its frontend interface is powered by <strong>Svelte</strong> components.</p> | |
| <div style="margin-top: 2rem;"> | |
| <button onclick="toggleTheme()" class="badge badge-python" style="cursor:pointer; border:none;"> | |
| <i class="fa-solid fa-moon"></i> Toggle Dark Mode | |
| </button> | |
| </div> | |
| </section> | |
| <!-- Architecture Grid --> | |
| <div class="grid-section"> | |
| <div class="card"> | |
| <h3><i class="fa-brands fa-python"></i> The Backend</h3> | |
| <p>You write Python code to define the logic. Gradio wraps this logic into an API.</p> | |
| <div style="margin-top: 1rem; background: #f0f0f0; padding: 10px; border-radius: 4px; font-family: monospace;"> | |
| <code>import gradio as gr</code> | |
| </div> | |
| </div> | |
| <div class="card"> | |
| <h3><i class="fa-brands fa-react"></i> The Frontend</h3> | |
| <p>Gradio uses Svelte to render the UI components (Buttons, Textboxes, Plots). It handles the state management and reactivity efficiently.</p> | |
| <div style="margin-top: 1rem; background: #f0f0f0; padding: 10px; border-radius: 4px; font-family: monospace;"> | |
| <code>gr.Button("Click Me")</code> → <code><Button.svelte></code> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Code Visualization --> | |
| <div class="card" style="margin-bottom: 3rem;"> | |
| <h3><i class="fa-solid fa-code"></i> How they connect</h3> | |
| <div class="code-container"> | |
| <div class="code-header"> | |
| <span class="code-tab active" id="py-tab">Python (Logic)</span> | |
| <span class="code-tab" id="sv-tab">Svelte (UI)</span> | |
| </div> | |
| <div id="py-code"> | |
| <pre> | |
| import gradio as gr | |
| def greet(name): | |
| return "Hello " + name + "! from Python." | |
| with gr.Blocks() as demo: | |
| inp = gr.Textbox(label="Name") | |
| btn = gr.Button("Greet") | |
| out = gr.Textbox(label="Output") | |
| btn.click(greet, inp, out) | |
| demo.launch() | |
| </pre> | |
| </div> | |
| <div id="sv-code" style="display:none;"> | |
| <pre> | |
| <!-- Svelte Component Logic --> | |
| <script> | |
| let name = ""; | |
| let output = ""; | |
| function greet() { | |
| output = "Hello " + name + "! from Svelte."; | |
| // Fetches data from Python backend via WebSocket | |
| } | |
| </script> | |
| <input bind:value={name} placeholder="Name" /> | |
| <button on:click={greet}>Greet</button> | |
| <div>{output}</div> | |
| </pre> | |
| </div> | |
| </div> | |
| <p style="margin-top: 1rem; font-size: 0.9rem; color: #666;"> | |
| <i class="fa-solid fa-info-circle"></i> Click the tabs above to see how Gradio translates Python definitions into Svelte logic. | |
| </p> | |
| </div> | |
| <!-- Architecture Flow --> | |
| <div class="arch-diagram"> | |
| <div class="arch-node" style="border-color: var(--python-blue);"> | |
| Python Backend | |
| <div style="font-size: 0.8rem; color: #666;">Logic & API</div> | |
| </div> | |
| <div class="arch-arrow"></div> | |
| <div class="arch-node" style="border-color: var(--gradio-orange);"> | |
| Gradio Bridge | |
| <div style="font-size: 0.8rem; color: #666;">WebSockets / REST</div> | |
| </div> | |
| <div class="arch-arrow"></div> | |
| <div class="arch-node" style="border-color: var(--svelte-color);"> | |
| Svelte Frontend | |
| <div style="font-size: 0.8rem; color: #666;">UI Rendering</div> | |
| </div> | |
| </div> | |
| <!-- Interactive Mock --> | |
| <div class="demo-section"> | |
| <h3><i class="fa-solid fa-play"></i> Live Simulation</h3> | |
| <p>This interface is styled to look like Gradio, demonstrating the Svelte-like reactivity.</p> | |
| <div class="gradio-mock"> | |
| <label style="font-weight: bold; margin-bottom: 5px; display:block;">Input Textbox</label> | |
| <input type="text" class="gradio-input" id="mock-input" placeholder="Type something..."> | |
| <button class="gradio-btn" onclick="runMock()">Submit</button> | |
| <label style="font-weight: bold; margin-top: 15px; margin-bottom: 5px; display:block;">Output</label> | |
| <div class="output-box" id="mock-output">Waiting for input...</div> | |
| </div> | |
| </div> | |
| </main> | |
| <footer> | |
| Generated to answer: "Is Gradio Svelte?" <br> | |
| © 2023 Modern Web Concepts | |
| </footer> | |
| <script> | |
| // Tab Switching Logic | |
| const pyTab = document.getElementById('py-tab'); | |
| const svTab = document.getElementById('sv-tab'); | |
| const pyCode = document.getElementById('py-code'); | |
| const svCode = document.getElementById('sv-code'); | |
| pyTab.addEventListener('click', () => { | |
| pyTab.classList.add('active'); | |
| svTab.classList.remove('active'); | |
| pyCode.style.display = 'block'; | |
| svCode.style.display = 'none'; | |
| }); | |
| svTab.addEventListener('click', () => { | |
| svTab.classList.add('active'); | |
| pyTab.classList.remove('active'); | |
| pyCode.style.display = 'none'; | |
| svCode.style.display = 'block'; | |
| }); | |
| // Mock Gradio Interaction | |
| function runMock() { | |
| const input = document.getElementById('mock-input').value; | |
| const output = document.getElementById('mock-output'); | |
| if(!input) { | |
| output.innerText = "Error: Input required."; | |
| output.style.color = "red"; | |
| return; | |
| } | |
| output.innerText = "Processing..."; | |
| output.style.color = "#555"; | |
| // Simulate network delay (Python backend call) | |
| setTimeout(() => { | |
| output.innerText = `Processed: ${input} (via Svelte UI)`; | |
| output.style.background = "#e8f5e9"; | |
| output.style.color = "green"; | |
| }, 600); | |
| } | |
| // Dark Mode Toggle | |
| function toggleTheme() { | |
| const body = document.body; | |
| const currentBg = body.style.backgroundColor; | |
| if (currentBg === 'var(--bg-dark)' || currentBg === '#0f172a') { | |
| body.style.backgroundColor = 'var(--bg-light);'; | |
| body.style.color = 'var(--text-main);'; | |
| document.querySelectorAll('.card').forEach(c => { | |
| c.style.background = 'var(--card-bg);'; | |
| c.style.color = 'var(--text-main);'; | |
| }); | |
| } else { | |
| body.style.backgroundColor = 'var(--bg-dark);'; | |
| body.style.color = 'var(--text-light);'; | |
| document.querySelectorAll('.card').forEach(c => { | |
| c.style.background = 'var(--card-bg-dark);'; | |
| c.style.color = 'var(--text-light);'; | |
| c.style.border = '1px solid rgba(255,255,255,0.1);'; | |
| }); | |
| document.querySelector('.hero').style.background = 'linear-gradient(135deg, #1e1e1e 50%, #2a2a2a 100%);'; | |
| document.querySelector('.hero h1').style.color = 'white'; // Reset gradient text for dark mode visibility if needed, or keep gradient | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> |