feat: add aria
This commit is contained in:
1 parent
c79d9ae674
commit
4091846934
11 files changed
+322
-97
No files matched your search
@@ -170,10 +170,10 @@ Dioxus is heavily inspired by React, but we want your transition to feel like an
|
|||||||
| Suspense | 🛠 | ✅ | schedule future render from future/promise |
|
| Suspense | 🛠 | ✅ | schedule future render from future/promise |
|
||||||
| Cooperative Scheduling | 🛠 | ✅ | Prioritize important events over non-important events |
|
| Cooperative Scheduling | 🛠 | ✅ | Prioritize important events over non-important events |
|
||||||
| Fine-grained reactivity | 🛠 | ❓ | Skip diffing for fine-grain updates |
|
| Fine-grained reactivity | 🛠 | ❓ | Skip diffing for fine-grain updates |
|
||||||
| Compile-time correct | ✅ | ❓ | Throw errors on invalid template layouts |
|
|
||||||
| Runs natively | ✅ | ❓ | runs as a portable binary w/o a runtime (Node) |
|
| Runs natively | ✅ | ❓ | runs as a portable binary w/o a runtime (Node) |
|
||||||
| 1st class global state | ✅ | ❓ | redux/recoil/mobx on top of context |
|
| 1st class global state | ✅ | ❓ | redux/recoil/mobx on top of context |
|
||||||
| Subtree Memoization | ✅ | ❓ | skip diffing static element subtrees |
|
| Subtree Memoization | ✅ | ❓ | skip diffing static element subtrees |
|
||||||
|
| Compile-time correct | ✅ | ❓ | Throw errors on invalid template layouts |
|
||||||
| Heuristic Engine | 🛠 | ❓ | track component memory usage to minimize future allocations |
|
| Heuristic Engine | 🛠 | ❓ | track component memory usage to minimize future allocations |
|
||||||
| NodeRef | 🛠 | ✅ | gain direct access to nodes [1] |
|
| NodeRef | 🛠 | ✅ | gain direct access to nodes [1] |
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ static Example: FC<()> = |cx| {
|
|||||||
|
|
||||||
// Expressions can be used in element position too:
|
// Expressions can be used in element position too:
|
||||||
{rsx!(p { "More templating!" })}
|
{rsx!(p { "More templating!" })}
|
||||||
{html!(<p>"Even HTML templating!!"</p>)}
|
// {html!(<p>"Even HTML templating!!"</p>)}
|
||||||
|
|
||||||
// Iterators
|
// Iterators
|
||||||
{(0..10).map(|i| rsx!(li { "{i}" }))}
|
{(0..10).map(|i| rsx!(li { "{i}" }))}
|
||||||
|
|||||||
+4
-1
@@ -2,7 +2,7 @@ use std::cell::Cell;
|
|||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_core::{
|
use dioxus_core::{
|
||||||
nodes::{NodeKey, VElement, VText},
|
nodes::{VElement, VText},
|
||||||
RealDomNode,
|
RealDomNode,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -23,6 +23,9 @@ const Example: FC<()> = |cx| {
|
|||||||
Fragment {
|
Fragment {
|
||||||
Fragment {
|
Fragment {
|
||||||
"h1"
|
"h1"
|
||||||
|
div {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"h2"
|
"h2"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ impl ToTokens for Component {
|
|||||||
#name,
|
#name,
|
||||||
#builder,
|
#builder,
|
||||||
#key_token,
|
#key_token,
|
||||||
#children
|
__cx.bump().alloc(#children)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,37 +23,18 @@ pub struct Element {
|
|||||||
impl ToTokens for Element {
|
impl ToTokens for Element {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream2) {
|
fn to_tokens(&self, tokens: &mut TokenStream2) {
|
||||||
let name = &self.name;
|
let name = &self.name;
|
||||||
|
let attr = &self.attributes;
|
||||||
|
let childs = &self.children;
|
||||||
|
let listeners = &self.listeners;
|
||||||
|
|
||||||
tokens.append_all(quote! {
|
tokens.append_all(quote! {
|
||||||
__cx.element(dioxus_elements::#name)
|
__cx.element(
|
||||||
});
|
dioxus_elements::#name,
|
||||||
|
__cx.bump().alloc([ #(#listeners),* ]),
|
||||||
// By gating these methods, we can keep the output of `cargo expand` readable.
|
__cx.bump().alloc([ #(#attr),* ]),
|
||||||
// We also prevent the issue where zero-sized arrays fail to have propery type inference.
|
__cx.bump().alloc([ #(#childs),* ]),
|
||||||
|
None,
|
||||||
if self.attributes.len() > 0 {
|
)
|
||||||
let attr = &self.attributes;
|
|
||||||
tokens.append_all(quote! {
|
|
||||||
.attributes([ #(#attr),* ])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.children.len() > 0 {
|
|
||||||
let childs = &self.children;
|
|
||||||
tokens.append_all(quote! {
|
|
||||||
.children([ #(#childs),* ])
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.listeners.len() > 0 {
|
|
||||||
let listeners = &self.listeners;
|
|
||||||
tokens.append_all(quote! {
|
|
||||||
.listeners([ #(#listeners),* ])
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
tokens.append_all(quote! {
|
|
||||||
.finish()
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,7 +64,13 @@ impl Parse for Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if content.peek(Ident) && content.peek2(Token![:]) && !content.peek3(Token![:]) {
|
if content.peek(Ident) && content.peek2(Token![:]) && !content.peek3(Token![:]) {
|
||||||
parse_element_body(&content, &mut attributes, &mut listeners, &mut key)?;
|
parse_element_body(
|
||||||
|
&content,
|
||||||
|
&mut attributes,
|
||||||
|
&mut listeners,
|
||||||
|
&mut key,
|
||||||
|
name.clone(),
|
||||||
|
)?;
|
||||||
} else {
|
} else {
|
||||||
children.push(content.parse::<Node>()?);
|
children.push(content.parse::<Node>()?);
|
||||||
}
|
}
|
||||||
@@ -110,6 +97,7 @@ impl Parse for Element {
|
|||||||
/// Parse a VElement's Attributes
|
/// Parse a VElement's Attributes
|
||||||
/// =======================================
|
/// =======================================
|
||||||
struct ElementAttr {
|
struct ElementAttr {
|
||||||
|
element_name: Ident,
|
||||||
name: Ident,
|
name: Ident,
|
||||||
value: AttrType,
|
value: AttrType,
|
||||||
namespace: Option<String>,
|
namespace: Option<String>,
|
||||||
@@ -130,6 +118,7 @@ fn parse_element_body(
|
|||||||
attrs: &mut Vec<ElementAttr>,
|
attrs: &mut Vec<ElementAttr>,
|
||||||
listeners: &mut Vec<ElementAttr>,
|
listeners: &mut Vec<ElementAttr>,
|
||||||
key: &mut Option<AttrType>,
|
key: &mut Option<AttrType>,
|
||||||
|
element_name: Ident,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut name = Ident::parse_any(stream)?;
|
let mut name = Ident::parse_any(stream)?;
|
||||||
let name_str = name.to_string();
|
let name_str = name.to_string();
|
||||||
@@ -159,6 +148,7 @@ fn parse_element_body(
|
|||||||
name,
|
name,
|
||||||
value: ty,
|
value: ty,
|
||||||
namespace: None,
|
namespace: None,
|
||||||
|
element_name: element_name.clone(),
|
||||||
});
|
});
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@@ -186,6 +176,7 @@ fn parse_element_body(
|
|||||||
name,
|
name,
|
||||||
value: ty,
|
value: ty,
|
||||||
namespace: Some("style".to_string()),
|
namespace: Some("style".to_string()),
|
||||||
|
element_name: element_name.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,13 +218,15 @@ fn parse_element_body(
|
|||||||
name,
|
name,
|
||||||
value: ty,
|
value: ty,
|
||||||
namespace: None,
|
namespace: None,
|
||||||
|
element_name,
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToTokens for ElementAttr {
|
impl ToTokens for ElementAttr {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream2) {
|
fn to_tokens(&self, tokens: &mut TokenStream2) {
|
||||||
let name = self.name.to_string();
|
let el_name = &self.element_name;
|
||||||
|
let name_str = self.name.to_string();
|
||||||
let nameident = &self.name;
|
let nameident = &self.name;
|
||||||
|
|
||||||
let namespace = match &self.namespace {
|
let namespace = match &self.namespace {
|
||||||
@@ -243,12 +236,22 @@ impl ToTokens for ElementAttr {
|
|||||||
|
|
||||||
match &self.value {
|
match &self.value {
|
||||||
AttrType::BumpText(value) => tokens.append_all(quote! {
|
AttrType::BumpText(value) => tokens.append_all(quote! {
|
||||||
__cx.attr(#name, format_args_f!(#value), #namespace)
|
dioxus_elements::#el_name.#nameident(__cx, format_args_f!(#value))
|
||||||
}),
|
}),
|
||||||
|
// __cx.attr(#name, format_args_f!(#value), #namespace, false)
|
||||||
|
//
|
||||||
|
// AttrType::BumpText(value) => tokens.append_all(quote! {
|
||||||
|
// __cx.attr(#name, format_args_f!(#value), #namespace, false)
|
||||||
|
// }),
|
||||||
AttrType::FieldTokens(exp) => tokens.append_all(quote! {
|
AttrType::FieldTokens(exp) => tokens.append_all(quote! {
|
||||||
__cx.attr(#name, #exp, #namespace)
|
dioxus_elements::#el_name.#nameident(__cx, #exp)
|
||||||
}),
|
}),
|
||||||
|
// __cx.attr(#name_str, #exp, #namespace, false)
|
||||||
|
|
||||||
|
// AttrType::FieldTokens(exp) => tokens.append_all(quote! {
|
||||||
|
// dioxus_elements::#el_name.#nameident(__cx, format_args_f!(#value))
|
||||||
|
// __cx.attr(#name_str, #exp, #namespace, false)
|
||||||
|
// }),
|
||||||
|
|
||||||
// todo: move event handlers on to the elements or onto the nodefactory
|
// todo: move event handlers on to the elements or onto the nodefactory
|
||||||
AttrType::Event(event) => tokens.append_all(quote! {
|
AttrType::Event(event) => tokens.append_all(quote! {
|
||||||
|
|||||||
@@ -97,12 +97,16 @@ impl ToTokens for RsxRender {
|
|||||||
// The `in cx` pattern allows directly rendering
|
// The `in cx` pattern allows directly rendering
|
||||||
Some(ident) => out_tokens.append_all(quote! {
|
Some(ident) => out_tokens.append_all(quote! {
|
||||||
#ident.render(dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory|{
|
#ident.render(dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory|{
|
||||||
|
use dioxus_elements::GlobalAttributes;
|
||||||
|
|
||||||
#inner
|
#inner
|
||||||
}))
|
}))
|
||||||
}),
|
}),
|
||||||
// Otherwise we just build the LazyNode wrapper
|
// Otherwise we just build the LazyNode wrapper
|
||||||
None => out_tokens.append_all(quote! {
|
None => out_tokens.append_all(quote! {
|
||||||
dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory|{
|
dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory|{
|
||||||
|
use dioxus_elements::GlobalAttributes;
|
||||||
|
|
||||||
#inner
|
#inner
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -46,9 +46,14 @@ pub struct VFragment<'src> {
|
|||||||
pub trait DioxusElement {
|
pub trait DioxusElement {
|
||||||
const TAG_NAME: &'static str;
|
const TAG_NAME: &'static str;
|
||||||
const NAME_SPACE: Option<&'static str>;
|
const NAME_SPACE: Option<&'static str>;
|
||||||
|
#[inline]
|
||||||
fn tag_name(&self) -> &'static str {
|
fn tag_name(&self) -> &'static str {
|
||||||
Self::TAG_NAME
|
Self::TAG_NAME
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
|
fn namespace(&self) -> Option<&'static str> {
|
||||||
|
Self::NAME_SPACE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub struct VElement<'a> {
|
pub struct VElement<'a> {
|
||||||
// tag is always static
|
// tag is always static
|
||||||
@@ -172,10 +177,33 @@ impl<'a> NodeFactory<'a> {
|
|||||||
listeners: &[Listener],
|
listeners: &[Listener],
|
||||||
attributes: &[Attribute],
|
attributes: &[Attribute],
|
||||||
children: &'a [VNode<'a>],
|
children: &'a [VNode<'a>],
|
||||||
) {
|
) -> VNode<'a> {
|
||||||
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn element() {}
|
pub fn element(
|
||||||
|
&self,
|
||||||
|
el: impl DioxusElement,
|
||||||
|
listeners: &'a [Listener<'a>],
|
||||||
|
attributes: &'a [Attribute<'a>],
|
||||||
|
children: &'a [VNode<'a>],
|
||||||
|
key: Option<&'a str>,
|
||||||
|
) -> VNode<'a> {
|
||||||
|
VNode {
|
||||||
|
dom_id: RealDomNode::empty_cell(),
|
||||||
|
key,
|
||||||
|
kind: VNodeKind::Element(self.bump().alloc(VElement {
|
||||||
|
tag_name: el.tag_name(),
|
||||||
|
namespace: el.namespace(),
|
||||||
|
static_listeners: false,
|
||||||
|
listeners,
|
||||||
|
static_attrs: false,
|
||||||
|
attributes,
|
||||||
|
static_children: false,
|
||||||
|
children,
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn suspended() -> VNode<'static> {
|
pub fn suspended() -> VNode<'static> {
|
||||||
VNode {
|
VNode {
|
||||||
@@ -202,7 +230,7 @@ impl<'a> NodeFactory<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn virtual_child<P, C>(
|
pub fn virtual_child<P>(
|
||||||
&self,
|
&self,
|
||||||
component: FC<P>,
|
component: FC<P>,
|
||||||
props: P,
|
props: P,
|
||||||
|
|||||||
+240
-56
@@ -19,48 +19,213 @@ use std::fmt::Arguments;
|
|||||||
|
|
||||||
use dioxus_core::{nodes::Attribute, DioxusElement, NodeFactory};
|
use dioxus_core::{nodes::Attribute, DioxusElement, NodeFactory};
|
||||||
|
|
||||||
trait GlobalAttributes {
|
macro_rules! no_namespace_trait_methods {
|
||||||
fn accesskey<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
|
(
|
||||||
cx.attr("accesskey", val, None, false)
|
$(
|
||||||
|
$(#[$attr:meta])*
|
||||||
|
$name:ident;
|
||||||
|
)*
|
||||||
|
) => {
|
||||||
|
$(
|
||||||
|
$(#[$attr])*
|
||||||
|
fn $name<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
|
||||||
|
cx.attr(stringify!(name), val, None, false)
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
macro_rules! style_trait_methods {
|
||||||
|
(
|
||||||
|
$(
|
||||||
|
$(#[$attr:meta])*
|
||||||
|
$name:ident: $lit:literal,
|
||||||
|
)*
|
||||||
|
) => {
|
||||||
|
$(
|
||||||
|
$(#[$attr])*
|
||||||
|
fn $name<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
|
||||||
|
cx.attr($lit, val, Some("style"), false)
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
macro_rules! aria_trait_methods {
|
||||||
|
(
|
||||||
|
$(
|
||||||
|
$(#[$attr:meta])*
|
||||||
|
$name:ident: $lit:literal,
|
||||||
|
)*
|
||||||
|
) => {
|
||||||
|
$(
|
||||||
|
$(#[$attr])*
|
||||||
|
fn $name<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
|
||||||
|
cx.attr($lit, val, None, false)
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait GlobalAttributes {
|
||||||
|
no_namespace_trait_methods! {
|
||||||
|
accesskey;
|
||||||
|
class;
|
||||||
|
contenteditable;
|
||||||
|
data;
|
||||||
|
dir;
|
||||||
|
draggable;
|
||||||
|
hidden;
|
||||||
|
id;
|
||||||
|
lang;
|
||||||
|
spellcheck;
|
||||||
|
style;
|
||||||
|
tabindex;
|
||||||
|
title;
|
||||||
|
translate;
|
||||||
}
|
}
|
||||||
fn class<'a>(&self, cx: NodeFactory<'a>, val: Arguments<'a>) -> Attribute<'a> {
|
style_trait_methods! {
|
||||||
cx.attr("class", val, None, false)
|
background: "background",
|
||||||
|
background_attachment: "background-attachment",
|
||||||
|
|
||||||
|
/// ## Definition and Usage
|
||||||
|
///
|
||||||
|
/// The background-color property sets the background color of an element.
|
||||||
|
///
|
||||||
|
/// The background of an element is the total size of the element, including padding and border (but not the margin).
|
||||||
|
///
|
||||||
|
/// Tip: Use a background color and a text color that makes the text easy to read.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// body {
|
||||||
|
/// style: {
|
||||||
|
/// background_color: "coral"
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
background_color: "background-color",
|
||||||
|
background_image: "background-image",
|
||||||
|
background_position: "background-position",
|
||||||
|
background_repeat: "background-repeat",
|
||||||
|
border: "border",
|
||||||
|
border_bottom: "border-bottom",
|
||||||
|
border_bottom_color: "border-bottom-color",
|
||||||
|
border_bottom_style: "border-bottom-style",
|
||||||
|
border_bottom_width: "border-bottom-width",
|
||||||
|
border_color: "border-color",
|
||||||
|
border_left: "border-left",
|
||||||
|
border_left_color: "border-left-color",
|
||||||
|
border_left_style: "border-left-style",
|
||||||
|
border_left_width: "border-left-width",
|
||||||
|
border_right: "border-right",
|
||||||
|
border_right_color: "border-right-color",
|
||||||
|
border_right_style: "border-right-style",
|
||||||
|
border_right_width: "border-right-width",
|
||||||
|
border_style: "border-style",
|
||||||
|
border_top: "border-top",
|
||||||
|
border_top_color: "border-top-color",
|
||||||
|
border_top_style: "border-top-style",
|
||||||
|
border_top_width: "border-top-width",
|
||||||
|
border_width: "border-width",
|
||||||
|
clear: "clear",
|
||||||
|
clip: "clip",
|
||||||
|
color: "color",
|
||||||
|
cursor: "cursor",
|
||||||
|
display: "display",
|
||||||
|
filter: "filter",
|
||||||
|
css_float: "css-float",
|
||||||
|
font: "font",
|
||||||
|
font_family: "font-family",
|
||||||
|
font_size: "font-size",
|
||||||
|
font_variant: "font-variant",
|
||||||
|
font_weight: "font-weight",
|
||||||
|
height: "height",
|
||||||
|
left: "left",
|
||||||
|
letter_spacing: "letter-spacing",
|
||||||
|
line_height: "line-height",
|
||||||
|
list_style: "list-style",
|
||||||
|
list_style_image: "list-style-image",
|
||||||
|
list_style_position: "list-style-position",
|
||||||
|
list_style_type: "list-style-type",
|
||||||
|
margin: "margin",
|
||||||
|
margin_bottom: "margin-bottom",
|
||||||
|
margin_left: "margin-left",
|
||||||
|
margin_right: "margin-right",
|
||||||
|
margin_top: "margin-top",
|
||||||
|
overflow: "overflow",
|
||||||
|
padding: "padding",
|
||||||
|
padding_bottom: "padding-bottom",
|
||||||
|
padding_left: "padding-left",
|
||||||
|
padding_right: "padding-right",
|
||||||
|
padding_top: "padding-top",
|
||||||
|
page_break_after: "page-break-after",
|
||||||
|
page_break_before: "page-break-before",
|
||||||
|
position: "position",
|
||||||
|
stroke_dasharray: "stroke-dasharray",
|
||||||
|
stroke_dashoffset: "stroke-dashoffset",
|
||||||
|
text_align: "text-align",
|
||||||
|
text_decoration: "text-decoration",
|
||||||
|
text_indent: "text-indent",
|
||||||
|
text_transform: "text-transform",
|
||||||
|
top: "top",
|
||||||
|
vertical_align: "vertical-align",
|
||||||
|
visibility: "visibility",
|
||||||
|
width: "width",
|
||||||
|
z_index: "z-index",
|
||||||
}
|
}
|
||||||
fn contenteditable<'a>(&self, cx: NodeFactory<'a>, val: Arguments<'a>) -> Attribute<'a> {
|
aria_trait_methods! {
|
||||||
cx.attr("contenteditable", val, None, false)
|
aria_current: "aria-current",
|
||||||
}
|
aria_details: "aria-details",
|
||||||
fn data<'a>(&self, cx: NodeFactory<'a>, val: Arguments<'a>) -> Attribute<'a> {
|
aria_disabled: "aria-disabled",
|
||||||
cx.attr("data", val, None, false)
|
aria_hidden: "aria-hidden",
|
||||||
}
|
aria_invalid: "aria-invalid",
|
||||||
fn dir<'a>(&self, cx: NodeFactory<'a>, val: Arguments<'a>) -> Attribute<'a> {
|
aria_keyshortcuts: "aria-keyshortcuts",
|
||||||
cx.attr("dir", val, None, false)
|
aria_label: "aria-label",
|
||||||
}
|
aria_roledescription: "aria-roledescription",
|
||||||
fn draggable<'a>(&self, cx: NodeFactory<'a>, val: Arguments<'a>) -> Attribute<'a> {
|
// Widget Attributes
|
||||||
cx.attr("draggable", val, None, false)
|
aria_autocomplete: "aria-autocomplete",
|
||||||
}
|
aria_checked: "aria-checked",
|
||||||
fn hidden<'a>(&self, cx: NodeFactory<'a>, val: Arguments<'a>) -> Attribute<'a> {
|
aria_expanded: "aria-expanded",
|
||||||
cx.attr("hidden", val, None, false)
|
aria_haspopup: "aria-haspopup",
|
||||||
}
|
aria_level: "aria-level",
|
||||||
fn id<'a>(&self, cx: NodeFactory<'a>, val: Arguments<'a>) -> Attribute<'a> {
|
aria_modal: "aria-modal",
|
||||||
cx.attr("id", val, None, false)
|
aria_multiline: "aria-multiline",
|
||||||
}
|
aria_multiselectable: "aria-multiselectable",
|
||||||
fn lang<'a>(&self, cx: NodeFactory<'a>, val: Arguments<'a>) -> Attribute<'a> {
|
aria_orientation: "aria-orientation",
|
||||||
cx.attr("lang", val, None, false)
|
aria_placeholder: "aria-placeholder",
|
||||||
}
|
aria_pressed: "aria-pressed",
|
||||||
fn spellcheck<'a>(&self, cx: NodeFactory<'a>, val: Arguments<'a>) -> Attribute<'a> {
|
aria_readonly: "aria-readonly",
|
||||||
cx.attr("spellcheck", val, None, false)
|
aria_required: "aria-required",
|
||||||
}
|
aria_selected: "aria-selected",
|
||||||
fn style<'a>(&self, cx: NodeFactory<'a>, val: Arguments<'a>) -> Attribute<'a> {
|
aria_sort: "aria-sort",
|
||||||
cx.attr("style", val, Some("style"), false)
|
aria_valuemax: "aria-valuemax",
|
||||||
}
|
aria_valuemin: "aria-valuemin",
|
||||||
fn tabindex<'a>(&self, cx: NodeFactory<'a>, val: Arguments<'a>) -> Attribute<'a> {
|
aria_valuenow: "aria-valuenow",
|
||||||
cx.attr("tabindex", val, None, false)
|
aria_valuetext: "aria-valuetext",
|
||||||
}
|
// Live Region Attributes
|
||||||
fn title<'a>(&self, cx: NodeFactory<'a>, val: Arguments<'a>) -> Attribute<'a> {
|
aria_atomic: "aria-atomic",
|
||||||
cx.attr("title", val, None, false)
|
aria_busy: "aria-busy",
|
||||||
}
|
aria_live: "aria-live",
|
||||||
fn translate<'a>(&self, cx: NodeFactory<'a>, val: Arguments<'a>) -> Attribute<'a> {
|
aria_relevant: "aria-relevant",
|
||||||
cx.attr("translate", val, None, false)
|
|
||||||
|
aria_dropeffect: "aria-dropeffect",
|
||||||
|
aria_grabbed: "aria-grabbed",
|
||||||
|
// Relationship Attributes
|
||||||
|
aria_activedescendant: "aria-activedescendant",
|
||||||
|
aria_colcount: "aria-colcount",
|
||||||
|
aria_colindex: "aria-colindex",
|
||||||
|
aria_colspan: "aria-colspan",
|
||||||
|
aria_controls: "aria-controls",
|
||||||
|
aria_describedby: "aria-describedby",
|
||||||
|
aria_errormessage: "aria-errormessage",
|
||||||
|
aria_flowto: "aria-flowto",
|
||||||
|
aria_labelledby: "aria-labelledby",
|
||||||
|
aria_owns: "aria-owns",
|
||||||
|
aria_posinset: "aria-posinset",
|
||||||
|
aria_rowcount: "aria-rowcount",
|
||||||
|
aria_rowindex: "aria-rowindex",
|
||||||
|
aria_rowspan: "aria-rowspan",
|
||||||
|
aria_setsize: "aria-setsize",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +252,7 @@ macro_rules! builder_constructors {
|
|||||||
|
|
||||||
impl $name {
|
impl $name {
|
||||||
$(
|
$(
|
||||||
pub fn $fil<'a>(&self, cx: NodeFactory<'a>, val: Arguments<'a>) -> Attribute<'a> {
|
pub fn $fil<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
|
||||||
cx.attr(stringify!($fil), val, None, false)
|
cx.attr(stringify!($fil), val, None, false)
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
@@ -149,7 +314,7 @@ builder_constructors! {
|
|||||||
rel: LinkType,
|
rel: LinkType,
|
||||||
sizes: String, // FIXME
|
sizes: String, // FIXME
|
||||||
title: String, // FIXME
|
title: String, // FIXME
|
||||||
// type: Mime,
|
r#type: Mime,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Build a
|
/// Build a
|
||||||
@@ -166,7 +331,7 @@ builder_constructors! {
|
|||||||
/// [`<style>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style)
|
/// [`<style>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style)
|
||||||
/// element.
|
/// element.
|
||||||
style {
|
style {
|
||||||
// type: Mime,
|
r#type: Mime,
|
||||||
media: String, // FIXME media query
|
media: String, // FIXME media query
|
||||||
nonce: Nonce,
|
nonce: Nonce,
|
||||||
title: String, // FIXME
|
title: String, // FIXME
|
||||||
@@ -307,6 +472,25 @@ builder_constructors! {
|
|||||||
/// Build a
|
/// Build a
|
||||||
/// [`<div>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div)
|
/// [`<div>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div)
|
||||||
/// element.
|
/// element.
|
||||||
|
///
|
||||||
|
/// ## Definition and Usage
|
||||||
|
/// - The <div> tag defines a division or a section in an HTML document.
|
||||||
|
/// - The <div> tag is used as a container for HTML elements - which is then styled with CSS or manipulated with JavaScript.
|
||||||
|
/// - The <div> tag is easily styled by using the class or id attribute.
|
||||||
|
/// - Any sort of content can be put inside the <div> tag!
|
||||||
|
///
|
||||||
|
/// Note: By default, browsers always place a line break before and after the <div> element.
|
||||||
|
///
|
||||||
|
/// ## Usage
|
||||||
|
/// ```
|
||||||
|
/// html!(<div> A header element </div>)
|
||||||
|
/// rsx!(div { "A header element" })
|
||||||
|
/// LazyNodes::new(|f| f.element(div, &[], &[], &[], None))
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## References:
|
||||||
|
/// - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div
|
||||||
|
/// - https://www.w3schools.com/tags/tag_div.asp
|
||||||
div {};
|
div {};
|
||||||
|
|
||||||
/// Build a
|
/// Build a
|
||||||
@@ -347,7 +531,7 @@ builder_constructors! {
|
|||||||
ol {
|
ol {
|
||||||
reversed: Bool,
|
reversed: Bool,
|
||||||
start: isize,
|
start: isize,
|
||||||
// type: OrderedListType,
|
r#type: OrderedListType,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Build a
|
/// Build a
|
||||||
@@ -376,7 +560,7 @@ builder_constructors! {
|
|||||||
href: Uri,
|
href: Uri,
|
||||||
hreflang: LanguageTag,
|
hreflang: LanguageTag,
|
||||||
target: Target,
|
target: Target,
|
||||||
// type: Mime,
|
r#type: Mime,
|
||||||
// ping: SpacedList<Uri>,
|
// ping: SpacedList<Uri>,
|
||||||
// rel: SpacedList<LinkType>,
|
// rel: SpacedList<LinkType>,
|
||||||
};
|
};
|
||||||
@@ -553,10 +737,10 @@ builder_constructors! {
|
|||||||
autoplay: Bool,
|
autoplay: Bool,
|
||||||
controls: Bool,
|
controls: Bool,
|
||||||
crossorigin: CrossOrigin,
|
crossorigin: CrossOrigin,
|
||||||
// loop: Bool,
|
|
||||||
muted: Bool,
|
muted: Bool,
|
||||||
preload: Preload,
|
preload: Preload,
|
||||||
src: Uri,
|
src: Uri,
|
||||||
|
r#loop: Bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Build a
|
/// Build a
|
||||||
@@ -601,7 +785,7 @@ builder_constructors! {
|
|||||||
controls: Bool,
|
controls: Bool,
|
||||||
crossorigin: CrossOrigin,
|
crossorigin: CrossOrigin,
|
||||||
height: usize,
|
height: usize,
|
||||||
// loop: Bool,
|
r#loop: Bool,
|
||||||
muted: Bool,
|
muted: Bool,
|
||||||
preload: Preload,
|
preload: Preload,
|
||||||
playsinline: Bool,
|
playsinline: Bool,
|
||||||
@@ -619,7 +803,7 @@ builder_constructors! {
|
|||||||
embed {
|
embed {
|
||||||
height: usize,
|
height: usize,
|
||||||
src: Uri,
|
src: Uri,
|
||||||
// type: Mime,
|
r#type: Mime,
|
||||||
width: usize,
|
width: usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -647,7 +831,7 @@ builder_constructors! {
|
|||||||
form: Id,
|
form: Id,
|
||||||
height: usize,
|
height: usize,
|
||||||
name: Id,
|
name: Id,
|
||||||
// type: Mime,
|
r#type: Mime,
|
||||||
typemustmatch: Bool,
|
typemustmatch: Bool,
|
||||||
usemap: String, // TODO should be a fragment starting with '#'
|
usemap: String, // TODO should be a fragment starting with '#'
|
||||||
width: usize,
|
width: usize,
|
||||||
@@ -671,7 +855,7 @@ builder_constructors! {
|
|||||||
/// element.
|
/// element.
|
||||||
source {
|
source {
|
||||||
src: Uri,
|
src: Uri,
|
||||||
// type: Mime,
|
r#type: Mime,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -701,8 +885,8 @@ builder_constructors! {
|
|||||||
nonce: Nonce,
|
nonce: Nonce,
|
||||||
src: Uri,
|
src: Uri,
|
||||||
text: String,
|
text: String,
|
||||||
// async: Bool,
|
r#async: Bool,
|
||||||
// type: String, // TODO could be an enum
|
r#type: String, // TODO could be an enum
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -807,7 +991,7 @@ builder_constructors! {
|
|||||||
formnovalidate: Bool,
|
formnovalidate: Bool,
|
||||||
formtarget: Target,
|
formtarget: Target,
|
||||||
name: Id,
|
name: Id,
|
||||||
// type: ButtonType,
|
r#type: ButtonType,
|
||||||
value: String,
|
value: String,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -869,7 +1053,7 @@ builder_constructors! {
|
|||||||
src: Uri,
|
src: Uri,
|
||||||
step: String,
|
step: String,
|
||||||
tabindex: usize,
|
tabindex: usize,
|
||||||
// type: InputType,
|
r#type: InputType,
|
||||||
value: String,
|
value: String,
|
||||||
width: isize,
|
width: isize,
|
||||||
};
|
};
|
||||||
@@ -878,7 +1062,7 @@ builder_constructors! {
|
|||||||
/// [`<label>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label)
|
/// [`<label>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label)
|
||||||
/// element.
|
/// element.
|
||||||
label {
|
label {
|
||||||
// for: Id,
|
r#for: Id,
|
||||||
form: Id,
|
form: Id,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -924,7 +1108,7 @@ builder_constructors! {
|
|||||||
output {
|
output {
|
||||||
form: Id,
|
form: Id,
|
||||||
name: Id,
|
name: Id,
|
||||||
// for: SpacedSet<Id>,
|
// r#for: SpacedSet<Id>,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Build a
|
/// Build a
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ mod tests {
|
|||||||
use dioxus_core as dioxus;
|
use dioxus_core as dioxus;
|
||||||
use dioxus_core::prelude::*;
|
use dioxus_core::prelude::*;
|
||||||
use dioxus_html as dioxus_elements;
|
use dioxus_html as dioxus_elements;
|
||||||
|
use dioxus_html::GlobalAttributes;
|
||||||
|
|
||||||
const SIMPLE_APP: FC<()> = |cx| {
|
const SIMPLE_APP: FC<()> = |cx| {
|
||||||
cx.render(rsx!(div {
|
cx.render(rsx!(div {
|
||||||
|
|||||||
@@ -21,4 +21,5 @@ mod dioxus_elements {
|
|||||||
const TAG_NAME: &'static str = "div";
|
const TAG_NAME: &'static str = "div";
|
||||||
const NAME_SPACE: Option<&'static str> = None;
|
const NAME_SPACE: Option<&'static str> = None;
|
||||||
}
|
}
|
||||||
|
pub trait GlobalAttributes {}
|
||||||
}
|
}
|
||||||
@@ -188,6 +188,7 @@ pub use dioxus_webview as desktop;
|
|||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
//! A glob import that includes helper types like FC, rsx!, html!, and required traits
|
//! A glob import that includes helper types like FC, rsx!, html!, and required traits
|
||||||
pub use dioxus_core::prelude::*;
|
pub use dioxus_core::prelude::*;
|
||||||
|
pub use dioxus_elements::GlobalAttributes;
|
||||||
pub use dioxus_hooks::*;
|
pub use dioxus_hooks::*;
|
||||||
pub use dioxus_html as dioxus_elements;
|
pub use dioxus_html as dioxus_elements;
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user