Skip to content

nayandas69/iced-markup

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

iced-markup

A declarative markup DSL for building Iced GUI applications in Rust.

Write concise, JSX-inspired syntax inside the view! macro and get idiomatic Iced widget code at compile time with zero runtime overhead.

Important

This is a pre-release (v0.1.0). It's stable enough to use, but expect syntax shifts. ⚠️ This crate is experimental. APIs may change and features are incomplete.

Check out the official guide

The Idea

Iced is great, but building layout-heavy UIs with 50 levels of .push() is a nightmare to read. iced-markup is a procedural macro that takes a JSX-like syntax and expands it into standard, zero-cost Iced code at compile time.

Installation

To use the markup macro in your project, add it via cargo:

cargo add iced-markup

Or add it manually to your Cargo.toml:

[dependencies]
iced-markup = "0.1.0"
iced = "0.13"

The Markup Pattern

Everything follows a predictable shape: widget_name(constructor_args) ![attributes] | style { children }

Part What it does
name The Iced widget (column, text, etc)
(...) Optional creation arguments
![...] Method calls (spacing, padding, +events)
| ... The styling pipe
{...} Nested children (for layout widgets)

Real code looks like this:

use iced_markup::view;
use iced::widget::{Column, Theme, Renderer};

fn ui() -> Column<'static, Message, Theme, Renderer> {
    view! {
        column ![spacing: 20] {
            text("Hello world") {},
            button("Click") ![+click: Message::DoSomething] {},
        }
    }
}

How the nesting works

You can nest widgets infinitely. If a widget supports .push(), you put its children inside {}.

view! {
    scrollable {
        column ![spacing: 10] {
            row ![spacing: 5] {
                text("Left") {},
                text("Right") {},
            },
            text("Bottom") {}
        }
    }
}

Control Flow & Logic

You don't need macros or .map() for lists. Use standard Rust syntax inside the curly braces.

view! {
    column {
        if user.is_admin {
            text("Admin Zone") | |_| text::primary {}
        },
        for i in 1..=5 {
            text(format!("Item {}", i)) {}
        }
    }
}

Event Shorthands

Tired of typing .on_input() or .on_press()? Use the + prefix in attributes.

  • +click -> on_press
  • +input -> on_input
  • +submit -> on_submit
button("Push me") ![+click: Msg::Trigger] {}

Parameters & Slots

If you need to set a special property using the @ syntax (like a scroll handler), do it inside the block:

scrollable {
    @on_scroll: Message::Scrolled
}

License

This project is licensed under the MIT License. See the LICENSE file for details.

About

A markup DSL for Iced GUI

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages