maud-extensions
Proc macros for Maud that make inline CSS/JS and component-style authoring simpler.
This crate includes bundled copies of gnat/surreal and gnat/css-scope-inline. Check those repos to see what these two tiny JS files can do and how to use them.
Why use it?
- Define component-local
js()andcss()helpers withjs!/css!. - Wrap markup with
component!and auto-inject JS/CSS helpers. - Emit direct
<script>/<style>blocks when needed. - Bundle
surreal.jsandcss-scope-inline.jswith zero path setup. - Embed fonts as base64
@font-faceCSS.
Table of Contents
- Install
- What's New in 0.3.x
- Quick Start
- component!
- Runtime Injection
- Macro Reference
- Font Helpers
- Migration Guide (0.2 -> 0.3)
- License
Install
What's New in 0.3.x
- New
component!macro for auto-injecting JS/CSS helpers into one root element. - Swapped JS/CSS macro naming so
js!/css!define local helpers andinline_js!/inline_css!emit direct tags. - Bundled runtime helper
surreal_scope_inline!()with no path setup. - Explicit compile-time shape checks for
component!input.
Quick Start
use ;
use ;
;
component!
component! wraps one top-level Maud element and appends the JS/CSS helpers
generated by js! and css! inside that root element automatically.
use ;
use ;
;
Equivalent output shape:
- root element content
- then
(js()) - then
(css())
Rules:
- input must be exactly one top-level element with a
{ ... }body js! { ... }andcss! { ... }must be present in scope (empty is valid:js! {}/css! {})- trailing
;is allowed - invalid root shapes fail at compile time with guidance
- if a helper is missing, the compiler error points at a required internal helper symbol;
add the corresponding
js! { ... }orcss! { ... }call
Runtime Injection
Use bundled runtime scripts with no filesystem setup:
use surreal_scope_inline;
html!
Need custom files instead? Use js_file! / css_file! (include_str! behavior):
use js_file;
html!
Macro Reference
js! { ... }/js!("...")- Generate local
fn js() -> maud::Markupand the hidden helper used bycomponent!.
- Generate local
css! { ... }/css!("...")- Generate local
fn css() -> maud::Markupand the hidden helper used bycomponent!.
- Generate local
component! { ... }- Wrap one root element and inject helpers emitted by
js!/css!at the end of its body.
- Wrap one root element and inject helpers emitted by
inline_js! { ... }/inline_js!("...")- Emit
<script>markup directly. - Validate JS via
swc_ecma_parser.
- Emit
inline_css! { ... }/inline_css!("...")- Emit
<style>markup directly. - Validate CSS via
cssparser.
- Emit
js_file!("path")/css_file!("path")- Emit
<script>/<style>tags from file contents.
- Emit
surreal_scope_inline!()- Emit bundled
surreal.jsandcss-scope-inline.js.
- Emit bundled
font_face!(...)/font_faces!(...)- Embed font files as base64
@font-faceCSS.
- Embed font files as base64
Font Helpers
font_face! and font_faces! embed font files as base64 data URLs. Because
this macro expands at the call site, the consuming crate must include base64
if you use these macros.
use font_face;
html!
Migration Guide (0.2 -> 0.3)
1. Rename JS/CSS macro usage
The JS/CSS macro names were intentionally swapped:
- old
js!-> newinline_js! - old
css!-> newinline_css! - old
inline_js!-> newjs! - old
inline_css!-> newcss!
2. Move to component! for root injection
Old pattern:
inline_js!
let view = html! ;
inline_css!
New pattern:
js!
let view = component! ;
css!
3. Keep runtime scripts explicit in layout/page shell
html!
4. Update assumptions in your codebase
component!requires exactly one top-level element with a body block.component!expectsjs!andcss!calls in scope (empty blocks are allowed).- defining
fn js()/fn css()manually is not enough; usejs!/css!socomponent!sees required helpers. font_face!/font_faces!still requirebase64in the consuming crate.js_file!/css_file!paths are resolved from the calling source file context.
License
MIT OR Apache-2.0