diff --git a/examples/techdemo/src/lib.rs b/examples/techdemo/src/lib.rs index df92778..07bf7d0 100644 --- a/examples/techdemo/src/lib.rs +++ b/examples/techdemo/src/lib.rs @@ -3,7 +3,9 @@ pub mod ui {} #[cfg(test)] mod tests { - use super::ui; + use super::ui::control_center::{forms, handles, slots}; + use super::ui::issue_card::handles as card_handles; + use super::ui::issue_lane::events as lane_events; use hemplate::Hemplate; use slhx::{Effect, IntoEffect, Payload, RenderSlotExt}; use slhx_test::inspect; @@ -28,14 +30,14 @@ mod tests { fn techdemo_uses_generated_slots_for_multi_target_updates() { fn update() -> impl IntoEffect { ( - ui::control_center::slots::hero_metrics.render(&FastMetric { label: "fast" }), - ui::control_center::slots::notice.text("typed"), + slots::hero_metrics.render(&FastMetric { label: "fast" }), + slots::notice.text("typed"), ) } let batch = inspect(update()); - assert!(batch.has_slot(ui::control_center::slots::hero_metrics)); - assert!(batch.has_slot(ui::control_center::slots::notice)); + assert!(batch.has_slot(slots::hero_metrics)); + assert!(batch.has_slot(slots::notice)); } // req: examples/001 req: form/001 req: form/004 req: form/006 req: derive_handler/003 @@ -43,34 +45,31 @@ mod tests { fn techdemo_form_handler_is_checked_against_hemplate_form() { #[slhx::handler] fn launch_work(_form: slhx::Form) -> impl IntoEffect { - ui::control_center::slots::notice.text("queued") + slots::notice.text("queued") } let batch = inspect(launch_work(LaunchWork::FORM)); - assert!(batch.has_slot(ui::control_center::slots::notice)); + assert!(batch.has_slot(slots::notice)); assert!(matches!(batch.ops(), [Effect::Put { payload: Payload::Text(_), .. }])); } // req: examples/001 req: form/002 req: codegen/003 #[test] fn techdemo_exports_form_and_interaction_handles() { - assert_ne!( - ui::control_center::handles::launch_work.id(), - ui::issue_card::handles::advance_work.id() - ); + assert_ne!(handles::launch_work.id(), card_handles::advance_work.id()); assert_eq!( - ui::control_center::forms::launch_work.field("title").resource, - ui::control_center::forms::launch_work.id() + forms::launch_work.field("title").resource, + forms::launch_work.id() ); } // req: codegen/006 #[test] fn techdemo_exports_generated_event_constants() { - assert_eq!(ui::issue_lane::events::drop.as_str(), "drop"); + assert_eq!(lane_events::drop.as_str(), "drop"); assert!(matches!( - slhx::event(ui::issue_lane::events::drop, "card-1"), + slhx::event(lane_events::drop, "card-1"), Effect::Emit { name, payload } if name == "drop" && payload == "card-1" )); } diff --git a/examples/techdemo/src/main.rs b/examples/techdemo/src/main.rs index 2a03197..aa95300 100644 --- a/examples/techdemo/src/main.rs +++ b/examples/techdemo/src/main.rs @@ -10,6 +10,9 @@ use slhx_axum::{ PageRequest, }; use slhx_techdemo::ui; +use slhx_techdemo::ui::control_center::{classes, forms, handles, slots}; +use slhx_techdemo::ui::issue_card::handles as card_handles; +use slhx_techdemo::ui::issue_lane::handles as lane_handles; use std::collections::{BTreeMap, VecDeque}; use std::convert::Infallible; use std::net::SocketAddr; @@ -266,13 +269,13 @@ async fn interact( // req: push/001 req: push/003 req: examples/001 async fn events(Query(params): Query>) -> impl IntoResponse { if params.contains_key("once") { - let effect = ui::control_center::slots::live_feed.render(&LiveFeed { tick: 1 }); + let effect = slots::live_feed.render(&LiveFeed { tick: 1 }); return sse(stream::iter([Ok::<_, Infallible>(effect.into_batch(ui::BUILD_FINGERPRINT))]).boxed()); } let batches = stream::unfold(1_u64, |tick| async move { tokio::time::sleep(Duration::from_secs(4)).await; - let effect = ui::control_center::slots::live_feed.render(&LiveFeed { tick }); + let effect = slots::live_feed.render(&LiveFeed { tick }); Some((Ok::<_, Infallible>(effect.into_batch(ui::BUILD_FINGERPRINT)), tick + 1)) }) .boxed(); @@ -281,7 +284,7 @@ async fn events(Query(params): Query>) -> impl IntoResp fn registry(shared: Arc) -> HandlerRegistry { HandlerRegistry::new(ui::BUILD_FINGERPRINT) - .register_handle(ui::control_center::handles::launch_work, { + .register_handle(handles::launch_work, { let shared = shared.clone(); move |form| { // req: form/002 req: examples/001 @@ -300,7 +303,7 @@ fn registry(shared: Arc) -> HandlerRegistry { demo_effects(&demo, "Launch accepted · 4 targets updated") } }) - .register_handle(ui::issue_card::handles::advance_work, { + .register_handle(card_handles::advance_work, { let shared = shared.clone(); move |form| { // req: list/003 req: examples/001 @@ -318,7 +321,7 @@ fn registry(shared: Arc) -> HandlerRegistry { demo_effects(&demo, "Pipeline advanced") } }) - .register_handle(ui::issue_lane::handles::move_to_lane, { + .register_handle(lane_handles::move_to_lane, { let shared = shared.clone(); move |form| { // req: list/003 req: examples/001 @@ -340,7 +343,7 @@ fn registry(shared: Arc) -> HandlerRegistry { demo_effects(&demo, "Drag-and-drop move persisted") } }) - .register_handle(ui::issue_card::handles::delete_work, { + .register_handle(card_handles::delete_work, { let shared = shared.clone(); move |form| { // req: list/003 req: examples/001 @@ -359,7 +362,7 @@ fn registry(shared: Arc) -> HandlerRegistry { demo_effects(&demo, "Card removed") } }) - .register_handle(ui::issue_card::handles::spotlight_work, { + .register_handle(card_handles::spotlight_work, { let shared = shared.clone(); move |form| { // req: examples/001 @@ -374,23 +377,23 @@ fn registry(shared: Arc) -> HandlerRegistry { demo_effects(&demo, "Inspector focused") } }) - .register_handle(ui::control_center::handles::simulate_push, { + .register_handle(handles::simulate_push, { let shared = shared.clone(); move |_| { // req: push/003 req: examples/001 let mut demo = shared.demo.lock().unwrap(); demo.log("Simulated push event produced the same EffectBatch shape"); ( - ui::control_center::slots::live_feed.render(&LiveFeed { + slots::live_feed.render(&LiveFeed { tick: demo.activity.len() as u64, }), - ui::control_center::slots::activity.render(&activity_view(&demo)), - ui::control_center::slots::notice.text("Push simulated · no client app code"), + slots::activity.render(&activity_view(&demo)), + slots::notice.text("Push simulated · no client app code"), slhx::event("slhx:island-orbit", island_snapshot(&demo)), ) } }) - .register_handle(ui::control_center::handles::reset_demo, { + .register_handle(handles::reset_demo, { let shared = shared.clone(); move |_| { // req: examples/001 @@ -411,12 +414,12 @@ fn update_work(demo: &mut DemoState, id: Option<&str>, update: impl FnOnce(&mut fn demo_effects(demo: &DemoState, notice: &'static str) -> impl IntoEffect { ( - ui::control_center::slots::hero_metrics.render(&hero_view(demo)), - ui::control_center::slots::board.html(render_board(demo)), - ui::control_center::slots::activity.render(&activity_view(demo)), - ui::control_center::slots::inspector.render(&inspector_view(demo)), - ui::control_center::slots::notice.text(notice), - ui::control_center::forms::launch_work.clear("title"), + slots::hero_metrics.render(&hero_view(demo)), + slots::board.html(render_board(demo)), + slots::activity.render(&activity_view(demo)), + slots::inspector.render(&inspector_view(demo)), + slots::notice.text(notice), + forms::launch_work.clear("title"), slhx::event("slhx:island-orbit", island_snapshot(demo)), ) } @@ -485,7 +488,7 @@ fn board_view(demo: &DemoState) -> BoardLanes { .iter() .enumerate() .map(|(idx, (lane_id, title, description))| IssueLane { - class: ui::control_center::classes::lane, + class: classes::lane, lane_id, title, description, @@ -510,11 +513,11 @@ fn issue_card(item: &WorkItem, selected: bool) -> IssueCard { IssueCard { class: if selected { CssClasses::from([ - ui::control_center::classes::work_card, - ui::control_center::classes::is_selected, + classes::work_card, + classes::is_selected, ]) } else { - CssClasses::from(ui::control_center::classes::work_card) + CssClasses::from(classes::work_card) }, id: item.id, title: item.title.clone(), @@ -584,7 +587,7 @@ fn architecture_activity() -> SafeHtml { fn render_control_center(page: ControlCenter) -> String { // req: html_safety/002 req: view/001 req: component/003 - ui::control_center::render_html(&page).into_string() + ui::render_html(&page).into_string() } fn render_template(template: &impl Hemplate) -> String { @@ -666,9 +669,9 @@ mod tests { #[test] fn generated_css_class_flows_through_hemplate_dynamic_attribute() { let board = render_board(&DemoState::default()); - assert_eq!(ui::control_center::classes::lane.as_str(), "lane"); - assert_eq!(ui::control_center::classes::work_card.as_str(), "work-card"); - assert_eq!(ui::control_center::classes::is_selected.as_str(), "is-selected"); + assert_eq!(classes::lane.as_str(), "lane"); + assert_eq!(classes::work_card.as_str(), "work-card"); + assert_eq!(classes::is_selected.as_str(), "is-selected"); let document = Html::parse_fragment(board.as_str()); assert_eq!(document.select(&selector(".lanes > section.lane")).count(), 3);