From 397503dc8a2cbe755e13e62accb29ee22150e81c Mon Sep 17 00:00:00 2001 From: geoffreygarrett Date: Wed, 8 Jan 2025 13:15:09 +0200 Subject: [PATCH 1/9] Update Workspace for Leptos 0.7 --- Cargo.toml | 109 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ce06992c..aceb6cde 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,34 +1,56 @@ [workspace] -# Temporarily disabled to upgrade individual packages to Leptos 0.7. -# members = [ -# "book-examples/*/*", -# "packages/colors", -# "packages/icons/*", -# "packages/primitives/*/*", -# "packages/themes/*", -# "scripts", -# "stories/*", -# ] +# Temporarily disabled subcrates to be upgraded individually to Leptos 0.7. +# Once a crate is ready, uncomment it here. members = [ "book-examples/*/*", "packages/colors", - "packages/icons/*", - "packages/primitives/leptos/accessible-icon", - "packages/primitives/leptos/arrow", - "packages/primitives/leptos/aspect-ratio", - "packages/primitives/leptos/direction", - "packages/primitives/leptos/id", - "packages/primitives/leptos/label", - "packages/primitives/leptos/use-controllable-state", - "packages/primitives/leptos/use-escape-keydown", - "packages/primitives/leptos/use-previous", - "packages/primitives/leptos/use-size", - "packages/primitives/leptos/visually-hidden", + "packages/icons/dioxus", + "packages/icons/yew", + + # -- Leptos Primitives (commented until they're upgraded) -- + # "packages/primitives/leptos/accessible-icon", + # "packages/primitives/leptos/arrow", + # "packages/primitives/leptos/aspect-ratio", + # "packages/primitives/leptos/avatar", + # "packages/primitives/leptos/checkbox", + # "packages/primitives/leptos/collection", + # "packages/primitives/leptos/compose-refs", + # "packages/primitives/leptos/direction", + # "packages/primitives/leptos/dismissable-layer", + # "packages/primitives/leptos/dropdown-menu", + # "packages/primitives/leptos/focus-guards", + # "packages/primitives/leptos/focus-scope", + # "packages/primitives/leptos/id", + # "packages/primitives/leptos/label", + # "packages/primitives/leptos/menu", + # "packages/primitives/leptos/popover", + # "packages/primitives/leptos/popper", + # "packages/primitives/leptos/portal", + # "packages/primitives/leptos/presence", + # "packages/primitives/leptos/primitive", + # "packages/primitives/leptos/progress", + # "packages/primitives/leptos/roving-focus", + # "packages/primitives/leptos/select", + # "packages/primitives/leptos/separator", + # "packages/primitives/leptos/slot", + # "packages/primitives/leptos/switch", + # "packages/primitives/leptos/tabs", + # "packages/primitives/leptos/toggle", + # "packages/primitives/leptos/use-controllable-state", + # "packages/primitives/leptos/use-escape-keydown", + # "packages/primitives/leptos/use-previous", + # "packages/primitives/leptos/use-size", + # "packages/primitives/leptos/visually-hidden", + + # -- Yew Primitives -- "packages/primitives/yew/*", + + # -- Themes, Scripts, and Stories -- "packages/themes/yew", "scripts", "stories/*", ] + resolver = "2" [workspace.package] @@ -39,14 +61,17 @@ repository = "https://github.com/RustForWeb/radix" version = "0.0.2" [workspace.dependencies] -console_log = "1.0.0" console_error_panic_hook = "0.1.7" +console_log = "1.0.0" dioxus = "0.6.1" leptos = "0.7.2" leptos_dom = "0.7.2" leptos_router = "0.7.2" leptos-node-ref = "0.0.3" +leptos-maybe-callback = "0.0.3" leptos-style = "0.0.3" +leptos-typed-fallback-show = "0.0.3" +leptos-use = "0.15.2" log = "0.4.22" send_wrapper = "0.6.0" serde = "1.0.198" @@ -58,6 +83,44 @@ yew-router = "0.18.0" yew-struct-component = "0.1.4" yew-style = "0.1.4" +# Subcrate packages (paths remain the same; you can comment out any subcrate not yet upgraded). +# We centralize shared dependencies in [workspace.dependencies] for a single source of truth, +# reducing duplication, preventing version drift, and keeping the Cargo.lock consistent. +#radix-leptos-arrow.path = "./packages/primitives/leptos/arrow" +#radix-leptos-aspect-ratio.path = "./packages/primitives/leptos/aspect-ratio" +#radix-leptos-accessible-icon.path = "./packages/primitives/leptos/accessible-icon" +#radix-leptos-avatar.path = "./packages/primitives/leptos/avatar" +#radix-leptos-checkbox.path = "./packages/primitives/leptos/checkbox" +#radix-leptos-collection.path = "./packages/primitives/leptos/collection" +#radix-leptos-compose-refs.path = "./packages/primitives/leptos/compose-refs" +#radix-leptos-direction.path = "./packages/primitives/leptos/direction" +#radix-leptos-dismissable-layer.path = "./packages/primitives/leptos/dismissable-layer" +#radix-leptos-dropdown-menu.path = "./packages/primitives/leptos/dropdown-menu" +#radix-leptos-focus-guards.path = "./packages/primitives/leptos/focus-guards" +#radix-leptos-focus-scope.path = "./packages/primitives/leptos/focus-scope" +#radix-leptos-id.path = "./packages/primitives/leptos/id" +#radix-leptos-label.path = "./packages/primitives/leptos/label" +#radix-leptos-menu.path = "./packages/primitives/leptos/menu" +#radix-leptos-popper.path = "./packages/primitives/leptos/popper" +#radix-leptos-portal.path = "./packages/primitives/leptos/portal" +#radix-leptos-presence.path = "./packages/primitives/leptos/presence" +#radix-leptos-primitive.path = "./packages/primitives/leptos/primitive" +#radix-leptos-progress.path = "./packages/primitives/leptos/progress" +#radix-leptos-roving-focus.path = "./packages/primitives/leptos/roving-focus" +#radix-leptos-select.path = "./packages/primitives/leptos/select" +#radix-leptos-separator.path = "./packages/primitives/leptos/separator" +#radix-leptos-slot.path = "./packages/primitives/leptos/slot" +#radix-leptos-switch.path = "./packages/primitives/leptos/switch" +#radix-leptos-tabs.path = "./packages/primitives/leptos/tabs" +#radix-leptos-toggle.path = "./packages/primitives/leptos/toggle" +#radix-leptos-use-controllable-state.path = "./packages/primitives/leptos/use-controllable-state" +#radix-leptos-use-escape-keydown.path = "./packages/primitives/leptos/use-escape-keydown" +#radix-leptos-use-previous.path = "./packages/primitives/leptos/use-previous" +#radix-leptos-use-size.path = "./packages/primitives/leptos/use-size" +#radix-leptos-visually-hidden.path = "./packages/primitives/leptos/visually-hidden" + [patch.crates-io] yew = { git = "https://github.com/RustForWeb/yew.git", branch = "feature/use-composed-ref" } yew-router = { git = "https://github.com/RustForWeb/yew.git", branch = "feature/use-composed-ref" } +leptos-node-ref = { git = "https://github.com/geoffreygarrett/leptos-utils", branch = "feature/any-node-ref" } +radix-leptos-primitive = { git = "https://github.com/geoffreygarrett/radix", branch = "update/leptos-0.7-primitive" } From 70159621139cc0c0150299b518aafaa4cb819d50 Mon Sep 17 00:00:00 2001 From: geoffreygarrett Date: Wed, 8 Jan 2025 14:16:57 +0200 Subject: [PATCH 2/9] Update Workspace for Leptos 0.7 --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index aceb6cde..ab7670fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -123,4 +123,3 @@ yew-style = "0.1.4" yew = { git = "https://github.com/RustForWeb/yew.git", branch = "feature/use-composed-ref" } yew-router = { git = "https://github.com/RustForWeb/yew.git", branch = "feature/use-composed-ref" } leptos-node-ref = { git = "https://github.com/geoffreygarrett/leptos-utils", branch = "feature/any-node-ref" } -radix-leptos-primitive = { git = "https://github.com/geoffreygarrett/radix", branch = "update/leptos-0.7-primitive" } From e896ace2c06b0f85a58bd61957d1d352f6c9695b Mon Sep 17 00:00:00 2001 From: geoffreygarrett Date: Mon, 6 Jan 2025 19:19:46 +0200 Subject: [PATCH 3/9] Update Primitive to Leptos 0.7 --- .../primitives/leptos/primitive/Cargo.toml | 14 +++ .../primitives/leptos/primitive/README.md | 98 ++++++++++++++++ .../primitives/leptos/primitive/src/lib.rs | 9 ++ .../leptos/primitive/src/primitive.rs | 109 ++++++++++++++++++ 4 files changed, 230 insertions(+) create mode 100644 packages/primitives/leptos/primitive/Cargo.toml create mode 100644 packages/primitives/leptos/primitive/README.md create mode 100644 packages/primitives/leptos/primitive/src/lib.rs create mode 100644 packages/primitives/leptos/primitive/src/primitive.rs diff --git a/packages/primitives/leptos/primitive/Cargo.toml b/packages/primitives/leptos/primitive/Cargo.toml new file mode 100644 index 00000000..fecb0b9d --- /dev/null +++ b/packages/primitives/leptos/primitive/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "radix-leptos-primitive" +description = "Leptos port of Radix Primitive." + +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +version.workspace = true + +[dependencies] +leptos.workspace = true +leptos-node-ref.workspace = true +leptos-typed-fallback-show.workspace = true \ No newline at end of file diff --git a/packages/primitives/leptos/primitive/README.md b/packages/primitives/leptos/primitive/README.md new file mode 100644 index 00000000..296e16dc --- /dev/null +++ b/packages/primitives/leptos/primitive/README.md @@ -0,0 +1,98 @@ + +

+ + Rust Radix Logo + +

+ +

radix-leptos-primitive

+ +This is an internal utility, not intended for public usage. + +[Rust Radix](https://github.com/RustForWeb/radix) is a Rust port of [Radix](https://www.radix-ui.com/primitives). + +## Overview + +```rust +use leptos::*; +use leptos_node_ref::AnyNodeRef; +use leptos_typed_fallback_show::TypedFallbackShow; + +/// A generic Primitive component. Renders `element()` by default, or its +/// children directly if `as_child` is `true`. We rely on `TypedChildrenFn` +/// so that attributes can pass through at runtime—critical in Leptos v0.7 +/// because `Children`-based types block such passthrough. +#[component] +#[allow(non_snake_case)] +pub fn Primitive( + element: fn() -> HtmlElement, + children: TypedChildrenFn, + #[prop(optional, into)] as_child: MaybeProp, + #[prop(optional, into)] node_ref: AnyNodeRef, +) -> impl IntoView +where + E: ElementType + 'static, + C: IntoView + 'static, +{ + let children = StoredValue::new(children.into_inner()); + view! { + + {children.with_value(|c| c()) + .add_any_attr(leptos_node_ref::any_node_ref(node_ref))} + + } +} + +/// Same idea, but for elements that do not take children (e.g. `img`, `input`). +#[component] +#[allow(non_snake_case)] +pub fn VoidPrimitive( + element: fn() -> HtmlElement, + children: TypedChildrenFn, + #[prop(optional, into)] as_child: MaybeProp, + #[prop(optional, into)] node_ref: AnyNodeRef, +) -> impl IntoView +where + E: ElementType + 'static, +{ + let children = StoredValue::new(children.into_inner()); + view! { + + {children.with_value(|c| c()) + .add_any_attr(leptos_node_ref::any_node_ref(node_ref))} + + } +} + +// (Compose callbacks is an internal piece from Radix Core; omitted for brevity.) +``` + +## Notes + +- **Why `TypedChildrenFn`?**: Leptos attribute passthrough only works if a component doesn't rely on `AnyView` or `Children`. Using typed children ensures classes, events, etc. from the parent can flow to the rendered DOM node. +- **`as_child`**: Mimics `asChild` in Radix’s React version, but we skip an explicit ``: Leptos’s approach to typed fallback rendering covers “slot-like” logic. +- **Class Handling**: Static classes from a parent can overwrite child-defined classes. No built-in merging exists. +- **Attribute System Limitations**: Leptos limits you to 26 dynamic attributes. Past that, nest components or try a custom approach. +- **Parity with React**: In React, `...props` merges everything automatically. In Leptos, we rely on typed props/attributes and can intercept unknown ones with `AttributeInterceptor`. + +## Documentation + +See [the Rust Radix book](https://radix.rustforweb.org/) for documentation. + +## Rust For Web + +The Rust Radix project is part of the [Rust For Web](https://github.com/RustForWeb). + +[Rust For Web](https://github.com/RustForWeb) creates and ports web UI libraries for Rust. All projects are free and open source. diff --git a/packages/primitives/leptos/primitive/src/lib.rs b/packages/primitives/leptos/primitive/src/lib.rs new file mode 100644 index 00000000..304fec6d --- /dev/null +++ b/packages/primitives/leptos/primitive/src/lib.rs @@ -0,0 +1,9 @@ +//! Leptos port of [Radix Primitive](https://www.radix-ui.com/primitives). +//! +//! This is an internal utility, not intended for public usage. + +//! See [`@radix-ui/react-primitive`](https://www.npmjs.com/package/@radix-ui/react-primitive) for the original package. + +mod primitive; + +pub use primitive::*; diff --git a/packages/primitives/leptos/primitive/src/primitive.rs b/packages/primitives/leptos/primitive/src/primitive.rs new file mode 100644 index 00000000..7d4c94ab --- /dev/null +++ b/packages/primitives/leptos/primitive/src/primitive.rs @@ -0,0 +1,109 @@ +use leptos::{ + attr::Attribute, + ev::Event, + html::{ElementType, HtmlElement}, + prelude::*, + wasm_bindgen::JsCast, + tachys::html::{class::IntoClass, node_ref::NodeRefContainer, style::IntoStyle}, +}; +use leptos_node_ref::{any_node_ref, AnyNodeRef}; +use leptos_typed_fallback_show::TypedFallbackShow; + +/* ------------------------------------------------------------------------------------------------- + * Primitive + * -----------------------------------------------------------------------------------------------*/ + +#[component] +#[allow(non_snake_case)] +pub fn Primitive( + element: fn() -> HtmlElement, + children: TypedChildrenFn, + #[prop(optional, into)] as_child: MaybeProp, + #[prop(optional, into)] node_ref: AnyNodeRef, +) -> impl IntoView +where + E: ElementType + 'static, + C: IntoView + 'static, + View: RenderHtml, + HtmlElement: ElementChild>, + as ElementChild>>::Output: IntoView, + ::Output: JsCast, + AnyNodeRef: NodeRefContainer, +{ + let children = StoredValue::new(children.into_inner()); + + view! { + + {children.with_value(|children| children()).add_any_attr(any_node_ref(node_ref))} + + } +} + +#[component] +#[allow(non_snake_case)] +pub fn VoidPrimitive( + element: fn() -> HtmlElement, + children: TypedChildrenFn, + #[prop(into, optional)] as_child: MaybeProp, + #[prop(into, optional)] node_ref: AnyNodeRef, +) -> impl IntoView +where + E: ElementType + 'static, + C: IntoView + 'static, + View: RenderHtml, + ::Output: JsCast, + AnyNodeRef: NodeRefContainer, +{ + let children = StoredValue::new(children.into_inner()); + view! { + + {children.with_value(|children| children()).add_any_attr(any_node_ref(node_ref))} + + } +} + +/* ------------------------------------------------------------------------------------------------- + * Utils + * -----------------------------------------------------------------------------------------------*/ + +pub fn compose_callbacks( + original_handler: Option>, + our_handler: Option>, + check_default_prevented: Option, +) -> impl Fn(E) +where + E: Clone + Into + 'static, +{ + let check_default_prevented = check_default_prevented.unwrap_or(true); + + move |event: E| { + // Run original handler first, matching TypeScript behavior + if let Some(original) = &original_handler { + original.run(event.clone()); + } + + // Only run our handler if default wasn't prevented (when checking is enabled) + if !check_default_prevented || !event.clone().into().default_prevented() { + if let Some(our) = &our_handler { + our.run(event); + } + } + } +} + +/* ------------------------------------------------------------------------------------------------- + * Primitive re-exports + * -----------------------------------------------------------------------------------------------*/ + +pub mod primitive { + pub use super::*; + pub use Primitive as Root; +} \ No newline at end of file From 2ee135bf5ed6fc773a14fa68ec5af2a40ea2a37a Mon Sep 17 00:00:00 2001 From: geoffreygarrett Date: Wed, 8 Jan 2025 14:13:52 +0200 Subject: [PATCH 4/9] Update Primitive for Leptos 0.7 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index ab7670fe..a16ac6ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -104,7 +104,7 @@ yew-style = "0.1.4" #radix-leptos-popper.path = "./packages/primitives/leptos/popper" #radix-leptos-portal.path = "./packages/primitives/leptos/portal" #radix-leptos-presence.path = "./packages/primitives/leptos/presence" -#radix-leptos-primitive.path = "./packages/primitives/leptos/primitive" +radix-leptos-primitive.path = "./packages/primitives/leptos/primitive" #radix-leptos-progress.path = "./packages/primitives/leptos/progress" #radix-leptos-roving-focus.path = "./packages/primitives/leptos/roving-focus" #radix-leptos-select.path = "./packages/primitives/leptos/select" From 08e08acfb65091751421c61b46fbe721a36929bb Mon Sep 17 00:00:00 2001 From: geoffreygarrett Date: Wed, 8 Jan 2025 14:24:49 +0200 Subject: [PATCH 5/9] Update Primitive for Leptos 0.7 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a16ac6ef..16f109e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ members = [ # "packages/primitives/leptos/popper", # "packages/primitives/leptos/portal", # "packages/primitives/leptos/presence", - # "packages/primitives/leptos/primitive", + "packages/primitives/leptos/primitive", # "packages/primitives/leptos/progress", # "packages/primitives/leptos/roving-focus", # "packages/primitives/leptos/select", From 98abf14db7ce26e07e4e4621b9bc9d0acacc5189 Mon Sep 17 00:00:00 2001 From: geoffreygarrett Date: Wed, 8 Jan 2025 14:26:14 +0200 Subject: [PATCH 6/9] Update Primitive for Leptos 0.7 --- .../primitives/leptos/primitive/src/primitive.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/packages/primitives/leptos/primitive/src/primitive.rs b/packages/primitives/leptos/primitive/src/primitive.rs index 7d4c94ab..fd39d291 100644 --- a/packages/primitives/leptos/primitive/src/primitive.rs +++ b/packages/primitives/leptos/primitive/src/primitive.rs @@ -1,10 +1,9 @@ use leptos::{ - attr::Attribute, ev::Event, html::{ElementType, HtmlElement}, prelude::*, wasm_bindgen::JsCast, - tachys::html::{class::IntoClass, node_ref::NodeRefContainer, style::IntoStyle}, + tachys::html::{node_ref::NodeRefContainer}, }; use leptos_node_ref::{any_node_ref, AnyNodeRef}; use leptos_typed_fallback_show::TypedFallbackShow; @@ -98,12 +97,3 @@ where } } } - -/* ------------------------------------------------------------------------------------------------- - * Primitive re-exports - * -----------------------------------------------------------------------------------------------*/ - -pub mod primitive { - pub use super::*; - pub use Primitive as Root; -} \ No newline at end of file From fc8f7cde16e11dadbfd3ed9857e6398bfa9cec0e Mon Sep 17 00:00:00 2001 From: geoffreygarrett Date: Mon, 6 Jan 2025 19:56:33 +0200 Subject: [PATCH 7/9] Update Aspect Ratio to Leptos 0.7 --- Cargo.toml | 2 + .../primitives/leptos/aspect-ratio/Cargo.toml | 3 +- .../primitives/leptos/aspect-ratio/README.md | 2 +- .../leptos/aspect-ratio/src/aspect_ratio.rs | 121 +++++++++--------- 4 files changed, 65 insertions(+), 63 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 16f109e0..df9deccf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,6 +82,7 @@ yew = "0.21.0" yew-router = "0.18.0" yew-struct-component = "0.1.4" yew-style = "0.1.4" +radix-leptos-primitive.version = "0.0.2" # Subcrate packages (paths remain the same; you can comment out any subcrate not yet upgraded). # We centralize shared dependencies in [workspace.dependencies] for a single source of truth, @@ -123,3 +124,4 @@ radix-leptos-primitive.path = "./packages/primitives/leptos/primitive" yew = { git = "https://github.com/RustForWeb/yew.git", branch = "feature/use-composed-ref" } yew-router = { git = "https://github.com/RustForWeb/yew.git", branch = "feature/use-composed-ref" } leptos-node-ref = { git = "https://github.com/geoffreygarrett/leptos-utils", branch = "feature/any-node-ref" } +radix-leptos-primitive = { git = "https://github.com/geoffreygarrett/radix", branch = "update/leptos-0.7-primitive" } \ No newline at end of file diff --git a/packages/primitives/leptos/aspect-ratio/Cargo.toml b/packages/primitives/leptos/aspect-ratio/Cargo.toml index 98ee8a20..23e59480 100644 --- a/packages/primitives/leptos/aspect-ratio/Cargo.toml +++ b/packages/primitives/leptos/aspect-ratio/Cargo.toml @@ -11,4 +11,5 @@ version.workspace = true [dependencies] leptos.workspace = true -leptos-style.workspace = true +leptos-node-ref.workspace = true +radix-leptos-primitive.workspace = true diff --git a/packages/primitives/leptos/aspect-ratio/README.md b/packages/primitives/leptos/aspect-ratio/README.md index 02e4a0df..98d2a736 100644 --- a/packages/primitives/leptos/aspect-ratio/README.md +++ b/packages/primitives/leptos/aspect-ratio/README.md @@ -16,6 +16,6 @@ See [the Rust Radix book](https://radix.rustforweb.org/) for documentation. ## Rust For Web -The Rust Radix project is part of [Rust For Web](https://github.com/RustForWeb). +The Rust Radix project is part of the [Rust For Web](https://github.com/RustForWeb). [Rust For Web](https://github.com/RustForWeb) creates and ports web UI libraries for Rust. All projects are free and open source. diff --git a/packages/primitives/leptos/aspect-ratio/src/aspect_ratio.rs b/packages/primitives/leptos/aspect-ratio/src/aspect_ratio.rs index 60b42326..971859e7 100644 --- a/packages/primitives/leptos/aspect-ratio/src/aspect_ratio.rs +++ b/packages/primitives/leptos/aspect-ratio/src/aspect_ratio.rs @@ -1,80 +1,79 @@ -use leptos::prelude::*; -use leptos_style::Style; +use leptos::{prelude::*, html}; +use radix_leptos_primitive::Primitive; +use leptos_node_ref::AnyNodeRef; -pub struct UseAspectRatioProps { - style: Style, -} +const DEFAULT_RATIO: f64 = 1.0; -pub struct UseAspectRatioAttrs { - style: Style, -} +/* ------------------------------------------------------------------------------------------------- + * AspectRatio + * -----------------------------------------------------------------------------------------------*/ -pub fn use_aspect_ratio(props: UseAspectRatioProps) -> UseAspectRatioAttrs { - UseAspectRatioAttrs { - style: props.style.with_defaults([ - // Ensures children expand in ratio. - ("position", "absolute"), - ("top", "0px"), - ("right", "0px"), - ("bottom", "0px"), - ("left", "0px"), - ]), - } -} +const NAME: &'static str = "AspectRatio"; #[component] -pub fn BaseAspectRatio( - #[prop(into, optional)] ratio: MaybeProp, - #[prop(optional)] children: Option, +#[allow(non_snake_case)] +pub fn AspectRatio( + /// Children passed to the AspectRatio component + children: TypedChildrenFn, + + /// Change the default rendered element for the one passed as a child + #[prop(into, optional, default = false.into())] + as_child: MaybeProp, + + /// The desired ratio when rendering the content (e.g., 16/9). Defaults to 1.0 if not specified. + #[prop(into, optional, default = DEFAULT_RATIO.into())] + ratio: MaybeProp, + + /// Reference to the underlying DOM node + #[prop(into, optional)] + node_ref: AnyNodeRef, ) -> impl IntoView { - let ratio = Signal::derive(move || ratio.get().unwrap_or(1.0)); + // calculates the percent-based padding for the aspect ratio + let padding_bottom = Signal::derive(move || { + 100.0 + / ratio + .get() + .unwrap_or(DEFAULT_RATIO) + .clamp(f64::EPSILON, f64::MAX) + }); + + #[cfg(debug_assertions)] + Effect::new(move |_| { + leptos::logging::log!("[{NAME}] ratio: {:?}", ratio.get()); + leptos::logging::log!("[{NAME}] as_child: {:?}", as_child.get()); + leptos::logging::log!("[{NAME}] node_ref: {:?}", node_ref.get()); + }); view! { + // ensures inner element is contained
- {children.map(|children| children())} +
} } -#[component] -pub fn AspectRatio( - #[prop(into, optional)] ratio: MaybeProp, - #[prop(into, optional)] style: Style, - #[prop(optional)] children: Option, -) -> impl IntoView { - let attrs = use_aspect_ratio(UseAspectRatioProps { style }); - - view! { - -
- {children.map(|children| children())} -
-
- } -} - -#[component] -pub fn AspectRatioAsChild( - #[prop(into, optional)] ratio: MaybeProp, - #[prop(into, optional)] style: Style, - render: R, -) -> impl IntoView -where - R: Fn(UseAspectRatioAttrs) -> RV + Send + 'static, - RV: IntoView + 'static, -{ - let attrs = use_aspect_ratio(UseAspectRatioProps { style }); +/* ------------------------------------------------------------------------------------------------- + * Primitive re-exports + * -----------------------------------------------------------------------------------------------*/ - view! { - - {render(attrs)} - - } +pub mod primitive { + pub use super::*; + pub use AspectRatio as Root; } From 99b9c722bda1bb9c1e7948611d56ff951a6eed7c Mon Sep 17 00:00:00 2001 From: geoffreygarrett Date: Wed, 8 Jan 2025 18:04:43 +0200 Subject: [PATCH 8/9] Update Aspect Ratio to Leptos 0.7 --- Cargo.toml | 6 +- .../src/primitives/components/aspect-ratio.md | 115 +++++++++++------- 2 files changed, 72 insertions(+), 49 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index df9deccf..deb8b3ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ members = [ # -- Leptos Primitives (commented until they're upgraded) -- # "packages/primitives/leptos/accessible-icon", # "packages/primitives/leptos/arrow", - # "packages/primitives/leptos/aspect-ratio", + "packages/primitives/leptos/aspect-ratio", # "packages/primitives/leptos/avatar", # "packages/primitives/leptos/checkbox", # "packages/primitives/leptos/collection", @@ -82,13 +82,12 @@ yew = "0.21.0" yew-router = "0.18.0" yew-struct-component = "0.1.4" yew-style = "0.1.4" -radix-leptos-primitive.version = "0.0.2" # Subcrate packages (paths remain the same; you can comment out any subcrate not yet upgraded). # We centralize shared dependencies in [workspace.dependencies] for a single source of truth, # reducing duplication, preventing version drift, and keeping the Cargo.lock consistent. #radix-leptos-arrow.path = "./packages/primitives/leptos/arrow" -#radix-leptos-aspect-ratio.path = "./packages/primitives/leptos/aspect-ratio" +radix-leptos-aspect-ratio.path = "./packages/primitives/leptos/aspect-ratio" #radix-leptos-accessible-icon.path = "./packages/primitives/leptos/accessible-icon" #radix-leptos-avatar.path = "./packages/primitives/leptos/avatar" #radix-leptos-checkbox.path = "./packages/primitives/leptos/checkbox" @@ -124,4 +123,3 @@ radix-leptos-primitive.path = "./packages/primitives/leptos/primitive" yew = { git = "https://github.com/RustForWeb/yew.git", branch = "feature/use-composed-ref" } yew-router = { git = "https://github.com/RustForWeb/yew.git", branch = "feature/use-composed-ref" } leptos-node-ref = { git = "https://github.com/geoffreygarrett/leptos-utils", branch = "feature/any-node-ref" } -radix-leptos-primitive = { git = "https://github.com/geoffreygarrett/radix", branch = "update/leptos-0.7-primitive" } \ No newline at end of file diff --git a/book/src/primitives/components/aspect-ratio.md b/book/src/primitives/components/aspect-ratio.md index b584eaed..5272bf0b 100644 --- a/book/src/primitives/components/aspect-ratio.md +++ b/book/src/primitives/components/aspect-ratio.md @@ -2,8 +2,8 @@ Displays content within a desired ratio. -{{#tabs global="framework" }} -{{#tab name="Leptos" }} +{{#tabs global="framework"}} +{{#tab name="Leptos"}} ```toml,trunk package = "radix-leptos-book-primitives" @@ -11,8 +11,8 @@ features = ["aspect-ratio"] files = ["src/aspect_ratio.rs"] ``` -{{#endtab }} -{{#tab name="Yew" }} +{{#endtab}} +{{#tab name="Yew"}} ```toml,trunk package = "radix-yew-book-primitives" @@ -20,78 +20,80 @@ features = ["aspect-ratio"] files = ["src/aspect_ratio.rs"] ``` -{{#endtab }} -{{#endtabs }} +{{#endtab}} +{{#endtabs}} ## Features -- Accepts any custom ratio. +- Accepts any custom ratio. ## Installation Install the component from your command line. -{{#tabs global="framework" }} -{{#tab name="Leptos" }} +{{#tabs global="framework"}} +{{#tab name="Leptos"}} ```shell cargo add radix-leptos-aspect-ratio ``` -- [View on crates.io](https://crates.io/crates/radix-leptos-aspect-ratio) -- [View on docs.rs](https://docs.rs/radix-leptos-aspect-ratio/latest/radix_leptos_aspect_ratio/) -- [View source](https://github.com/RustForWeb/radix/tree/main/packages/primitives/leptos/aspect-ratio) +- [View on crates.io](https://crates.io/crates/radix-leptos-aspect-ratio) +- [View on docs.rs](https://docs.rs/radix-leptos-aspect-ratio/latest/radix_leptos_aspect_ratio/) +- [View source](https://github.com/RustForWeb/radix/tree/main/packages/primitives/leptos/aspect-ratio) -{{#endtab }} -{{#tab name="Yew" }} +{{#endtab}} +{{#tab name="Yew"}} ```shell cargo add radix-yew-aspect-ratio ``` -- [View on crates.io](https://crates.io/crates/radix-yew-aspect-ratio) -- [View on docs.rs](https://docs.rs/radix-yew-aspect-ratio/latest/radix_yew_aspect_ratio/) -- [View source](https://github.com/RustForWeb/radix/tree/main/packages/primitives/yew/aspect-ratio) +- [View on crates.io](https://crates.io/crates/radix-yew-aspect-ratio) +- [View on docs.rs](https://docs.rs/radix-yew-aspect-ratio/latest/radix_yew_aspect_ratio/) +- [View source](https://github.com/RustForWeb/radix/tree/main/packages/primitives/yew/aspect-ratio) -{{#endtab }} -{{#endtabs }} +{{#endtab}} +{{#endtabs}} ## Anatomy -Import the component. - -{{#tabs global="framework" }} -{{#tab name="Leptos" }} +{{#tabs global="framework"}} +{{#tab name="Leptos"}} ```rust,ignore use leptos::*; -use radix_leptos_aspect_ratio::*; +use radix_leptos_aspect_ratio as AspectRatio; #[component] fn Anatomy() -> impl IntoView { view! { - + +
"Constrained within the 16:9 ratio!"
+
} } ``` -{{#endtab }} -{{#tab name="Yew" }} +{{#endtab}} +{{#tab name="Yew"}} ```rust,ignore use radix_yew_aspect_ratio::*; -use yew::prelude::::*; +use yew::prelude::*; #[function_component] fn Anatomy() -> Html { html! { - + + {"Constrained within the desired ratio!"} + } } ``` -{{#endtab }} -{{#endtabs }} +{{#endtab}} +{{#endtabs}} ## API Reference @@ -99,24 +101,47 @@ fn Anatomy() -> Html { Contains the content you want to constrain to a given ratio. -{{#tabs global="framework" }} -{{#tab name="Leptos" }} +{{#tabs global="framework"}} +{{#tab name="Leptos"}} + +| Prop | Type | Default | +|------------|-------------------|---------| +| `as_child` | `MaybeProp` | `false` | +| `ratio` | `MaybeProp` | `1.0` | +| `node_ref` | `AnyNodeRef` | - | + +### Usage + +To use the `Root` alias for the `AspectRatio` component, import it and use `AspectRatio::Root` in your view. + +```rust,ignore +use leptos::*; +use radix_leptos_aspect_ratio as AspectRatio; + +#[component] +fn Example() -> impl IntoView { + view! { + + Example Image + + } +} +``` -| Prop | Type | Default | -| ------- | ---------------- | ------- | -| `ratio` | `MaybeProp` | `1.0` | +{{#endtab}} +{{#tab name="Yew"}} -{{#endtab }} -{{#tab name="Yew" }} + -| Prop | Type | Default | -| ---------- | ----------------------------------------------- | ------- | -| `as_child` | `Option>` | - | -| `ratio` | `f64` | `1.0` | +| Prop | Type | Default | +|---------|-------|---------| +| `ratio` | `f64` | `1.0` | -{{#endtab }} -{{#endtabs }} +{{#endtab}} +{{#endtabs}} ## See Also -- [Radix documentation](https://www.radix-ui.com/primitives/docs/components/aspect-ratio) +- [Radix documentation](https://www.radix-ui.com/primitives/docs/components/aspect-ratio) + +``` \ No newline at end of file From e24c136c4a6c7aed414d851ec3cc7cf20ea8c558 Mon Sep 17 00:00:00 2001 From: geoffreygarrett Date: Wed, 8 Jan 2025 18:08:08 +0200 Subject: [PATCH 9/9] Update Aspect Ratio to Leptos 0.7 --- .../primitives/leptos/aspect-ratio/README.md | 2 +- .../leptos/aspect-ratio/src/aspect_ratio.rs | 65 ++++++++++--------- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/packages/primitives/leptos/aspect-ratio/README.md b/packages/primitives/leptos/aspect-ratio/README.md index 98d2a736..02e4a0df 100644 --- a/packages/primitives/leptos/aspect-ratio/README.md +++ b/packages/primitives/leptos/aspect-ratio/README.md @@ -16,6 +16,6 @@ See [the Rust Radix book](https://radix.rustforweb.org/) for documentation. ## Rust For Web -The Rust Radix project is part of the [Rust For Web](https://github.com/RustForWeb). +The Rust Radix project is part of [Rust For Web](https://github.com/RustForWeb). [Rust For Web](https://github.com/RustForWeb) creates and ports web UI libraries for Rust. All projects are free and open source. diff --git a/packages/primitives/leptos/aspect-ratio/src/aspect_ratio.rs b/packages/primitives/leptos/aspect-ratio/src/aspect_ratio.rs index 971859e7..2590151f 100644 --- a/packages/primitives/leptos/aspect-ratio/src/aspect_ratio.rs +++ b/packages/primitives/leptos/aspect-ratio/src/aspect_ratio.rs @@ -1,4 +1,4 @@ -use leptos::{prelude::*, html}; +use leptos::{prelude::*, html, attribute_interceptor::AttributeInterceptor}; use radix_leptos_primitive::Primitive; use leptos_node_ref::AnyNodeRef; @@ -15,19 +15,19 @@ const NAME: &'static str = "AspectRatio"; pub fn AspectRatio( /// Children passed to the AspectRatio component children: TypedChildrenFn, - /// Change the default rendered element for the one passed as a child #[prop(into, optional, default = false.into())] as_child: MaybeProp, - /// The desired ratio when rendering the content (e.g., 16/9). Defaults to 1.0 if not specified. #[prop(into, optional, default = DEFAULT_RATIO.into())] ratio: MaybeProp, - /// Reference to the underlying DOM node #[prop(into, optional)] node_ref: AnyNodeRef, ) -> impl IntoView { + // attribute interceptor incurs this requirement + let children = StoredValue::new(children.into_inner()); + // calculates the percent-based padding for the aspect ratio let padding_bottom = Signal::derive(move || { 100.0 @@ -42,38 +42,39 @@ pub fn AspectRatio( leptos::logging::log!("[{NAME}] ratio: {:?}", ratio.get()); leptos::logging::log!("[{NAME}] as_child: {:?}", as_child.get()); leptos::logging::log!("[{NAME}] node_ref: {:?}", node_ref.get()); + leptos::logging::log!("[{NAME}] padding_bottom: {:?}", padding_bottom.get()); }); view! { - // ensures inner element is contained -
- -
+ // replicate the radix react spread props + + // ensures inner element is contained +
+ + {children.with_value(|children| children())} + +
+
} } -/* ------------------------------------------------------------------------------------------------- - * Primitive re-exports - * -----------------------------------------------------------------------------------------------*/ +/* -----------------------------------------------------------------------------------------------*/ -pub mod primitive { - pub use super::*; - pub use AspectRatio as Root; -} +pub use AspectRatio as Root;