2 unstable releases
0.2.0 | Jun 25, 2021 |
---|---|
0.1.0 | Jun 24, 2021 |
#50 in #web-ui
370KB
9K
SLoC
Consecuit HTML
lib.rs
:
HTML components for [consecuit].
This crate provides components like div
, span
, table
for [consecuit].
Basic usage
Also see the docs at [consecuit], as it also contain some info on how to use this.
First, import the prelude:
use consecuit_html::prelude::*;
Then you can use the components in the cc_tree!
macro with the same structure as HTML:
cc_tree!(
<div>
<div>
</div>
</div>
<span>"hello"</span>
)
Props
All components in this crate takes props that can be built with builder pattern.
Start with [html_props()
][elem::html_props()], then add your attributes.
Like this:
cc_tree!(
<div {html_props().class_name("container container-box").onclick(click_handler)}>
</div>
)
String attributes like class_name
or href
take anything that is Into<Cow<'static, str>>
.
In the code above, class_name
can take "container container-box"
because it is &'static str
which is Into<Cow<'static, str>>
.
Event attributes like onclick
or oninput
take a Callback
.
A Callback
can be created with Callback::new
, like this:
let click_handler = Callback::new(move |ev: web_sys::MouseEvent| {
web_sys::console::log_1(
&"You clicked the button!".into()
);
});
cc_tree!(
<button {html_props().onclick(click_handler)}>"click me!"</button>
)
Sometimes you may get error about ambigous props.
For example, many different components take href
.
The compiler won't allow this:
<a {html_props().href("https://example.com")}>"Go to web"</a>
You have to use HtmlProps<(web_sys type of your element)> instead. For example:
<a {HtmlProps::<web_sys::HtmlAnchorElement>::new().href("https://example.com")}>"Go to web"</a>
Reference
To get a reference to the underlying [web_sys] element, you can use the reference
prop.
The reference
prop takes a Reference of Option of the element type.
For instance, the input tag (<input>
) has web_sys::HtmlInputElement as the underlying element.
So its reference must be a Reference<Option<web_sys::HtmlInputElement>>
.
let (cc, input_ref): (_, Reference<Option<web_sys::HtmlInputElement>>) = cc.hook(use_ref, ());
cc_tree!(
<input {html_props().reference(input_ref)} />
)
The Option inside the reference is guarunteed to be Some after the component rendered atleast once.
You can then use the methods in Reference to do things with the underlying [web_sys] element.
For example, this read the value of an and set it to empty.
let (cc, input_ref): (_, Reference<Option<web_sys::HtmlInputElement>>) = cc.hook(use_ref, ());
let submit_click_handler = Callback::new(move |_ev| {
let input_value = input_ref.visit_with(|opt: &Option<web_sys::HtmlInputElement>| {
// Unwrap the Option<web_sys::HtmlInputElement>
let inp: &web_sys::HtmlInputElement = opt.as_ref().unwrap();
// Get the value
let value = inp.value();
// Set it to empty
inp.set_value("");
value
}).unwrap();
web_sys::console::log_1(&format!("The submitted value was: {}", input_value).into());
});
cc_tree!(
<input {html_props().reference(input_ref)} />
<button {html_props().onclick(submit_click_handler)}>"submit"</button>
)
Notes
Most of the components and props in this crate are generated by a combination of parsing [web_sys]'s API and scraping MDN.
Only attributes with a set_
method provided by [web_sys] are available as props.
For example, [web_sys] has set_class_name
, so we have class_name
prop.
Most notably missing is styling. [web_sys] does not have set_style
. (it has a more sophisicated system for styling).
You have to stick with class names and CSS for now.
Contributions are welcome.
Dependencies
~10MB
~203K SLoC