Skip to main content

Crate maud_extensions

Crate maud_extensions 

Source
Expand description

Tiny Maud superpowers.

This crate is the public runtime/support surface:

  • reexports proc macros like css! and js!
  • optionally reexports the experimental Component derive
  • optionally reexports the experimental component impl macro
  • provides runtime slot wrapper types like Slot and Slots
  • reexports bon so generated component code can depend only on maud-extensions

Recommended dependency spelling:

[dependencies]
mx = { package = "maud-extensions", version = "0.6.2", features = ["components"] }

§Experimental components

The component system is currently opt-in behind the components feature. The macro that turns impl-local component rendering and asset blocks on is:

#[mx::component]
impl Card {
    render! { ... }
    css! { ... }
    js!(once, { ... });
}

That impl macro is what makes render!, css!, and js! part of the component render pipeline.

The preferred authoring pattern is:

  • #[derive(Component)] on the struct
  • Slot<maud::Markup> / Slot<Vec<maud::Markup>> for slot fields
  • #[mx(default)] on the single default slot
  • #[mx::component] on the inherent impl block
  • render! { ... } for the component root
  • optional colocated css! { ... } and js!(once, { ... }) blocks

The builder .render() path uses the hidden [ComponentRender] hook and currently auto-injects impl-local CSS and JS into the rendered root.

use maud::Markup;
use mx::{Component, Slot};

#[derive(Component)]
struct Card {
    title: String,
    header: Slot<Markup>,
    #[mx(default)]
    body: Slot<Markup>,
    footer: Slot<Markup>,
    #[mx(each = action)]
    actions: Slot<Vec<Markup>>,
}

#[mx::component]
impl Card {
    css! {
        me {
            padding: 1rem;
            border: 1px solid #ddd;
        }
    }

    js!(once, {
        me().class_add("ready");
    });

    render! {
        article.card {
            header class="header" { (self.header) }
            h2 { (self.title) }
            div.body { (self.body) }
            footer class="footer" { (self.footer) }
            div.actions { (self.actions) }
        }
    }
}

The broader browser-side runtime pieces this layers on top of today include:

Macros§

css
Emits a <style> tag or defines a named local CSS helper.
js
Emits a <script> tag or defines a named local JS helper.

Structs§

Slot
Typed slot storage for component fields.

Type Aliases§

Slots
Convenience alias for repeated markup-backed slot storage.

Attribute Macros§

component
Experimental component impl macro for colocated render/css/js blocks.

Derive Macros§

Component
Experimental opt-in derive for builder-centric Maud component authoring.