// MobileShell — Material 3 layout: TopAppBar + Content + BottomNavBar + FAB.
// Parent provides content as @children.
import { MaterialColors, MaterialSpacing } from "../../tokens/material/mod.slint";
import { Sizes } from "../../tokens/sizes.slint";
import { NavItem } from "../types.slint";
import { TopAppBar } from "top-app-bar.slint";
import { BottomNavBar } from "bottom-nav-bar.slint";
import { FAB } from "fab.slint";
import { FluentIcons } from "../../tokens/theme.slint";
/// M ob il es he ll component.
export component MobileShell inherits VerticalLayout {
// Config
/// Input property "title".
in property <string> title: "App";
/// Input property "nav-items".
in property <[NavItem]> nav-items;
/// Input property "active-view".
in property <string> active-view: "";
/// Input property "fab-icon".
in property <string> fab-icon: FluentIcons.add;
/// Input property "fab-label".
in property <string> fab-label: "";
/// Input property "show-fab".
in property <bool> show-fab: true;
// Callbacks
/// Callback fired for n av ig at e.
callback navigate(string);
/// Callback fired for f ab c li ck ed.
callback fab-clicked();
spacing: Sizes.no-size;
// ── TopAppBar ─────────────────────────────────────────────────────────
TopAppBar {
title: root.title;
action-icon: FluentIcons.search;
}
// ── Content area ──────────────────────────────────────────────────────
Rectangle {
vertical-stretch: Sizes.one;
background: MaterialColors.surface;
VerticalLayout {
padding: MaterialSpacing.md;
@children
}
// FAB (bottom-right, above bottom nav)
if root.show-fab: FAB {
icon: root.fab-icon;
label: root.fab-label;
x: parent.width - self.width - MaterialSpacing.md;
y: parent.height - self.height - MaterialSpacing.md;
clicked => { root.fab-clicked(); }
}
}
// ── BottomNavBar ──────────────────────────────────────────────────────
BottomNavBar {
items: root.nav-items;
active: root.active-view;
navigate(id) => { root.navigate(id); }
}
}