Files
leptos-shadcn-ui/packages/signal-management/src/component_migration/component_helpers.rs
Peter Hanssens f6a72352c0 feat: Complete file size optimization - refactor 10 large files into 55 focused modules
- Refactored 6,741 lines across 10 large files into 55 focused modules
- All modules now under 300 lines for better LLM comprehension and maintainability
- Maintained full test coverage and functionality

Files refactored:
- packages/leptos/input/src/implementation_tests.rs (867 lines) → 6 modules
- packages/leptos/form/src/implementation_tests.rs (783 lines) → 5 modules
- packages/signal-management/src/signal_management_tests.rs (766 lines) → 7 modules
- packages/signal-management/src/simple_tests.rs (753 lines) → 7 modules
- packages/signal-management/src/lifecycle_tests.rs (648 lines) → 5 modules
- packages/leptos/input/src/tdd_tests.rs (663 lines) → 6 modules
- packages/leptos/command/src/tdd_tests.rs (607 lines) → 5 modules
- packages/signal-management/src/memory_management_tests.rs (554 lines) → 5 modules
- packages/signal-management/src/component_migration.rs (541 lines) → 4 modules
- packages/leptos/button/src/tdd_tests.rs (560 lines) → 5 modules

Added comprehensive remediation documentation in docs/remediation/
All tests passing - 132 tests for button component alone
2025-09-19 20:57:55 +10:00

269 lines
8.9 KiB
Rust

