diff --git a/app/src/app.rs b/app/src/app.rs index a756187..5ea7bf0 100644 --- a/app/src/app.rs +++ b/app/src/app.rs @@ -21,7 +21,7 @@ use registry::hooks::use_data_scrolled::DATA_SCROLL_TARGET; #[cfg(target_arch = "wasm32")] use registry::hooks::use_scroll_lock; use registry::hooks::use_theme_mode::ThemeMode; -use registry::ui::sonner::SonnerToaster; +use registry::ui::sonner::{SonnerToaster, provide_sonner}; use registry::ui::toast_custom::toaster::{Toaster, provide_toaster}; use crate::components::navigation::app_wrapper::AppWrapper; @@ -57,6 +57,7 @@ pub fn App() -> impl IntoView { use_scroll_lock::init(); provide_toaster(); + provide_sonner(); let theme_mode = ThemeMode::init(); diff --git a/app/src/domain/docs/routing/docs_layout.rs b/app/src/domain/docs/routing/docs_layout.rs index 4195dac..3b79ac4 100644 --- a/app/src/domain/docs/routing/docs_layout.rs +++ b/app/src/domain/docs/routing/docs_layout.rs @@ -14,7 +14,7 @@ use crate::utils::page_transition::{PAGE_OUTLET, retrigger_page_fade}; #[derive(Clone)] pub struct DocsTocContext { - pub toc_items: RwSignal>, + pub toc_items: ArcRwSignal>, } #[component] @@ -23,7 +23,7 @@ pub fn DocsLayout() -> impl IntoView { let params_demo_name = ParamsUtils::extract(PARAM::NAME); let params_demo_name_arc = Arc::new(params_demo_name); - let toc_items = RwSignal::new(Vec::::new()); + let toc_items: ArcRwSignal> = RwSignal::new(Vec::::new()).into(); let toc_context = DocsTocContext { toc_items }; provide_context(toc_context.clone()); diff --git a/app/src/domain/markdown_ui/components/md_shared_with_toc.rs b/app/src/domain/markdown_ui/components/md_shared_with_toc.rs index e20485a..2df1ead 100644 --- a/app/src/domain/markdown_ui/components/md_shared_with_toc.rs +++ b/app/src/domain/markdown_ui/components/md_shared_with_toc.rs @@ -8,7 +8,7 @@ use crate::domain::markdown_ui::components::md_skeleton::MdSkeletonDemo; #[component] pub fn SharedDemoMdWithToc( md_path: &'static str, - #[prop(into)] toc_signal: WriteSignal>, + #[prop(into)] toc_signal: ArcWriteSignal>, ) -> impl IntoView { let md_file_resource = Resource::new(|| (), move |_| async move { read_md_file_typed(md_path.to_string()).await }); diff --git a/app/src/domain/markdown_ui/components/resizable_wrapper.rs b/app/src/domain/markdown_ui/components/resizable_wrapper.rs index 72eaaa4..875f2dc 100644 --- a/app/src/domain/markdown_ui/components/resizable_wrapper.rs +++ b/app/src/domain/markdown_ui/components/resizable_wrapper.rs @@ -9,13 +9,17 @@ use crate::domain::markdown_ui::components::my_resizable::{ /* ========================================================== */ #[component] -pub fn ResizableWrapper(children: Children, #[prop(into, optional)] preview_class: String) -> impl IntoView { +pub fn ResizableWrapper( + children: Children, + #[prop(into, optional)] preview_class: String, + #[prop(into, optional)] demo_name: String, +) -> impl IntoView { let preview_classes = format!("flex justify-center items-center w-full min-h-[370px] {}", preview_class); view! { -
+
{children()}
diff --git a/app/src/domain/markdown_ui/components/static_demo_wrapper.rs b/app/src/domain/markdown_ui/components/static_demo_wrapper.rs index 1d9085f..7c0c750 100644 --- a/app/src/domain/markdown_ui/components/static_demo_wrapper.rs +++ b/app/src/domain/markdown_ui/components/static_demo_wrapper.rs @@ -140,7 +140,7 @@ pub fn StaticDemoWrapper(demo_type: MarkdownType, children: Children) -> impl In // TODO 🚑 Show does not work at the moment. Using display as shortfix solution.
- {children_view} + {children_view}
diff --git a/app/src/domain/tests/drawer_tofix.rs b/app/src/domain/tests/drawer_tofix.rs index 92349fc..eec51ae 100644 --- a/app/src/domain/tests/drawer_tofix.rs +++ b/app/src/domain/tests/drawer_tofix.rs @@ -1,13 +1,15 @@ use std::time::Duration; -use leptos::{ev, html, leptos_dom::helpers::window_event_listener, prelude::*}; +use leptos::leptos_dom::helpers::window_event_listener; +use leptos::prelude::*; +use leptos::{ev, html}; use leptos_ui::clx; +use registry::ui::button::{Button, ButtonSize, ButtonVariant}; use tw_merge::*; -use wasm_bindgen::{JsCast, closure::Closure}; +use wasm_bindgen::JsCast; +use wasm_bindgen::closure::Closure; use web_sys::{Element, HtmlElement, KeyboardEvent, PointerEvent}; -use crate::ui::button::{Button, ButtonSize, ButtonVariant}; - const VELOCITY_THRESHOLD: f64 = 0.4; const CLOSE_THRESHOLD: f64 = 0.25; const TRANSITION_DURATION_MS: u64 = 500; @@ -341,9 +343,7 @@ pub fn DrawerContent( let delta = current_pos.get_untracked() - start_pos.get_untracked(); let closing_direction = dragging_in_closing_direction(delta, position); - if !is_allowed_to_drag.get() - && !should_drag(event.target(), &drawer, open_time, last_time_drag_prevented) - { + if !is_allowed_to_drag.get() && !should_drag(event.target(), &drawer, open_time, last_time_drag_prevented) { return; } @@ -351,9 +351,7 @@ pub fn DrawerContent( if closing_direction { let abs_delta = delta.abs(); - let _ = drawer - .style() - .set_property("transform", &drag_transform(delta, closing_direction, position)); + let _ = drawer.style().set_property("transform", &drag_transform(delta, closing_direction, position)); if let Some(wrapper) = query_drawer_wrapper() { let percentage_dragged = percentage_dragged(abs_delta, drawer_size.get_untracked()); @@ -372,9 +370,7 @@ pub fn DrawerContent( let _ = overlay.style().set_property("transition", "none"); let _ = overlay.style().set_property("opacity", &opacity.to_string()); } else { - let _ = drawer - .style() - .set_property("transform", &drag_transform(delta, closing_direction, position)); + let _ = drawer.style().set_property("transform", &drag_transform(delta, closing_direction, position)); } } }; @@ -388,11 +384,8 @@ pub fn DrawerContent( DrawerPosition::Right => "right-0 top-0 bottom-0 max-w-[96vw] rounded-l-[10px]", }; - let merged_class = tw_merge!( - "flex flex-col pt-3 pb-6 px-6 fixed z-210 bg-background hidden outline-none", - position_class, - class - ); + let merged_class = + tw_merge!("flex flex-col pt-3 pb-6 px-6 fixed z-210 bg-background hidden outline-none", position_class, class); let class_ctx = ctx.clone(); let content_animate_ctx = ctx.clone(); @@ -534,12 +527,7 @@ fn should_close_from_drag(delta: f64, velocity: f64, drawer_size: f64, position: } } -fn finish_pointer_drag( - ctx: &DrawerContext, - event: PointerEvent, - position: DrawerPosition, - drag_state: DragState, -) { +fn finish_pointer_drag(ctx: &DrawerContext, event: PointerEvent, position: DrawerPosition, drag_state: DragState) { if !drag_state.is_dragging.get() || !ctx.dismissible.get() { return; } @@ -552,9 +540,7 @@ fn finish_pointer_drag( let elapsed = (now_ms() - drag_state.drag_start_time.get_untracked()).max(1.0); let velocity = delta.abs() / elapsed; - let _ = drawer - .style() - .set_property("transition", &format!("transform 0.5s {TRANSITION_EASING}")); + let _ = drawer.style().set_property("transition", &format!("transform 0.5s {TRANSITION_EASING}")); if let Some(wrapper) = query_drawer_wrapper() { let _ = wrapper.style().set_property( @@ -564,9 +550,7 @@ fn finish_pointer_drag( } if let Some(overlay) = &overlay { - let _ = overlay - .style() - .set_property("transition", &format!("opacity 0.5s {TRANSITION_EASING}")); + let _ = overlay.style().set_property("transition", &format!("opacity 0.5s {TRANSITION_EASING}")); } let size = drag_state.drawer_size.get_untracked().max(1.0); @@ -647,8 +631,7 @@ fn should_drag( } fn focusable_elements(drawer: &HtmlElement) -> Vec { - const FOCUSABLE_SELECTOR: &str = - "a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])"; + const FOCUSABLE_SELECTOR: &str = "a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])"; let Ok(elements) = drawer.query_selector_all(FOCUSABLE_SELECTOR) else { return Vec::new(); @@ -682,10 +665,7 @@ fn focus_first_drawer_element(ctx: &DrawerContext) { } let is_only_close_button = focusable.len() == 1 - && focusable - .first() - .and_then(|element| element.get_attribute("data-name")) - .as_deref() + && focusable.first().and_then(|element| element.get_attribute("data-name")).as_deref() == Some("DrawerClose"); if is_only_close_button { @@ -718,8 +698,8 @@ fn fix_drawer_position(drawer: &HtmlElement) { fn lock_body_scroll() { let Some(document) = window().document() else { return }; let Some(body) = document.body() else { return }; - let scrollbar_width = - window().inner_width().ok().and_then(|width| width.as_f64()).unwrap_or_default() - f64::from(body.client_width()); + let scrollbar_width = window().inner_width().ok().and_then(|width| width.as_f64()).unwrap_or_default() + - f64::from(body.client_width()); let _ = body.set_attribute("data-state", "open"); if scrollbar_width > 0.0 { @@ -861,14 +841,10 @@ fn close_drawer_dom(ctx: &DrawerContext, position: DrawerPosition, variant: Draw ctx.content_animate.set(false); ctx.overlay_animate.set(false); - let _ = drawer - .style() - .set_property("transition", &format!("transform 0.5s {TRANSITION_EASING}")); + let _ = drawer.style().set_property("transition", &format!("transform 0.5s {TRANSITION_EASING}")); let _ = drawer.style().set_property("transform", &close_transform(size, position, variant)); - let _ = overlay - .style() - .set_property("transition", &format!("opacity 0.5s {TRANSITION_EASING}")); + let _ = overlay.style().set_property("transition", &format!("opacity 0.5s {TRANSITION_EASING}")); let _ = overlay.style().set_property("opacity", "0"); reset_wrapper_styles(); diff --git a/app/src/domain/tests/mod.rs b/app/src/domain/tests/mod.rs index aa76ce2..c165c04 100644 --- a/app/src/domain/tests/mod.rs +++ b/app/src/domain/tests/mod.rs @@ -1,2 +1,3 @@ +pub mod drawer_tofix; pub mod page_test; pub mod page_to_fix; diff --git a/app/src/domain/tests/page_to_fix.rs b/app/src/domain/tests/page_to_fix.rs index 5e6d626..76bfb81 100644 --- a/app/src/domain/tests/page_to_fix.rs +++ b/app/src/domain/tests/page_to_fix.rs @@ -1,19 +1,415 @@ +use icons::{FileText, Lock, TriangleAlert, X}; use leptos::prelude::*; -use registry::demos::demo_carousel::DemoCarousel; +use registry::ui::button::Button; +use registry::ui::dialog::{ + Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, + DialogTrigger, +}; +use registry::ui::direction_provider::{Direction, DirectionProvider}; +use registry::ui::input::Input; +use registry::ui::label::Label; +use registry::ui::textarea::Textarea; + +use crate::domain::tests::drawer_tofix::{ + Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHandle, DrawerHeader, + DrawerPosition, DrawerTitle, DrawerTrigger, DrawerVariant, +}; #[component] pub fn PageToFix() -> impl IntoView { view! { -
-

"To Fix"

- - "→ Test" - +
+
+
+

"Drawer Parity Test Page"

+

+ "This page isolates the Rust drawer port parked in " + "domain/tests/drawer_tofix.rs" + " so behavior can be matched against the original JS implementation before the public drawer is touched again." +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + -
-

"Carousel"

- + + + + + + + + + + + + + + + + + + + +
} } + +#[component] +fn DrawerDemoCard(title: &'static str, description: &'static str, children: Children) -> impl IntoView { + view! { +
+
+

{title}

+

{description}

+
+
{children()}
+
+ } +} + +#[component] +fn DemoDrawerToFix() -> impl IntoView { + view! { + + "Open Drawer" + + + + + + "Drawer Title" + "Drag down to close or click outside." + + + "Close" + + + + } +} + +#[component] +fn DemoDrawerDialogToFix() -> impl IntoView { + view! { +
+
+ + "Subscribe" + + + + + "Subscribe" + "Get the latest updates delivered to your inbox." + + + + "Cancel" + + + + + +
+ + +
+ } +} + +#[component] +fn DemoDrawerFamilyToFix() -> impl IntoView { + view! { + + "Open Drawer" + + +
+

"Options"

+ +
+ +
+ + + + + +
+
+
+ } +} + +#[component] +fn DemoDrawerFocusToFix() -> impl IntoView { + view! { + + "Open Drawer" + + + + + + + "Focus Drawer" + + "Test keyboard navigation: Press Tab to cycle through elements, Shift+Tab to go back, and Escape to close." + + + +
+
+ + +
+ +
+ + +
+ +
+ +