mirror of
https://github.com/cloud-shuttle/leptos-shadcn-ui.git
synced 2025-12-22 22:00:00 +00:00
- 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
269 lines
8.9 KiB
Rust
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(())
|
|
}
|