//! Component Migration Helpers Module
//!
//! This module provides helper functions for migrating specific components
//! to use ArcRwSignal and ArcMemo patterns.
use leptos::prelude::*;
use super::component_types::*;
/// Helper function to create a migrated button component
/// Migrates Button component to use ArcRwSignal and ArcMemo patterns
pub fn create_migrated_button_component() -> Option<()> {
// Create persistent signals using ArcRwSignal for state that needs to persist
let button_state = ArcRwSignal::new(ButtonState {
variant: ButtonVariant::Default,
size: ButtonSize::Default,
disabled: false,
loading: false,
});
// Create computed signal using ArcMemo for derived state
let button_state_for_class = button_state.clone();
let _button_class = ArcMemo::new(move |_| {
let state = button_state_for_class.get();
format!("button-{}-{}",
match state.variant {
ButtonVariant::Default => "default",
ButtonVariant::Destructive => "destructive",
ButtonVariant::Outline => "outline",
ButtonVariant::Secondary => "secondary",
ButtonVariant::Ghost => "ghost",
ButtonVariant::Link => "link",
},
match state.size {
ButtonSize::Default => "default",
ButtonSize::Sm => "sm",
ButtonSize::Lg => "lg",
ButtonSize::Icon => "icon",
}
)
});
// Create event handler with proper signal management
let _handle_click = {
let button_state = button_state.clone();
move || {
if !button_state.get().disabled && !button_state.get().loading {
// Update state atomically
button_state.update(|state| {
state.loading = true;
});
// Simulate async operation
// In real implementation, this would be an async operation
button_state.update(|state| {
state.loading = false;
});
}
}
};
Some(())
}
/// Helper function to create a migrated input component
/// Migrates Input component to use ArcRwSignal and ArcMemo patterns
pub fn create_migrated_input_component() -> Option<()> {
// Create persistent signals for input state
let input_state = ArcRwSignal::new(InputState {
value: String::new(),
placeholder: String::new(),
disabled: false,
error: None,
focused: false,
});
// Create computed validation state using ArcMemo
let input_state_for_validation = input_state.clone();
let _validation_state = ArcMemo::new(move |_| {
let state = input_state_for_validation.get();
ValidationState {
is_valid: state.error.is_none() && !state.value.is_empty(),
has_error: state.error.is_some(),
error_message: state.error.clone(),
}
});
// Create computed class using ArcMemo
let input_state_for_class = input_state.clone();
let validation_state_for_class = _validation_state.clone();
let _input_class = ArcMemo::new(move |_| {
let state = input_state_for_class.get();
let validation = validation_state_for_class.get();
format!("input-{}-{}",
if state.focused { "focused" } else { "unfocused" },
if validation.has_error { "error" } else { "valid" }
)
});
Some(())
}
/// Helper function to create a migrated card component
/// Migrates Card component to use ArcRwSignal and ArcMemo patterns
pub fn create_migrated_card_component() -> Option<()> {
// Create persistent signals for card state
let card_state = ArcRwSignal::new(CardState {
title: String::new(),
description: String::new(),
expanded: false,
loading: false,
});
// Create computed card class using ArcMemo
let _card_class = ArcMemo::new(move |_| {
let state = card_state.get();
format!("card-{}-{}",
if state.expanded { "expanded" } else { "collapsed" },
if state.loading { "loading" } else { "ready" }
)
});
Some(())
}
/// Helper function to create a migrated form component
/// Migrates Form component to use ArcRwSignal and ArcMemo patterns
pub fn create_migrated_form_component() -> Option<()> {
// Create persistent signals for form state
let form_state = ArcRwSignal::new(FormState {
fields: std::collections::HashMap::new(),
is_submitting: false,
is_valid: false,
errors: Vec::new(),
});
// Create computed form validation using ArcMemo
let _form_validation = ArcMemo::new(move |_| {
let state = form_state.get();
FormValidation {
can_submit: state.is_valid && !state.is_submitting,
has_errors: !state.errors.is_empty(),
error_count: state.errors.len(),
}
});
Some(())
}
/// Helper function to create a migrated table component
/// Migrates Table component to use ArcRwSignal and ArcMemo patterns
pub fn create_migrated_table_component() -> Option<()> {
// Create persistent signals for table state
let table_state = ArcRwSignal::new(TableState {
data: Vec::new(),
sort_column: None,
sort_direction: SortDirection::Asc,
selected_rows: std::collections::HashSet::new(),
page: 1,
page_size: 10,
});
// Create computed sorted data using ArcMemo
let _sorted_data = ArcMemo::new(move |_| {
let state = table_state.get();
// In real implementation, this would sort the data
state.data.clone()
});
Some(())
}
/// Helper function to create a migrated dialog component
/// Migrates Dialog component to use ArcRwSignal and ArcMemo patterns
pub fn create_migrated_dialog_component() -> Option<()> {
// Create persistent signals for dialog state
let dialog_state = ArcRwSignal::new(DialogState {
is_open: false,
title: String::new(),
content: String::new(),
can_close: true,
});
// Create computed dialog class using ArcMemo
let _dialog_class = ArcMemo::new(move |_| {
let state = dialog_state.get();
format!("dialog-{}-{}",
if state.is_open { "open" } else { "closed" },
if state.can_close { "closable" } else { "modal" }
)
});
Some(())
}
/// Helper function to create a migrated navigation component
/// Migrates Navigation component to use ArcRwSignal and ArcMemo patterns
pub fn create_migrated_navigation_component() -> Option<()> {
// Create persistent signals for navigation state
let nav_state = ArcRwSignal::new(NavigationState {
items: Vec::new(),
active_item: None,
collapsed: false,
mobile_open: false,
});
// Create computed navigation class using ArcMemo
let _nav_class = ArcMemo::new(move |_| {
let state = nav_state.get();
format!("nav-{}-{}",
if state.collapsed { "collapsed" } else { "expanded" },
if state.mobile_open { "mobile" } else { "desktop" }
)
});
Some(())
}
/// Helper function to create a migrated toast component
/// Migrates Toast component to use ArcRwSignal and ArcMemo patterns
pub fn create_migrated_toast_component() -> Option<()> {
// Create persistent signals for toast state
let toast_state = ArcRwSignal::new(ToastState {
message: String::new(),
variant: ToastVariant::Info,
duration: 5000,
is_visible: false,
});
// Create computed toast class using ArcMemo
let _toast_class = ArcMemo::new(move |_| {
let state = toast_state.get();
format!("toast-{}-{}",
match state.variant {
ToastVariant::Info => "info",
ToastVariant::Success => "success",
ToastVariant::Warning => "warning",
ToastVariant::Error => "error",
},
if state.is_visible { "visible" } else { "hidden" }
)
});
Some(())
}
/// Helper function to create a migrated calendar component
/// Migrates Calendar component to use ArcRwSignal and ArcMemo patterns
pub fn create_migrated_calendar_component() -> Option<()> {
// Create persistent signals for calendar state
let calendar_state = ArcRwSignal::new(CalendarState {
selected_date: None,
current_month: chrono::Local::now().date_naive(),
events: Vec::new(),
view_mode: CalendarView::Month,
});
// Create computed calendar data using ArcMemo
let _calendar_data = ArcMemo::new(move |_| {
let state = calendar_state.get();
CalendarData {
month: state.current_month,
selected: state.selected_date,
event_count: state.events.len(),
}
});
Some(())
}