feat: allow arbitrary attributes for `<A/>` component (#1953)
This commit is contained in:
parent
3394e316b7
commit
a11c6303e2
|
@ -96,6 +96,10 @@ pub fn A<H>(
|
|||
/// Sets the `id` attribute on the underlying `<a>` tag, making it easier to target.
|
||||
#[prop(optional, into)]
|
||||
id: Option<Oco<'static, str>>,
|
||||
/// Arbitrary attributes to add to the `<a>`. Attributes can be added with the
|
||||
/// `attr:` syntax in the `view` macro.
|
||||
#[prop(attrs)]
|
||||
attributes: Vec<(&'static str, Attribute)>,
|
||||
/// The nodes or elements to be shown inside the link.
|
||||
children: Children,
|
||||
) -> impl IntoView
|
||||
|
@ -115,6 +119,7 @@ where
|
|||
class: Option<AttributeValue>,
|
||||
#[allow(unused)] active_class: Option<Oco<'static, str>>,
|
||||
id: Option<Oco<'static, str>>,
|
||||
#[allow(unused)] attributes: Vec<(&'static str, Attribute)>,
|
||||
children: Children,
|
||||
) -> View {
|
||||
#[cfg(not(any(feature = "hydrate", feature = "csr")))]
|
||||
|
@ -147,74 +152,90 @@ where
|
|||
|
||||
#[cfg(feature = "ssr")]
|
||||
{
|
||||
// if we have `active_class`, the SSR optimization doesn't play nicely
|
||||
// if we have `active_class` or arbitrary attributes,
|
||||
// the SSR optimization doesn't play nicely
|
||||
// so we use the builder instead
|
||||
if let Some(active_class) = active_class {
|
||||
let mut a = leptos::html::a()
|
||||
.attr("href", move || href.get().unwrap_or_default())
|
||||
.attr("target", target)
|
||||
.attr("aria-current", move || {
|
||||
if is_active.get() {
|
||||
Some("page")
|
||||
} else {
|
||||
None
|
||||
let needs_builder =
|
||||
active_class.is_some() || !attributes.is_empty();
|
||||
if needs_builder {
|
||||
let mut a = leptos::html::a()
|
||||
.attr("href", move || href.get().unwrap_or_default())
|
||||
.attr("target", target)
|
||||
.attr("aria-current", move || {
|
||||
if is_active.get() {
|
||||
Some("page")
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.attr(
|
||||
"class",
|
||||
class.map(|class| class.into_attribute_boxed()),
|
||||
);
|
||||
|
||||
if let Some(active_class) = active_class {
|
||||
for class_name in active_class.split_ascii_whitespace()
|
||||
{
|
||||
a = a.class(class_name.to_string(), move || {
|
||||
is_active.get()
|
||||
})
|
||||
}
|
||||
})
|
||||
.attr(
|
||||
"class",
|
||||
class.map(|class| class.into_attribute_boxed()),
|
||||
);
|
||||
}
|
||||
|
||||
for class_name in active_class.split_ascii_whitespace() {
|
||||
a = a.class(class_name.to_string(), move || is_active.get())
|
||||
a = a.attr("id", id).child(children());
|
||||
|
||||
for (attr_name, attr_value) in attributes {
|
||||
a = a.attr(attr_name, attr_value);
|
||||
}
|
||||
|
||||
a
|
||||
}
|
||||
|
||||
a.attr("id", id).child(children()).into_view()
|
||||
}
|
||||
// but keep the nice SSR optimization in most cases
|
||||
else {
|
||||
view! {
|
||||
<a
|
||||
href=move || href.get().unwrap_or_default()
|
||||
target=target
|
||||
aria-current=move || if is_active.get() { Some("page") } else { None }
|
||||
class=class
|
||||
id=id
|
||||
>
|
||||
{children()}
|
||||
</a>
|
||||
// but keep the nice SSR optimization in most cases
|
||||
else {
|
||||
view! {
|
||||
<a
|
||||
href=move || href.get().unwrap_or_default()
|
||||
target=target
|
||||
aria-current=move || if is_active.get() { Some("page") } else { None }
|
||||
class=class
|
||||
id=id
|
||||
>
|
||||
{children()}
|
||||
</a>
|
||||
}
|
||||
}
|
||||
.into_view()
|
||||
}
|
||||
}
|
||||
|
||||
// the non-SSR version doesn't need the SSR optimizations
|
||||
// DRY here to avoid WASM binary size bloat
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
{
|
||||
let a = view! {
|
||||
let mut a = view! {
|
||||
<a
|
||||
href=move || href.get().unwrap_or_default()
|
||||
target=target
|
||||
prop:state={state.map(|s| s.to_js_value())}
|
||||
prop:replace={replace}
|
||||
aria-current=move || if is_active.get() { Some("page") } else { None }
|
||||
prop:state=state.map(|s| s.to_js_value())
|
||||
prop:replace=replace
|
||||
aria-current=move || if is_active.get() { Some("a") } else { None }
|
||||
class=class
|
||||
id=id
|
||||
>
|
||||
{children()}
|
||||
</a>
|
||||
};
|
||||
|
||||
if let Some(active_class) = active_class {
|
||||
let mut a = a;
|
||||
for class_name in active_class.split_ascii_whitespace() {
|
||||
a = a.class(class_name.to_string(), move || is_active.get())
|
||||
}
|
||||
a
|
||||
} else {
|
||||
a
|
||||
}
|
||||
.into_view()
|
||||
|
||||
for (attr_name, attr_value) in attributes {
|
||||
a = a.attr(attr_name, attr_value);
|
||||
}
|
||||
|
||||
a.into_view()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,6 +249,7 @@ where
|
|||
class,
|
||||
active_class,
|
||||
id,
|
||||
attributes,
|
||||
children,
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue