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
  • 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.7", features = ["components"] }

§Experimental components

The component system is currently opt-in behind the components feature. 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
  • reserve #[mx(default)] for slot selection only; use Rust Default or Option<T> for non-slot defaults
  • ordinary inherent helpers like fn css() -> Markup and fn js() -> Markup
  • ordinary impl Render with explicit (Self::css()) / (Self::js()) emission where desired
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>>,
}

impl Card {
    fn css() -> Markup {
        mx::css! {
            me {
                padding: 1rem;
                border: 1px solid #ddd;
            }
        }
    }

    fn js() -> Markup {
        mx::js!(once, {
            me().class_add("ready");
        })
    }
}

impl maud::Render for Card {
    fn render(&self) -> Markup {
        maud::html! {
            article.card {
                (Self::css())
                (Self::js())
                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:

To bootstrap those browser-side pieces in a page, use Init in <head>:

use maud::html;
use mx::Init;

fn page() -> maud::Markup {
    html! {
        head { (Init::all()) }
        body { /* page body */ }
    }
}

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.
signals_inline
Emits bundled Signals runtime and adapter.
surreal_scope_inline
Emits bundled Surreal and css-scope-inline runtimes.
surreal_scope_signals_inline
Emits the full runtime bundle: Surreal, css-scope-inline, Signals core, and adapter.

Structs§

Init
Page-level runtime bootstrap for bundled browser-side helpers.
Slot
Typed slot storage for component fields.

Type Aliases§

Slots
Convenience alias for repeated markup-backed slot storage.

Derive Macros§

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