Skip to content

Commit 7366fd8

Browse files
committed
feat!: frender_with_attrs
1 parent c993cb9 commit 7366fd8

File tree

12 files changed

+175
-4
lines changed

12 files changed

+175
-4
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/frender-attrs/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ frender-ssr-html = { version = "0.1.0", path = "../frender-ssr-html", optional =
1616
async-str-iter = { version = "0.1.0", path = "../async-str-iter", optional = true }
1717

1818
[features]
19-
default = ["csr", "ssr", "either"] # TODO: remove
2019
csr = []
2120
ssr = ["dep:frender-ssr-html", "dep:async-str-iter"]
2221
either = ["dep:either"]
22+
experimental = []
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#[cfg(feature = "csr")]
2+
pub mod csr {
3+
pub use crate::csr::{CsrAttributes, RenderAttributes};
4+
}
5+
6+
#[cfg(feature = "ssr")]
7+
pub mod ssr {
8+
pub use crate::ssr::SsrAttributes;
9+
}

packages/frender-attrs/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
pub mod values;
22

33
#[cfg(feature = "csr")]
4-
pub mod csr;
4+
mod csr;
55
#[cfg(feature = "ssr")]
6-
pub mod ssr;
6+
mod ssr;
77

88
pub mod attrs;
99

@@ -38,3 +38,6 @@ mod sealed {
3838
#[cfg(not(feature = "ssr"))]
3939
pub trait Attributes {}
4040
}
41+
42+
#[cfg(feature = "experimental")]
43+
pub mod experimental;

packages/frender-html/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ frender-attr-value = { version = "0.1.0", path = "../frender-attr-value", featur
2424
"html",
2525
"experimental",
2626
] }
27+
frender-attrs = { version = "0.1.0", path = "../frender-attrs", features = [
28+
"experimental",
29+
] }
2730
frender-form-control = { version = "0.1.0", path = "../frender-form-control", features = [
2831
"ssr",
2932
] }
@@ -120,6 +123,7 @@ macros_not_expanded = []
120123
components = []
121124
csr = [
122125
"frender-attr-value/csr",
126+
"frender-attrs/csr",
123127
"frender-dom/csr",
124128
"frender-form-control/csr",
125129
"frender-style/csr",
@@ -129,6 +133,7 @@ csr = [
129133
ssr = [
130134
"dep:frender-ssr",
131135
"frender-attr-value/ssr",
136+
"frender-attrs/ssr",
132137
"frender-dom/ssr",
133138
"frender-form-control/ssr",
134139
"frender-style/ssr",
@@ -147,6 +152,8 @@ web = [
147152
# Also requires csr
148153
either = [
149154
"dep:either",
155+
"frender-attr-value/either",
156+
"frender-attrs/either",
150157
"frender-ssr/either",
151158
"frender-dom/either",
152159
"frender-form-control/either",

packages/frender-html/src/attrs.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use frender_attrs::IntoAttributes;
2+
3+
pub struct Attrs<A: IntoAttributes>(pub A);
4+
5+
#[cfg(feature = "csr")]
6+
mod csr;
7+
#[cfg(feature = "ssr")]
8+
mod ssr;
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use std::marker::PhantomData;
2+
3+
use frender_attrs::{
4+
experimental::csr::{CsrAttributes, RenderAttributes},
5+
IntoAttributes,
6+
};
7+
use frender_common::convert::FromMut as _;
8+
use frender_dom::csr::behaviors;
9+
10+
use crate::{
11+
csr::behavior_type::{BehaviorType, UnpinnedNonReactiveRenderStateKind, UnpinnedRenderWithBehavior},
12+
html::{behavior_type_traits, RenderHtml},
13+
};
14+
15+
use super::Attrs;
16+
17+
enum Never {}
18+
pub struct StateKind<S>(Never, PhantomData<S>);
19+
20+
impl<S> UnpinnedNonReactiveRenderStateKind for StateKind<S> {
21+
type UnpinnedNonReactiveState<R: ?Sized + RenderHtml> = S;
22+
}
23+
24+
impl<
25+
//
26+
BT: behavior_type_traits::Element,
27+
T: IntoAttributes,
28+
> UnpinnedRenderWithBehavior<BT> for Attrs<T>
29+
{
30+
type UnpinnedRenderStateKind = StateKind<<T::IntoAttributes as CsrAttributes>::State>;
31+
32+
fn unpinned_render_init_with_behavior<R: ?Sized + RenderHtml>(
33+
//
34+
this: Self,
35+
renderer: &mut R,
36+
b: &mut <BT as BehaviorType>::OfBehaviorType<R>,
37+
) -> <Self::UnpinnedRenderStateKind as crate::csr::behavior_type::UnpinnedNonReactiveRenderStateKind>::UnpinnedNonReactiveState<R> {
38+
T::into_attributes(this.0).render_init(&mut Render {
39+
renderer,
40+
element: BT::Element::from_mut(b),
41+
})
42+
}
43+
44+
fn unpinned_render_update_with_behavior<R: ?Sized + RenderHtml>(
45+
//
46+
this: Self,
47+
renderer: &mut R,
48+
b: &mut <BT as BehaviorType>::OfBehaviorType<R>,
49+
state: &mut <Self::UnpinnedRenderStateKind as crate::csr::behavior_type::UnpinnedNonReactiveRenderStateKind>::UnpinnedNonReactiveState<R>,
50+
) {
51+
T::into_attributes(this.0).render_update(
52+
&mut Render {
53+
renderer,
54+
element: BT::Element::from_mut(b),
55+
},
56+
state,
57+
)
58+
}
59+
}
60+
61+
struct Render<'a, R: ?Sized, E: ?Sized> {
62+
renderer: &'a mut R,
63+
element: &'a mut E,
64+
}
65+
66+
impl<R: ?Sized, E: ?Sized + behaviors::Element<R>> RenderAttributes for Render<'_, R, E> {
67+
fn set_attribute(&mut self, name: &str, value: &str) {
68+
self.element.set_attribute(self.renderer, name, value)
69+
}
70+
71+
fn remove_attribute(&mut self, name: &str) {
72+
self.element.remove_attribute(self.renderer, name)
73+
}
74+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use frender_attrs::{experimental::ssr::SsrAttributes, IntoAttributes};
2+
use frender_dom::ssr::IntoSpaceAndHtmlAttributesOrEmpty;
3+
4+
use super::Attrs;
5+
6+
impl<T: IntoAttributes> IntoSpaceAndHtmlAttributesOrEmpty for Attrs<T> {
7+
type SpaceAndHtmlAttributesOrEmpty = <T::IntoAttributes as SsrAttributes>::IntoSsrAttributes;
8+
9+
fn into_space_and_html_attributes_or_empty(self) -> Self::SpaceAndHtmlAttributesOrEmpty {
10+
T::into_attributes(self.0).into_ssr_attributes()
11+
}
12+
}

packages/frender-html/src/intrinsic.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
use frender_attrs::IntoAttributes;
12
use frender_common::Empty;
23

34
#[cfg(feature = "csr")]
45
pub(crate) use csr_attr_state::AttributeState;
56

7+
use crate::values::Attrs;
8+
69
#[cfg(feature = "csr")]
710
mod csr_attr_state;
811

@@ -197,4 +200,14 @@ impl<M, C, A, P> Intrinsic<M, C, A, P> {
197200
{
198201
Self::with_any_attribute_with_pinned_state_appended(this, attr_with_pinned_state)
199202
}
203+
204+
/// This method is prefixed with `frender_` so that it probably won't conflict with html attribute names.
205+
pub fn frender_with_attrs<IntoAttrs: IntoAttributes>(self, attrs: IntoAttrs) -> Intrinsic<M, C, (A, Attrs<IntoAttrs>), P> {
206+
Intrinsic {
207+
type_marker: self.type_marker,
208+
attributes: (self.attributes, Attrs(attrs)),
209+
attributes_with_pinned_state: self.attributes_with_pinned_state,
210+
children: self.children,
211+
}
212+
}
200213
}

packages/frender-html/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub mod __private {
3838
mod special;
3939

4040
mod attr_value;
41+
mod attrs;
4142
mod dom_tokens;
4243
mod event_listener;
4344
mod style;

0 commit comments

Comments
 (0)