Parser: Support multiple components in one file, change args to params with defaults
This commit is contained in:
1 parent
635d466874
commit
81d51d5617
38 files changed
+2151
-455
No files matched your search
@@ -0,0 +1,133 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Toggle - Conditional Rendering - Ritz Framework</title>
|
||||
<link rel="stylesheet" href="../runtime/ritz-debug.css">
|
||||
<style>
|
||||
body {
|
||||
font-family: system-ui, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
#app {
|
||||
max-width: 800px;
|
||||
margin: 50px auto;
|
||||
padding: 40px;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
|
||||
}
|
||||
.toggle-app {
|
||||
text-align: center;
|
||||
}
|
||||
.toggle-app h1 {
|
||||
color: #667eea;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.toggle-app .info {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.toggle-app .controls {
|
||||
margin: 30px 0;
|
||||
}
|
||||
.toggle-app button {
|
||||
font-size: 18px;
|
||||
padding: 15px 40px;
|
||||
background: #667eea;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
font-weight: 600;
|
||||
}
|
||||
.toggle-app button:hover {
|
||||
background: #5568d3;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
|
||||
}
|
||||
.toggle-app button:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
.toggle-app .display {
|
||||
margin-top: 40px;
|
||||
min-height: 150px;
|
||||
}
|
||||
.toggle-app .high,
|
||||
.toggle-app .low {
|
||||
padding: 30px;
|
||||
border-radius: 8px;
|
||||
animation: fadeIn 0.3s;
|
||||
}
|
||||
.toggle-app .high {
|
||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
color: white;
|
||||
}
|
||||
.toggle-app .low {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
color: white;
|
||||
}
|
||||
.toggle-app .high p,
|
||||
.toggle-app .low p {
|
||||
margin: 10px 0;
|
||||
font-size: 18px;
|
||||
}
|
||||
.toggle-app .count {
|
||||
font-size: 36px;
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
}
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: scale(0.95); }
|
||||
to { opacity: 1; transform: scale(1); }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
<div id="ritz-debug" class="ritz-debug hidden">
|
||||
<div class="debug-header">
|
||||
<h3>🎭 Ritz Debug</h3>
|
||||
<button onclick="ritzDebug.toggle()">×</button>
|
||||
</div>
|
||||
<div id="status" class="status">Loading...</div>
|
||||
<div class="debug-content">
|
||||
<div class="debug-section">
|
||||
<h4>Component</h4>
|
||||
<pre>Toggle.py (Conditional Rendering)</pre>
|
||||
</div>
|
||||
<div class="debug-section">
|
||||
<h4>Features</h4>
|
||||
<pre>✓ if/else statements in WASM
|
||||
✓ Comparison operators (>)
|
||||
✓ Conditional DOM rendering
|
||||
✓ Signal-based conditions</pre>
|
||||
</div>
|
||||
<div class="debug-section">
|
||||
<h4>Console Commands</h4>
|
||||
<pre>ritzRuntime.getLog()
|
||||
ritzInstance.exports.get_count()
|
||||
ritzInstance.exports.increment()</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../runtime/ritz-runtime.js"></script>
|
||||
<script src="../runtime/ritz-debug.js"></script>
|
||||
<script>
|
||||
// Wait for DOM to be ready
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
new RitzLoader().load('Toggle.wasm', 'Toggle');
|
||||
});
|
||||
} else {
|
||||
new RitzLoader().load('Toggle.wasm', 'Toggle');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,192 @@
|
||||
; Generated by Ritz Framework with Signals
|
||||
; Component: Toggle
|
||||
|
||||
; String constants
|
||||
@.str.0 = private unnamed_addr constant [4 x i8] c"div\00"
|
||||
@.str.1 = private unnamed_addr constant [6 x i8] c"class\00"
|
||||
@.str.2 = private unnamed_addr constant [5 x i8] c"high\00"
|
||||
@.str.3 = private unnamed_addr constant [2 x i8] c"p\00"
|
||||
@.str.4 = private unnamed_addr constant [24 x i8] c"✨ Count is HIGH (> 5)\00"
|
||||
@.str.5 = private unnamed_addr constant [6 x i8] c"count\00"
|
||||
@.str.6 = private unnamed_addr constant [2 x i8] c"0\00"
|
||||
@.str.7 = private unnamed_addr constant [4 x i8] c"low\00"
|
||||
@.str.8 = private unnamed_addr constant [25 x i8] c"📉 Count is low (<= 5)\00"
|
||||
@.str.9 = private unnamed_addr constant [11 x i8] c"toggle-app\00"
|
||||
@.str.10 = private unnamed_addr constant [3 x i8] c"h1\00"
|
||||
@.str.11 = private unnamed_addr constant [27 x i8] c"Conditional Rendering Demo\00"
|
||||
@.str.12 = private unnamed_addr constant [5 x i8] c"info\00"
|
||||
@.str.13 = private unnamed_addr constant [44 x i8] c"This demonstrates if/else rendering in WASM\00"
|
||||
@.str.14 = private unnamed_addr constant [9 x i8] c"controls\00"
|
||||
@.str.15 = private unnamed_addr constant [7 x i8] c"button\00"
|
||||
@.str.16 = private unnamed_addr constant [6 x i8] c"click\00"
|
||||
@.str.17 = private unnamed_addr constant [10 x i8] c"increment\00"
|
||||
@.str.18 = private unnamed_addr constant [18 x i8] c"Increment Counter\00"
|
||||
@.str.19 = private unnamed_addr constant [8 x i8] c"display\00"
|
||||
|
||||
; Signal storage (reactive state in WASM memory)
|
||||
@signal_count = global i32 0
|
||||
|
||||
; Conditional rendering state
|
||||
@cond_0_parent = global i32 0
|
||||
@cond_0_marker = global i32 0
|
||||
@cond_0_current = global i32 0
|
||||
@cond_0_then_root = global i32 0
|
||||
@cond_0_else_root = global i32 0
|
||||
|
||||
; JavaScript bridge function declarations
|
||||
declare i32 @js_create_element(i8*)
|
||||
declare i32 @js_create_text(i8*)
|
||||
declare void @js_append_child(i32, i32)
|
||||
declare void @js_set_attribute(i32, i8*, i8*)
|
||||
declare void @js_set_root(i32)
|
||||
declare void @js_bind_event(i32, i8*, i8*)
|
||||
declare void @js_update_text_content(i32, i8*)
|
||||
declare i32 @js_create_marker()
|
||||
declare void @js_replace_at_marker(i32, i32, i32)
|
||||
|
||||
; Signal helper functions
|
||||
define i32 @get_count() {
|
||||
entry:
|
||||
%val = load i32, i32* @signal_count
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
define void @set_count(i32 %newval) {
|
||||
entry:
|
||||
store i32 %newval, i32* @signal_count
|
||||
; TODO: Trigger DOM update callback
|
||||
ret void
|
||||
}
|
||||
|
||||
; Event handler: increment
|
||||
define void @increment() {
|
||||
entry:
|
||||
%var0 = load i32, i32* @signal_count
|
||||
%var1 = add i32 %var0, 1
|
||||
store i32 %var1, i32* @signal_count
|
||||
call void @reevaluate_conditional_0()
|
||||
ret void
|
||||
}
|
||||
|
||||
; Conditional 0 - then branch
|
||||
define i32 @_render_cond_0_then() {
|
||||
entry:
|
||||
%var2 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0))
|
||||
call void @js_set_attribute(i32 %var2, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.2, i32 0, i32 0))
|
||||
%var3 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0))
|
||||
%var4 = call i32 @js_create_text(i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.4, i32 0, i32 0))
|
||||
call void @js_append_child(i32 %var3, i32 %var4)
|
||||
call void @js_append_child(i32 %var2, i32 %var3)
|
||||
%var5 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0))
|
||||
call void @js_set_attribute(i32 %var5, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.5, i32 0, i32 0))
|
||||
; TODO: Format f-string with signal count
|
||||
%var6 = call i32 @js_create_text(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.6, i32 0, i32 0))
|
||||
call void @js_append_child(i32 %var5, i32 %var6)
|
||||
call void @js_append_child(i32 %var2, i32 %var5)
|
||||
ret i32 %var2
|
||||
}
|
||||
|
||||
; Conditional 0 - else branch
|
||||
define i32 @_render_cond_0_else() {
|
||||
entry:
|
||||
%var7 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0))
|
||||
call void @js_set_attribute(i32 %var7, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.7, i32 0, i32 0))
|
||||
%var8 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0))
|
||||
%var9 = call i32 @js_create_text(i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.8, i32 0, i32 0))
|
||||
call void @js_append_child(i32 %var8, i32 %var9)
|
||||
call void @js_append_child(i32 %var7, i32 %var8)
|
||||
%var10 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0))
|
||||
call void @js_set_attribute(i32 %var10, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.5, i32 0, i32 0))
|
||||
; TODO: Format f-string with signal count
|
||||
%var11 = call i32 @js_create_text(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.6, i32 0, i32 0))
|
||||
call void @js_append_child(i32 %var10, i32 %var11)
|
||||
call void @js_append_child(i32 %var7, i32 %var10)
|
||||
ret i32 %var7
|
||||
}
|
||||
|
||||
; Initialize conditional 0 - render both branches
|
||||
define void @_init_conditional_0(i1 %cond) {
|
||||
entry:
|
||||
; Render both branches upfront
|
||||
%then_root = call i32 @_render_cond_0_then()
|
||||
%else_root = call i32 @_render_cond_0_else()
|
||||
store i32 %then_root, i32* @cond_0_then_root
|
||||
store i32 %else_root, i32* @cond_0_else_root
|
||||
%marker = load i32, i32* @cond_0_marker
|
||||
br i1 %cond, label %insert_then, label %insert_else
|
||||
insert_then:
|
||||
call void @js_replace_at_marker(i32 %marker, i32 0, i32 %then_root)
|
||||
store i32 1, i32* @cond_0_current
|
||||
ret void
|
||||
insert_else:
|
||||
call void @js_replace_at_marker(i32 %marker, i32 0, i32 %else_root)
|
||||
store i32 0, i32* @cond_0_current
|
||||
ret void
|
||||
}
|
||||
|
||||
; Re-evaluate conditional 0
|
||||
define void @reevaluate_conditional_0() {
|
||||
entry:
|
||||
%var12 = load i32, i32* @signal_count
|
||||
%var13 = icmp sgt i32 %var12, 5
|
||||
%var15 = load i32, i32* @cond_0_current
|
||||
%var16 = zext i1 %var13 to i32
|
||||
%var17 = icmp ne i32 %var15, %var16
|
||||
br i1 %var17, label %swap, label %done
|
||||
swap:
|
||||
br i1 %var13, label %swap_to_then, label %swap_to_else
|
||||
swap_to_then:
|
||||
%var18 = load i32, i32* @cond_0_else_root
|
||||
%var19 = load i32, i32* @cond_0_then_root
|
||||
%var20 = load i32, i32* @cond_0_marker
|
||||
call void @js_replace_at_marker(i32 %var20, i32 %var18, i32 %var19)
|
||||
store i32 1, i32* @cond_0_current
|
||||
br label %done
|
||||
swap_to_else:
|
||||
%var21 = load i32, i32* @cond_0_then_root
|
||||
%var22 = load i32, i32* @cond_0_else_root
|
||||
%var23 = load i32, i32* @cond_0_marker
|
||||
call void @js_replace_at_marker(i32 %var23, i32 %var21, i32 %var22)
|
||||
store i32 0, i32* @cond_0_current
|
||||
br label %done
|
||||
done:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Component render function
|
||||
define void @render_Toggle() {
|
||||
entry:
|
||||
%var24 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0))
|
||||
call void @js_set_attribute(i32 %var24, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.9, i32 0, i32 0))
|
||||
%var25 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.10, i32 0, i32 0))
|
||||
%var26 = call i32 @js_create_text(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @.str.11, i32 0, i32 0))
|
||||
call void @js_append_child(i32 %var25, i32 %var26)
|
||||
call void @js_append_child(i32 %var24, i32 %var25)
|
||||
%var27 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0))
|
||||
call void @js_set_attribute(i32 %var27, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.12, i32 0, i32 0))
|
||||
%var28 = call i32 @js_create_text(i8* getelementptr inbounds ([44 x i8], [44 x i8]* @.str.13, i32 0, i32 0))
|
||||
call void @js_append_child(i32 %var27, i32 %var28)
|
||||
call void @js_append_child(i32 %var24, i32 %var27)
|
||||
%var29 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0))
|
||||
call void @js_set_attribute(i32 %var29, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.14, i32 0, i32 0))
|
||||
%var30 = call i32 @js_create_element(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.15, i32 0, i32 0))
|
||||
call void @js_bind_event(i32 %var30, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.16, i32 0, i32 0), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.17, i32 0, i32 0))
|
||||
%var31 = call i32 @js_create_text(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.18, i32 0, i32 0))
|
||||
call void @js_append_child(i32 %var30, i32 %var31)
|
||||
call void @js_append_child(i32 %var29, i32 %var30)
|
||||
call void @js_append_child(i32 %var24, i32 %var29)
|
||||
%var32 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0))
|
||||
call void @js_set_attribute(i32 %var32, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.19, i32 0, i32 0))
|
||||
%var33 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0))
|
||||
%var34 = call i32 @js_create_marker()
|
||||
call void @js_append_child(i32 %var33, i32 %var34)
|
||||
store i32 %var34, i32* @cond_0_marker
|
||||
store i32 %var33, i32* @cond_0_parent
|
||||
%var35 = load i32, i32* @signal_count
|
||||
%var36 = icmp sgt i32 %var35, 5
|
||||
call void @_init_conditional_0(i1 %var36)
|
||||
call void @js_append_child(i32 %var32, i32 %var33)
|
||||
call void @js_append_child(i32 %var24, i32 %var32)
|
||||
call void @js_set_root(i32 %var24)
|
||||
ret void
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
"""
|
||||
Toggle component - Demonstrates conditional rendering with if statements.
|
||||
|
||||
This component uses a signal with comparison to conditionally render content.
|
||||
"""
|
||||
|
||||
from ritz.syntax import *
|
||||
|
||||
|
||||
@component
|
||||
def Toggle():
|
||||
"""Counter that shows different content based on threshold."""
|
||||
count = signal(0)
|
||||
|
||||
def increment():
|
||||
count += 1
|
||||
|
||||
with Div(class_="toggle-app"):
|
||||
with H1():
|
||||
yield "Conditional Rendering Demo"
|
||||
|
||||
with P(class_="info"):
|
||||
yield "This demonstrates if/else rendering in WASM"
|
||||
|
||||
with Div(class_="controls"):
|
||||
with Button(onclick=increment):
|
||||
yield "Increment Counter"
|
||||
|
||||
with Div(class_="display"):
|
||||
if count > 5:
|
||||
with Div(class_="high"):
|
||||
with P():
|
||||
yield "✨ Count is HIGH (> 5)"
|
||||
with P(class_="count"):
|
||||
yield f"Current count: {count}"
|
||||
else:
|
||||
with Div(class_="low"):
|
||||
with P():
|
||||
yield "📉 Count is low (<= 5)"
|
||||
with P(class_="count"):
|
||||
yield f"Current count: {count}"
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,131 @@
|
||||
/* Ritz Debug Bar Styles */
|
||||
|
||||
.ritz-debug {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 400px;
|
||||
height: 100vh;
|
||||
background: #1e1e1e;
|
||||
color: #d4d4d4;
|
||||
font-family: 'Consolas', 'Monaco', monospace;
|
||||
font-size: 13px;
|
||||
box-shadow: -2px 0 10px rgba(0,0,0,0.3);
|
||||
transition: transform 0.3s ease;
|
||||
z-index: 9999;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.ritz-debug.hidden {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
.debug-header {
|
||||
background: #252525;
|
||||
padding: 15px;
|
||||
border-bottom: 1px solid #3e3e3e;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.debug-header h3 {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.debug-header button {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #d4d4d4;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.debug-header button:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.status {
|
||||
margin: 15px;
|
||||
padding: 10px;
|
||||
background: #2d2d30;
|
||||
border-left: 3px solid #007acc;
|
||||
border-radius: 3px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.status.success {
|
||||
border-left-color: #4ec9b0;
|
||||
}
|
||||
|
||||
.status.error {
|
||||
border-left-color: #f48771;
|
||||
color: #f48771;
|
||||
}
|
||||
|
||||
.debug-content {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.debug-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.debug-section h4 {
|
||||
margin: 0 0 10px 0;
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
color: #858585;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.debug-section pre {
|
||||
background: #252525;
|
||||
padding: 10px;
|
||||
border-radius: 3px;
|
||||
overflow-x: auto;
|
||||
margin: 0;
|
||||
font-size: 11px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Toggle hint */
|
||||
.debug-toggle-hint {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
background: #252525;
|
||||
color: #d4d4d4;
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
font-family: 'Consolas', 'Monaco', monospace;
|
||||
font-size: 11px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
||||
opacity: 0;
|
||||
animation: fadeInOut 3s ease-in-out;
|
||||
pointer-events: none;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
@keyframes fadeInOut {
|
||||
0%, 100% { opacity: 0; }
|
||||
10%, 90% { opacity: 1; }
|
||||
}
|
||||
|
||||
/* App container default styles */
|
||||
#app {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
transition: margin-right 0.3s ease;
|
||||
}
|
||||
|
||||
body.debug-open #app {
|
||||
margin-right: 400px;
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Ritz Debug Bar Controller
|
||||
*/
|
||||
|
||||
class RitzDebug {
|
||||
constructor() {
|
||||
this.debugBar = document.getElementById('ritz-debug');
|
||||
this.isOpen = false;
|
||||
|
||||
// Setup keyboard shortcut (Ctrl+`)
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.ctrlKey && e.key === '`') {
|
||||
e.preventDefault();
|
||||
this.toggle();
|
||||
}
|
||||
});
|
||||
|
||||
// Show hint on first load
|
||||
this.showHint();
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.isOpen = !this.isOpen;
|
||||
|
||||
if (this.debugBar) {
|
||||
if (this.isOpen) {
|
||||
this.debugBar.classList.remove('hidden');
|
||||
document.body.classList.add('debug-open');
|
||||
} else {
|
||||
this.debugBar.classList.add('hidden');
|
||||
document.body.classList.remove('debug-open');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open() {
|
||||
this.isOpen = true;
|
||||
if (this.debugBar) {
|
||||
this.debugBar.classList.remove('hidden');
|
||||
document.body.classList.add('debug-open');
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
this.isOpen = false;
|
||||
if (this.debugBar) {
|
||||
this.debugBar.classList.add('hidden');
|
||||
document.body.classList.remove('debug-open');
|
||||
}
|
||||
}
|
||||
|
||||
showHint() {
|
||||
// Show toggle hint for 3 seconds
|
||||
const hint = document.createElement('div');
|
||||
hint.className = 'debug-toggle-hint';
|
||||
hint.textContent = 'Press Ctrl+` to toggle debug';
|
||||
document.body.appendChild(hint);
|
||||
|
||||
setTimeout(() => {
|
||||
hint.remove();
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
log(message, type = 'info') {
|
||||
const status = document.getElementById('status');
|
||||
if (status) {
|
||||
status.textContent = message;
|
||||
status.className = 'status ' + type;
|
||||
}
|
||||
console.log(`[Ritz] ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize debug controller
|
||||
const ritzDebug = new RitzDebug();
|
||||
|
||||
// Export
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = RitzDebug;
|
||||
} else {
|
||||
window.RitzDebug = RitzDebug;
|
||||
window.ritzDebug = ritzDebug;
|
||||
}
|
||||
Reference in new issue
Block a user