#!/usr/bin/env python3 """ Batch Component Migration Script for Leptos 0.8.8 Signal Integration This script creates signal-managed versions of all components efficiently """ import os import subprocess import sys from pathlib import Path # Component batches by complexity SIMPLE_COMPONENTS = [ "separator", "skeleton", "badge", "avatar", "aspect-ratio", "label", "progress" ] MEDIUM_COMPONENTS = [ "textarea", "checkbox", "radio-group", "switch", "slider", "alert", "breadcrumb", "pagination", "tabs", "accordion", "collapsible", "resizable", "scroll-area", "popover", "tooltip", "hover-card" ] COMPLEX_COMPONENTS = [ "form", "table", "dialog", "sheet", "drawer", "dropdown-menu", "context-menu", "navigation-menu", "menubar", "command", "combobox", "select", "calendar", "date-picker", "toast", "alert-dialog", "carousel", "toggle", "input-otp" ] def create_signal_managed_component(component_name, complexity="medium"): """Create a signal-managed version of a component""" component_path = Path(f"packages/leptos/{component_name}") if not component_path.exists(): print(f"āš ļø Component {component_name} not found, skipping...") return False print(f"šŸ“¦ Migrating {component_name} (complexity: {complexity})...") # Add signal management dependency to Cargo.toml cargo_toml = component_path / "Cargo.toml" if cargo_toml.exists(): with open(cargo_toml, 'r') as f: content = f.read() if "leptos-shadcn-signal-management" not in content: # Add dependency lines = content.split('\n') deps_section = False for i, line in enumerate(lines): if line.strip() == "[dependencies]": deps_section = True elif deps_section and line.strip().startswith('[') and line.strip() != "[dependencies]": lines.insert(i, 'leptos-shadcn-signal-management = { path = "../../signal-management" }') break elif deps_section and line.strip() == "": lines.insert(i, 'leptos-shadcn-signal-management = { path = "../../signal-management" }') break with open(cargo_toml, 'w') as f: f.write('\n'.join(lines)) print(f" āž• Added signal management dependency") # Create signal_managed.rs signal_managed_path = component_path / "src" / "signal_managed.rs" # Generate component-specific template template = generate_component_template(component_name, complexity) with open(signal_managed_path, 'w') as f: f.write(template) print(f" šŸ”§ Created signal_managed.rs") # Update lib.rs lib_rs_path = component_path / "src" / "lib.rs" if lib_rs_path.exists(): with open(lib_rs_path, 'r') as f: content = f.read() if "pub mod signal_managed;" not in content: # Add module declaration lines = content.split('\n') for i, line in enumerate(lines): if line.strip().startswith("pub mod ") and not line.strip().startswith("pub mod signal_managed"): lines.insert(i, "pub mod signal_managed;") break # Add exports at the end if "pub use signal_managed::" not in content: lines.append("") lines.append("// Signal-managed exports") lines.append(f"pub use signal_managed::*;") with open(lib_rs_path, 'w') as f: f.write('\n'.join(lines)) print(f" šŸ“ Updated lib.rs exports") return True def generate_component_template(component_name, complexity): """Generate a template for the signal-managed component""" component_class = component_name.replace('-', '_').title() template = f'''//! Signal-managed version of the {component_name} component using leptos-shadcn-signal-management use leptos::prelude::*; use leptos_style::Style; use leptos_shadcn_signal_management::*; /// Signal-managed {component_name} state #[derive(Debug, Clone, PartialEq)] pub struct SignalManaged{component_class}State {{ pub is_active: bool, pub is_hovered: bool, pub is_focused: bool, pub click_count: u32, }} impl Default for SignalManaged{component_class}State {{ fn default() -> Self {{ Self {{ is_active: false, is_hovered: false, is_focused: false, click_count: 0, }} }} }} /// Signal-managed {component_name} component #[component] pub fn SignalManaged{component_class}( #[prop(into, optional)] class: MaybeProp, #[prop(into, optional)] id: MaybeProp, #[prop(into, optional)] style: Signal