UNPKG

slidev-addon-notecell

Version:

A Slidev addon for interactive Jupyter notebook cells with code execution capabilities

278 lines (244 loc) 8.68 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>NoteCell Addon Test</title> <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 0; padding: 20px; background: #f8fafc; } .container { max-width: 1200px; margin: 0 auto; } .demo-section { background: white; border-radius: 8px; padding: 24px; margin-bottom: 24px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } .demo-title { font-size: 1.5rem; font-weight: 600; margin-bottom: 16px; color: #1f2937; } .demo-description { color: #6b7280; margin-bottom: 20px; } /* NoteCell Styles */ .wrapper-all { height: 400px; width: 100%; display: flex; flex-flow: column; overflow: auto; max-height: 450px; scrollbar-width: none; border: 1px solid #e5e7eb; border-radius: 6px; } .thebe-code { width: 100%; height: 100%; position: relative; } .thebe-code pre { margin: 0; padding: 16px; background: #f8fafc; border: none; border-radius: 6px 6px 0 0; font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-size: 14px; line-height: 1.5; overflow-x: auto; } .output-wrapper { flex-grow: 1; width: 100%; font-size: 0.9rem; overflow: auto; padding: 16px; scrollbar-width: none; background: white; border-top: 1px solid #e5e7eb; min-height: 100px; } .thebe-code:before { content: var(--pseudo-before-content, 'runnable'); background-color: #fbbf24; color: #92400e; padding: 4px 8px; text-align: center; border-radius: 4px; font-size: 0.75rem; font-weight: 500; z-index: 10; position: absolute; top: 8px; right: 8px; } .horizontal-layout { flex-flow: row; } .horizontal-layout .thebe-code { flex-grow: 1; width: auto; margin-right: 1rem; } .horizontal-layout .output-wrapper { width: 50%; border-top: none; border-left: 1px solid #e5e7eb; } .hide { display: none; } .status-indicator { padding: 8px 16px; background: #dbeafe; color: #1e40af; border-radius: 4px; font-size: 0.875rem; margin-bottom: 16px; } .mock-output { font-family: monospace; background: #f3f4f6; padding: 12px; border-radius: 4px; border-left: 4px solid #10b981; } </style> </head> <body> <div id="app"> <div class="container"> <h1>NoteCell Addon Test</h1> <p>This page demonstrates the NoteCell component functionality without requiring a full Slidev setup.</p> <div class="demo-section"> <h2 class="demo-title">Basic Vertical Layout</h2> <p class="demo-description">Double-click the code area to simulate execution</p> <mock-note-cell layout="vertical"> <pre><code>print("Hello from Jupyter!") print("This is an interactive code cell") # Simple calculation result = 2 + 2 print(f"2 + 2 = {result}")</code></pre> </mock-note-cell> </div> <div class="demo-section"> <h2 class="demo-title">Horizontal Layout</h2> <p class="demo-description">Code and output side by side</p> <mock-note-cell layout="horizontal"> <pre><code>import matplotlib.pyplot as plt import numpy as np # Generate sample data x = np.linspace(0, 10, 100) y = np.sin(x) # Create plot plt.figure(figsize=(8, 4)) plt.plot(x, y, 'b-', linewidth=2) plt.title('Sine Wave') plt.show()</code></pre> </mock-note-cell> </div> <div class="demo-section"> <h2 class="demo-title">Component Features</h2> <div class="status-indicator"> ✅ Interactive code execution simulation<br> ✅ Vertical and horizontal layouts<br> ✅ Toggle between code and output views<br> ✅ Status indicators (runnable/running)<br> ✅ Responsive design </div> </div> </div> </div> <script> const { createApp, ref, computed } = Vue; const MockNoteCell = { props: { layout: { type: String, default: 'vertical' } }, setup(props) { const isCodeHidden = ref(false); const isExecuting = ref(false); const hasOutput = ref(false); const mockOutput = ref(''); const onDoubleClick = async () => { if (hasOutput.value && !isCodeHidden.value) { // Toggle to output view isCodeHidden.value = true; return; } if (isCodeHidden.value) { // Toggle back to code view isCodeHidden.value = false; return; } // Simulate code execution isExecuting.value = true; // Simulate execution delay await new Promise(resolve => setTimeout(resolve, 2000)); // Generate mock output mockOutput.value = `Hello from Jupyter! This is an interactive code cell 2 + 2 = 4 [Execution completed in 0.123s]`; isExecuting.value = false; hasOutput.value = true; isCodeHidden.value = true; }; const statusText = computed(() => { if (isExecuting.value) return 'running'; if (hasOutput.value) return 'executed'; return 'runnable'; }); return { isCodeHidden, isExecuting, hasOutput, mockOutput, onDoubleClick, statusText }; }, template: ` <div class="wrapper-all" :class="{ 'horizontal-layout': layout === 'horizontal' }" @dblclick="onDoubleClick"> <div class="thebe-code" :class="{ hide: isCodeHidden }" :style="{ '--pseudo-before-content': "'" + statusText + "'" }"> <slot></slot> </div> <div class="output-wrapper" :class="{ hide: !isCodeHidden }"> <div v-if="isExecuting" class="mock-output"> <div>🔄 Executing code...</div> </div> <div v-else-if="hasOutput" class="mock-output"> <pre>{{ mockOutput }}</pre> </div> <div v-else class="mock-output"> <em>Output will appear here after execution</em> </div> </div> </div> ` }; createApp({ components: { MockNoteCell } }).mount('#app'); </script> </body> </html>