Aspirational examples for app developer contract.

This commit is contained in:
2026-03-21 17:05:25 -04:00
parent d4ff472a14
commit f59d519448
8 changed files with 866 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
//! Aspirational RUIN app API for typed children, slots, and builder finalization.
//!
//! Intentionally non-compiling; this is a design sketch.
use ruin::prelude::*;
#[ruin_runtime::async_main]
async fn main() -> ruin::Result<()> {
App::new()
.window(Window::new().title("RUIN Children Contracts").size(1100.0, 760.0))
.mount::<ChildrenContractsExample>()
.run()
.await
}
#[component]
fn ChildrenContractsExample() -> impl View {
let projects = projects();
view! {
column(fill = true, gap = 20, padding = 24) {
text(role = TextRole::Heading(1), size = 30, weight = FontWeight::Semibold) {
"Typed children and slots"
}
text(color = colors::muted()) {
"This sketch focuses on declaration-side child contracts. The `view!` syntax stays \
uniform for all components, while the generated builder enforces props first and \
`children` as the finalizing step."
}
SplitLayout(sidebar = view! {
block(gap = 12, width = 280) {
text(role = TextRole::Heading(2), size = 22, weight = FontWeight::Semibold) {
"Filters"
}
FilterChip(selected = true) { "All projects" }
FilterChip(selected = false) { "Recent" }
}
}) {
column(gap = 12) {
text(role = TextRole::Heading(2), size = 22, weight = FontWeight::Semibold) {
"Projects"
}
ForEach(items = projects, key = |project| project.id) { |project|
ProjectRow(project = project.clone()) {}
}
}
}
Dialog(
open = true,
title = view! {
text(role = TextRole::Heading(2), size = 22, weight = FontWeight::Semibold) {
"Dialog with custom title and actions"
}
},
actions = view! {
button(kind = ButtonKind::Secondary) { "Cancel" }
button(kind = ButtonKind::Primary) { "Delete" }
},
) {
text(color = colors::muted()) {
"A dialog can declare exactly one main child body plus separately typed \
title/actions slots."
}
}
}
}
}
#[component]
fn FilterChip(children: impl InlineChildren, selected: bool) -> impl View {
let background = if selected {
colors::accent()
} else {
colors::muted().with_alpha(0.12)
};
view! {
block(
padding = (8, 16),
background = background,
corner_radius = 1000,
) {
children
}
}
}
#[component]
fn ForEach<T, C>(
items: impl IntoIterator<Item = T>,
key: impl Fn(&T) -> u64,
children: impl Fn(T) -> C,
) -> impl View
where
C: Children,
{
todo!("The framework would lower this into a keyed mapper primitive or composite")
}
#[derive(Clone)]
struct Project {
id: u64,
name: String,
}
fn projects() -> Vec<Project> {
Vec::new()
}