Rask
Rask
v0.23.1-alpha.0.745

Layouts

App frame

An application's frame in one line: the menu in Flux's sidebar, breadcrumbs written from that menu, who is signed in with a sign-out that asks first, and the page in the main. Not one of Flux UI's components: the kit's own, laid out of Flux's sidebar, header, breadcrumbs and profile as its sidebar layout lays them out.

An app's layout

The layout is the route its pages nest under; Outlet is where each page goes. Open Drivers, choose Active, then a driver: the row stays lit beneath its list, and the trail's Drivers leads back to the list still filtered. Vehicles sits in a group, which the trail names. On a phone the menu slides in from the header's toggle and the trail keeps its last two steps.

AppFrameExample.cs
using Rask.Core.Routing;

namespace Rask.Site.Features.UiDocs.Examples;

// An app's layout, whole: the route its pages nest under, and the frame they are drawn in. The menu is one sidebar nav,
// and the frame lights the row of the page shown (or of the list it is beneath), opens its group, and writes the
// breadcrumbs from it. The outlet is where each page goes, and the built-in 404 and 403 with them.
[Route("demo/app-frame")]
public sealed partial class AppFrameExample : Component
{
    protected override Component? HeadAssets => UiLayoutDemo.Meta("App frame", UiDocsCatalog.AppFrame);

    // The wrapper stands in for the app's <body> (its Shell's min-h-screen bg-white dark:bg-zinc-800): the frame's grid.
    protected override Component? Render() =>
        Div.Class("min-h-screen bg-white antialiased dark:bg-zinc-800")[
            Ui.AppFrame.Brand("Acme Fuels").Logo("/img/rask-mark.svg").Tenant("Northern depot").User("Mara Lind")
                .SignOut(Routes.UiAppFramePage())[
                Ui.SidebarNav[
                    Ui.SidebarItem.Key("home").Icon(Ui.IconName.Home).Href(Routes.AppFrameHomeDemoPage())["Home"],
                    Ui.SidebarItem.Key("drivers").Icon(Ui.IconName.Identification).Href(Routes.AppFrameDriversDemoPage())["Drivers"],
                    Ui.SidebarGroup.Key("fleet").Expandable(true).Icon(Ui.IconName.Truck).Heading("Fleet")[
                        Ui.SidebarItem.Key("vehicles").Icon(Ui.IconName.Truck).Href(Routes.AppFrameVehiclesDemoPage())["Vehicles"]
                    ]
                ],
                Outlet
            ]
        ];
}
Live result

The look is the kit's, the same in every app: the accent is the app's theme (--color-accent in its stylesheet) and the logo is Logo(url).

Lit and opened by the frame: the row of the page shown, or of the list it is beneath (/drivers/7 lights Drivers), and the group holding it. A row's own .Current(…) wins; a string link — an old front end — is never lit. Home is the row every other row is beneath.

The way back to a list keeps its filters, sort and page as the reader left them, and leaves out a Ui.EditorDialog's key, so it never reopens a form.

It mounts Ui.Toast, Ui.ConfirmLeave and Ui.Confirm in the catalog's words, and the built-in 404 and 403 stand in its main.

Reference

Ui.AppFrame

not in Flux UI

An app's frame: each Ui.SidebarNav among its children is the menu in Flux's sidebar, everything else (the Outlet) is the main; the header holds the phone's toggle and breadcrumbs written from the menu.

Step
Takes
What it does
.Brand(…)text: Ui.AppFrame.Brand("PPTA")The app's name at the top of the sidebar, leading home. Required, and taken first.
.Logo(…)stringThe logo's URL, before the name; all of the brand in a narrowed sidebar.
.LogoDark(…)stringThe logo shown in dark mode instead.
.Tenant(…)stringWhat the pages are shown inside — a partner, a tenant — in a line under the brand.
.User(…)stringWho is signed in, at the sidebar's foot.
.SignOut(…)a URL: "/logout"Where signing out goes, an endpoint that answers a GET: the profile's menu holds the sign-out row, which asks first in the catalog's words.
.Notices(…)ComponentWhat stands at the header's end: how background work is getting on.

Confirm