A responsive, draggable/resizable grid system for Rust, inspired by react-grid-layout. The spatial engine is deterministic headless Rust (hadrone-core); UI integrations cover Dioxus 0.7, Leptos, Yew, and vanilla JS via WebAssembly.
- Shared engine: Compaction, collision handling, pointer/session math, and optional validation live in
hadrone-core(no DOM types in core). - Framework crates:
hadrone-dioxus,hadrone-leptos,hadrone-yewwith aligned drag/resize behavior; Dioxus also exposes structuredLayoutEventlifecycle hooks (on_layout_event,emit_interaction_updates). - Compaction:
CompactionType::Gravity(vertical “rising tide”) andFreePlacement. - Collisions: Pluggable
CollisionStrategy(PushDowndefault,Noneto skip displacement until compaction). - Layout model:
LayoutItemsupports min/max size, optional aspect ratio (width/height),is_static, and separateis_draggable/is_resizable(RGL-style). - Import/export:
validate_layout,repair_layout, and responsivescale_layout_cols/select_breakpointfor breakpoint changes. - Extras:
hadrone-extrasprovides storage adapters and responsive breakpoint helpers (e.g. web + Dioxus).
| Crate | Role |
|---|---|
hadrone-core |
Grid math, LayoutEngine, InteractionSession, validation, responsive helpers, LayoutEvent types |
hadrone-dioxus |
GridLayout / GridItem for Dioxus 0.7 |
hadrone-leptos |
GridLayout for Leptos |
hadrone-yew |
GridLayout for Yew |
hadrone-wasm |
JS bindings (GridEngineWasm) for vanilla front ends |
hadrone-extras |
Persistence (LayoutStorage), BreakpointConfig, debounced save |
packages/ui |
Shared dashboard CSS and UI helpers used by web/desktop |
cargo run -p dioxus-dashboard # desktop dashboard example
dx serve --package packages/web # web Grid Engine Debugger
dx serve --package packages/desktop # desktop shell with file-backed layoutcargo run --example leptos-dashboardcargo run --example yew-dashboardBuild bindings into examples/vanilla-js/pkg/, then serve only examples/vanilla-js (see examples/vanilla-js/README.md):
cargo run -p vanilla-js-runner # wasm-pack build + prints serve instructions
cd examples/vanilla-js && python3 -m http.server 8083Open http://localhost:8083.
GridLayout requires margin, compaction, and render_item (other props have defaults such as container_padding, collision_strategy).
use dioxus::prelude::*;
use hadrone_core::{CompactionType, LayoutItem};
use hadrone_dioxus::GridLayout;
#[component]
fn Dashboard() -> Element {
let mut layout = use_signal(|| vec![
LayoutItem { id: "1".into(), x: 0, y: 0, w: 4, h: 2, ..Default::default() },
]);
rsx! {
GridLayout {
layout,
cols: 12,
row_height: 100.0,
margin: (10, 10),
compaction: CompactionType::Gravity,
render_item: |item: LayoutItem| rsx! {
div { class: "widget", "Widget {item.id}" }
},
}
}
}use hadrone_core::CompactionType;
use hadrone_leptos::GridLayout;
use leptos::*;
#[component]
fn Dashboard() -> impl IntoView {
let layout = create_rw_signal(vec![]);
view! {
<GridLayout
layout=layout
cols=12.into()
row_height=100.0.into()
margin=(10, 10).into()
compaction=CompactionType::Gravity.into()
render_item=move |item| view! { <div class="widget">"Widget " {item.id}</div> }
/>
}
}During drag/resize, the core InteractionSession tracks sub-pixel movement and snaps grid updates from deltas, so the live element can stay smooth while the committed layout stays grid-aligned. container_padding on the session matches CSS padding on the grid container when you need pixel-aligned overlays.
MIT / Apache-2.0