diff --git a/Cargo.lock b/Cargo.lock index 9abe8545..54b9a12c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2841,6 +2841,14 @@ dependencies = [ "web-sys", ] +[[package]] +name = "radix-leptos-accessible-icon" +version = "0.0.2" +dependencies = [ + "leptos", + "radix-leptos-visually-hidden", +] + [[package]] name = "radix-leptos-book-icons" version = "0.0.2" @@ -2886,6 +2894,7 @@ dependencies = [ "leptos", "leptos_router", "log", + "radix-leptos-accessible-icon", "radix-leptos-label", "radix-leptos-visually-hidden", "tailwind_fuse", diff --git a/Cargo.toml b/Cargo.toml index 4ddfd5d3..1c199903 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ members = [ "packages/colors", "packages/icons/dioxus", "packages/icons/yew", + "packages/primitives/leptos/accessible-icon", "packages/primitives/leptos/id", "packages/primitives/leptos/label", "packages/primitives/leptos/visually-hidden", diff --git a/book/src/primitives/utilities/accessible-icon.md b/book/src/primitives/utilities/accessible-icon.md index 9c0abbd9..78eb6fae 100644 --- a/book/src/primitives/utilities/accessible-icon.md +++ b/book/src/primitives/utilities/accessible-icon.md @@ -56,9 +56,9 @@ Contains the icon to make accessible. {{#tabs global="framework" }} {{#tab name="Leptos" }} -| Prop | Type | Default | -| ------- | --------------------- | ------- | -| `label` | `MaybeSignal` | - | +| Prop | Type | Default | +| ------- | ---------------- | ------- | +| `label` | `Signal` | - | {{#endtab }} {{#endtabs }} diff --git a/book/src/primitives/utilities/visually-hidden.md b/book/src/primitives/utilities/visually-hidden.md index 1f3cb43a..f420d132 100644 --- a/book/src/primitives/utilities/visually-hidden.md +++ b/book/src/primitives/utilities/visually-hidden.md @@ -81,9 +81,7 @@ Anything you put inside this component will be hidden from the screen but will b {{#tabs global="framework" }} {{#tab name="Leptos" }} -| Prop | Type | Default | -| ---------- | ----------------- | ------- | -| `as_child` | `MaybeProp` | `false` | +No props. {{#endtab }} {{#tab name="Yew" }} @@ -112,7 +110,7 @@ fn Example() -> impl IntoView { view! { } } diff --git a/packages/primitives/leptos/accessible-icon/src/accessible_icon.rs b/packages/primitives/leptos/accessible-icon/src/accessible_icon.rs index 29840caf..6c085e05 100644 --- a/packages/primitives/leptos/accessible-icon/src/accessible_icon.rs +++ b/packages/primitives/leptos/accessible-icon/src/accessible_icon.rs @@ -1,36 +1,38 @@ -use leptos::*; +use leptos::{ + attr::{ + aria_hidden, + custom::{custom_attribute, CustomAttr}, + AriaHidden, Attr, NextAttribute, + }, + prelude::*, +}; use radix_leptos_visually_hidden::VisuallyHidden; +pub type AccessibleIconAttrs = ( + Attr, + CustomAttr<&'static str, &'static str>, +); + +pub fn use_accessible_icon() -> AccessibleIconAttrs { + aria_hidden("true").add_any_attr(custom_attribute("focusable", "false")) +} + #[component] -pub fn AccessibleIcon( +pub fn AccessibleIcon( /// The accessible label for the icon. This label will be visually hidden but announced to screen reader users, /// similar to `alt` text for `img` tags. #[prop(into)] - label: MaybeSignal, - #[prop(optional)] children: Option, -) -> impl IntoView { - let label = Signal::derive(move || label.get()); + label: Signal, + render: R, +) -> impl IntoView +where + R: Fn(AccessibleIconAttrs) -> IV, + IV: IntoView, +{ + let attrs = use_accessible_icon(); view! { - {children.map(|children| map_children(children().as_children()))} + {render(attrs)} {label} } } - -fn map_children(children: &[View]) -> View { - children - .iter() - .map(|child| match child { - View::Element(element) => element - .clone() - .into_html_element() - // Accessibility - .attr("aria-hidden", "true") - // See: https://allyjs.io/tutorials/focusing-in-svg.html#making-svg-elements-focusable - .attr("focusable", "false") - .into_view(), - View::Component(component) => map_children(&component.children), - _ => child.into_view(), - }) - .collect_view() -} diff --git a/stories/leptos/Cargo.toml b/stories/leptos/Cargo.toml index 2035fad9..e20522bf 100644 --- a/stories/leptos/Cargo.toml +++ b/stories/leptos/Cargo.toml @@ -15,7 +15,7 @@ console_error_panic_hook.workspace = true leptos = { workspace = true, features = ["csr"] } leptos_router.workspace = true log.workspace = true -# radix-leptos-accessible-icon = { path = "../../packages/primitives/leptos/accessible-icon" } +radix-leptos-accessible-icon = { path = "../../packages/primitives/leptos/accessible-icon" } # radix-leptos-arrow = { path = "../../packages/primitives/leptos/arrow" } # radix-leptos-aspect-ratio = { path = "../../packages/primitives/leptos/aspect-ratio" } # radix-leptos-avatar = { path = "../../packages/primitives/leptos/avatar" } diff --git a/stories/leptos/src/app.rs b/stories/leptos/src/app.rs index b905471d..1515fd2f 100644 --- a/stories/leptos/src/app.rs +++ b/stories/leptos/src/app.rs @@ -8,7 +8,7 @@ use leptos_router::{ // accessible_icon, arrow, aspect_ratio, avatar, checkbox, collection, focus_scope, label, menu, // popper, portal, presence, progress, separator, slot, switch, toggle, visually_hidden, // }; -use crate::primitives::{label, visually_hidden}; +use crate::primitives::{accessible_icon, label, visually_hidden}; #[component] fn NavLink(href: H, children: Children) -> impl IntoView @@ -39,14 +39,14 @@ pub fn App() -> impl IntoView {
  • Index
  • - //
  • - // Accessible Icon +
  • + Accessible Icon - //
      - //
    • Styled
    • - //
    • Chromatic
    • - //
    - //
  • +
      +
    • Styled
    • +
    • Chromatic
    • +
    + //
  • // Arrow @@ -211,8 +211,8 @@ pub fn App() -> impl IntoView { - // - // + + // // diff --git a/stories/leptos/src/primitives.rs b/stories/leptos/src/primitives.rs index 9d65921e..807589dc 100644 --- a/stories/leptos/src/primitives.rs +++ b/stories/leptos/src/primitives.rs @@ -1,4 +1,4 @@ -// pub mod accessible_icon; +pub mod accessible_icon; // pub mod arrow; // pub mod aspect_ratio; // pub mod avatar; diff --git a/stories/leptos/src/primitives/accessible_icon.rs b/stories/leptos/src/primitives/accessible_icon.rs index a0071d22..54b1f1e0 100644 --- a/stories/leptos/src/primitives/accessible_icon.rs +++ b/stories/leptos/src/primitives/accessible_icon.rs @@ -1,13 +1,16 @@ -use leptos::*; +use leptos::prelude::*; use radix_leptos_accessible_icon::*; #[component] pub fn Styled() -> impl IntoView { view! { } } @@ -17,19 +20,21 @@ pub fn Chromatic() -> impl IntoView { view! {

    Some text with an inline accessible icon{" "} - - - + + } + />

    } } #[component] -fn CrossIcon(#[prop(attrs)] attrs: Vec<(&'static str, Attribute)>) -> impl IntoView { +fn CrossIcon() -> impl IntoView { view! { } - .attrs(attrs) }