# Phase 4: Cleanup & Polish - Make It Sexy ## Critical Issues to Fix ### 1. Debug Console UI Jank **Problem**: Page content shifts RIGHT when debug console opens (counter-intuitive) - Expected: Content shifts LEFT to make room - Current: Content margin-right increases, pushing content right **Fix**: ```css /* BEFORE (wrong) */ body.debug-open #app { margin-right: 420px; /* Pushes content right - bad! */ } /* AFTER (correct) */ body.debug-open #app { margin-right: 0; /* Keep in place or... */ /* OR shift left to center remaining space */ transform: translateX(-200px); } ``` ### 2. Un-Ritzy Toggle Implementation (CRITICAL) **Current (WRONG)**: JS manipulates DOM classes, WASM calls JS bridge function ```python # ANTI-PATTERN - calling JS to manipulate DOM! @external def js_toggle_debug_console(): pass def toggle(): js_toggle_debug_console() # ❌ JS does the work ``` **Correct (RITZY)**: Signal drives reactive class, declarative event binding ```python # THE RITZ WAY - declarative and reactive! console_open = signal(False) @event('keydown') # Declarative event registration def handle_keydown(event): if event.key == '`' and event.ctrlKey: console_open.value = not console_open.value def toggle(): """Button click handler""" console_open.value = not console_open.value # Reactive class binding (syntax TBD) with Div(class_=lambda: 'ritz-debug' if console_open else 'ritz-debug hidden'): # ...or maybe: # class_={'ritz-debug': True, 'hidden': not console_open} ``` **What this requires**: #### A. Reactive Class Binding - [ ] Parser support for lambda/function in class attribute - [ ] Codegen to track class dependencies on signals - [ ] Runtime bridge: `js_set_class(elem_id, class_string)` - [ ] Signal updates trigger class re-evaluation #### B. Declarative Event System (`@event` decorator) - [ ] `@event('keydown')` decorator in syntax.py - [ ] Parser recognizes @event and extracts event type - [ ] Codegen emits global event registration (not element-specific) - [ ] Runtime: `js_register_global_event(event_type, handler_name)` - [ ] JS passes event object to WASM with properties - [ ] WASM can access `event.key`, `event.ctrlKey`, etc. #### C. Event Object Bridge - [ ] Define event object structure (dict/struct in WASM) - [ ] JS serializes event properties to WASM memory - [ ] WASM handler receives event pointer - [ ] Helper functions: `event_get_key()`, `event_get_ctrl_key()`, etc. ## Framework Improvements Needed ### 3. Reactive Attribute System (Beyond Classes) Make ALL attributes reactive: ```python disabled = signal(False) with Button(disabled=disabled): yield "Click me" # When disabled changes, button.disabled updates automatically ``` **Implementation**: - [ ] Track attribute dependencies on signals - [ ] Generate update functions for each reactive attribute - [ ] Runtime bridge: `js_set_attribute_bool()`, `js_set_attribute_int()`, etc. ### 4. Testing Infrastructure **Problem**: No way to test Ritz code without manual browser testing **Solution A: Python Interpreter Mode** ```bash # Run Ritz components in pure Python for testing python3 -m ritz.test examples/highfive/HighFive.py # Output: # ✓ HighFive renders correctly # ✓ increment() updates signal # ✓ Button has correct onclick handler ``` Implementation: - [ ] Create `ritz/test_runtime.py` - Python VNode interpreter - [ ] Execute component functions, track signal changes - [ ] Assert on rendered VNode tree structure - [ ] Mock event handlers and verify signal updates **Solution B: LLVM Interpreter** ```bash # Execute LLVM IR directly (no WASM step) python3 -m ritz.test --llvm examples/highfive/HighFive.py # Uses: lli (LLVM interpreter) or llvm-python bindings ``` Implementation: - [ ] Mock JS bridge functions in C/LLVM - [ ] Execute LLVM IR with test assertions - [ ] Verify correct function calls and signal state **Solution C: Headless Browser Tests** ```bash # Full integration tests with Playwright/Puppeteer python3 -m ritz.test --browser examples/highfive/HighFive.py ``` Implementation: - [ ] Playwright/Puppeteer test harness - [ ] Load WASM in headless browser - [ ] Verify DOM structure and interactions - [ ] Snapshot testing for visual regression ### 5. Test Coverage Requirements **Unit Tests Needed**: - [ ] Parser: All AST node types - [ ] Parser: @component, @external, @event decorators - [ ] Codegen: Signal generation - [ ] Codegen: Event handler generation - [ ] Codegen: Reactive attributes - [ ] Codegen: Conditional rendering - [ ] Runtime: Signal updates - [ ] Runtime: Event dispatch - [ ] Runtime: DOM mutations **Integration Tests Needed**: - [ ] Counter component (signals + events) - [ ] Tabs component (match/case conditionals) - [ ] Forms (input binding, validation) - [ ] Debug console (global events, reactive classes) **Snapshot Tests**: - [ ] Generated LLVM IR (detect codegen regressions) - [ ] Generated WASM size (detect bloat) - [ ] Rendered HTML structure ## Code Quality & Consistency ### 6. Example App Consistency Update all examples to use: - [ ] RitzMain() convention - [ ] Main.wasm output - [ ] template.html (no custom HTML) - [ ] Shared styles.css - [ ] Component-specific styles in