Skip to content
5 changes: 1 addition & 4 deletions examples/rsx_usage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,7 @@ fn WithInline(text: String) -> Element {
}

#[component]
fn Label<T: Clone + PartialEq + 'static>(text: T) -> Element
where
T: Display,
{
fn Label<T: Clone + PartialEq + Display + 'static>(text: T) -> Element {
rsx! {
p { "{text}" }
}
Expand Down
6 changes: 5 additions & 1 deletion packages/autofmt/src/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ impl Writer<'_> {
..
} = el;

let brace = brace
.as_ref()
.expect("braces should always be present in strict mode");

/*
1. Write the tag
2. Write the key
Expand Down Expand Up @@ -426,7 +430,7 @@ impl Writer<'_> {
}
}

fn get_expr_length(expr: &Expr) -> Option<usize> {
fn get_expr_length(expr: &impl Spanned) -> Option<usize> {
let span = expr.span();
let (start, end) = (span.start(), span.end());
if start.line == end.line {
Expand Down
8 changes: 4 additions & 4 deletions packages/autofmt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use collect_macros::byte_offset;
use dioxus_rsx::{BodyNode, CallBody, IfmtInput};
use proc_macro2::LineColumn;
use quote::ToTokens;
use syn::{ExprMacro, MacroDelimiter};
use syn::{parse::Parser, ExprMacro, MacroDelimiter};

mod buffer;
mod collect_macros;
Expand Down Expand Up @@ -77,7 +77,7 @@ pub fn fmt_file(contents: &str, indent: IndentOptions) -> Vec<FormattedBlock> {
continue;
}

let body = item.parse_body::<CallBody>().unwrap();
let body = item.parse_body_with(CallBody::parse_strict).unwrap();

let rsx_start = macro_path.span().start();

Expand Down Expand Up @@ -153,7 +153,7 @@ fn write_body(buf: &mut Writer, body: &CallBody) {
}

pub fn fmt_block_from_expr(raw: &str, expr: ExprMacro) -> Option<String> {
let body = syn::parse2::<CallBody>(expr.mac.tokens).unwrap();
let body = CallBody::parse_strict.parse2(expr.mac.tokens).unwrap();

let mut buf = Writer::new(raw);

Expand All @@ -163,7 +163,7 @@ pub fn fmt_block_from_expr(raw: &str, expr: ExprMacro) -> Option<String> {
}

pub fn fmt_block(block: &str, indent_level: usize, indent: IndentOptions) -> Option<String> {
let body = syn::parse_str::<dioxus_rsx::CallBody>(block).unwrap();
let body = CallBody::parse_strict.parse_str(block).unwrap();

let mut buf = Writer::new(block);

Expand Down
29 changes: 29 additions & 0 deletions packages/core-macro/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,15 @@ impl ToTokens for ComponentBody {
}
};

let completion_hints = self.completion_hints();

tokens.append_all(quote! {
#props_struct

#[allow(non_snake_case)]
#comp_fn

#completion_hints
});
}
}
Expand Down Expand Up @@ -221,6 +225,31 @@ impl ComponentBody {

false
}

// We generate an extra enum to help us autocomplete the braces after the component.
// This is a bit of a hack, but it's the only way to get the braces to autocomplete.
fn completion_hints(&self) -> TokenStream {
let comp_fn = &self.item_fn.sig.ident;
let completions_mod = Ident::new(&format!("{}_completions", comp_fn), comp_fn.span());

let vis = &self.item_fn.vis;

quote! {
#[allow(non_snake_case)]
#[doc(hidden)]
mod #completions_mod {
#[doc(hidden)]
#[allow(non_camel_case_types)]
/// This enum is generated to help autocomplete the braces after the component. It does nothing
pub enum Component {
#comp_fn {}
}
}

#[allow(unused)]
#vis use #completions_mod::Component::#comp_fn;
}
}
}

struct DocField<'a> {
Expand Down
2 changes: 1 addition & 1 deletion packages/dioxus-lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub mod prelude {
pub use dioxus_html as dioxus_elements;

#[cfg(feature = "html")]
pub use dioxus_elements::{prelude::*, GlobalAttributes, SvgAttributes};
pub use dioxus_elements::{global_attributes, prelude::*, svg_attributes};

pub use dioxus_core;
}
2 changes: 1 addition & 1 deletion packages/dioxus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub mod prelude {

#[cfg(feature = "html")]
#[cfg_attr(docsrs, doc(cfg(feature = "html")))]
pub use dioxus_elements::{prelude::*, GlobalAttributes, SvgAttributes};
pub use dioxus_elements::{global_attributes, prelude::*, svg_attributes};

#[cfg(all(
not(any(target_arch = "wasm32", target_os = "ios", target_os = "android")),
Expand Down
22 changes: 2 additions & 20 deletions packages/html-internal-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ pub fn impl_extension_attributes(input: TokenStream) -> TokenStream {
}

struct ImplExtensionAttributes {
is_element: bool,
name: Ident,
attrs: Punctuated<Ident, Token![,]>,
}
Expand All @@ -23,16 +22,11 @@ impl Parse for ImplExtensionAttributes {
fn parse(input: ParseStream) -> syn::Result<Self> {
let content;

let element: Ident = input.parse()?;
let name = input.parse()?;
braced!(content in input);
let attrs = content.parse_terminated(Ident::parse, Token![,])?;

Ok(ImplExtensionAttributes {
is_element: element == "ELEMENT",
name,
attrs,
})
Ok(ImplExtensionAttributes { name, attrs })
}
}

Expand All @@ -44,22 +38,10 @@ impl ToTokens for ImplExtensionAttributes {
.strip_prefix("r#")
.unwrap_or(&name_string)
.to_case(Case::UpperCamel);
let impl_name = Ident::new(format!("{}Impl", &camel_name).as_str(), name.span());
let extension_name = Ident::new(format!("{}Extension", &camel_name).as_str(), name.span());

if !self.is_element {
tokens.append_all(quote! {
struct #impl_name;
impl #name for #impl_name {}
});
}

let impls = self.attrs.iter().map(|ident| {
let d = if self.is_element {
quote! { #name::#ident }
} else {
quote! { <#impl_name as #name>::#ident }
};
let d = quote! { #name::#ident };
quote! {
fn #ident(self, value: impl IntoAttributeValue) -> Self {
let d = #d;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use dioxus_html_internal_macro::impl_extension_attributes;
use crate::AttributeDiscription;

#[cfg(feature = "hot-reload-context")]
macro_rules! trait_method_mapping {
macro_rules! mod_method_mapping {
(
$matching:ident;
$(#[$attr:meta])*
Expand Down Expand Up @@ -68,30 +68,31 @@ macro_rules! html_to_rsx_attribute_mapping {
};
}

macro_rules! trait_methods {
macro_rules! mod_methods {
(
@base
$(#[$trait_attr:meta])*
$trait:ident;
$(#[$mod_attr:meta])*
$mod:ident;
$fn:ident;
$fn_html_to_rsx:ident;
$(
$(#[$attr:meta])*
$name:ident $(: $($arg:literal),*)*;
)+
) => {
$(#[$trait_attr])*
pub trait $trait {
$(#[$mod_attr])*
pub mod $mod {
use super::*;
$(
$(#[$attr])*
const $name: AttributeDiscription = trait_methods! { $name $(: $($arg),*)*; };
pub const $name: AttributeDiscription = mod_methods! { $name $(: $($arg),*)*; };
)*
}

#[cfg(feature = "hot-reload-context")]
pub(crate) fn $fn(attr: &str) -> Option<(&'static str, Option<&'static str>)> {
$(
trait_method_mapping! {
mod_method_mapping! {
attr;
$name$(: $($arg),*)*;
}
Expand All @@ -111,7 +112,7 @@ macro_rules! trait_methods {
None
}

impl_extension_attributes![GLOBAL $trait { $($name,)* }];
impl_extension_attributes![$mod { $($name,)* }];
};

// Rename the incoming ident and apply a custom namespace
Expand All @@ -124,10 +125,10 @@ macro_rules! trait_methods {
( $name:ident; ) => { (stringify!($name), None, false) };
}

trait_methods! {
mod_methods! {
@base

GlobalAttributes;
global_attributes;
map_global_attributes;
map_html_global_attributes_to_rsx;

Expand Down Expand Up @@ -1640,9 +1641,9 @@ trait_methods! {
aria_setsize: "aria-setsize";
}

trait_methods! {
mod_methods! {
@base
SvgAttributes;
svg_attributes;
map_svg_attributes;
map_html_svg_attributes_to_rsx;

Expand Down
41 changes: 26 additions & 15 deletions packages/html/src/elements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use dioxus_rsx::HotReloadingContext;

#[cfg(feature = "hot-reload-context")]
use crate::{map_global_attributes, map_svg_attributes};
use crate::{GlobalAttributes, SvgAttributes};

pub type AttributeDiscription = (&'static str, Option<&'static str>, bool);

Expand Down Expand Up @@ -115,9 +114,11 @@ macro_rules! impl_element {
) => {
#[allow(non_camel_case_types)]
$(#[$attr])*
pub struct $name;
pub mod $name {
#[allow(unused)]
use super::*;
pub use crate::attribute_groups::global_attributes::*;

impl $name {
pub const TAG_NAME: &'static str = stringify!($name);
pub const NAME_SPACE: Option<&'static str> = None;

Expand All @@ -128,8 +129,6 @@ macro_rules! impl_element {
);
)*
}

impl GlobalAttributes for $name {}
};

(
Expand All @@ -141,13 +140,12 @@ macro_rules! impl_element {
)*
}
) => {
#[allow(non_camel_case_types)]
$(#[$attr])*
pub struct $name;

impl SvgAttributes for $name {}
pub mod $name {
#[allow(unused)]
use super::*;
pub use crate::attribute_groups::svg_attributes::*;

impl $name {
pub const TAG_NAME: &'static str = stringify!($name);
pub const NAME_SPACE: Option<&'static str> = Some($namespace);

Expand All @@ -171,11 +169,11 @@ macro_rules! impl_element {
) => {
#[allow(non_camel_case_types)]
$(#[$attr])*
pub struct $element;

impl SvgAttributes for $element {}
pub mod $element {
#[allow(unused)]
use super::*;
pub use crate::attribute_groups::svg_attributes::*;

impl $element {
pub const TAG_NAME: &'static str = $name;
pub const NAME_SPACE: Option<&'static str> = Some($namespace);

Expand Down Expand Up @@ -384,10 +382,23 @@ macro_rules! builder_constructors {
);
)*

/// This module contains helpers for rust analyzer autocompletion
#[doc(hidden)]
pub mod completions {
/// This helper tells rust analyzer that it should autocomplete the element name with braces.
#[allow(non_camel_case_types)]
pub enum CompleteWithBraces {
$(
$(#[$attr])*
$name {}
),*
}
}

pub(crate) mod extensions {
use super::*;
$(
impl_extension_attributes![ELEMENT $name { $($fil,)* }];
impl_extension_attributes![$name { $($fil,)* }];
)*
}
};
Expand Down
Loading