AuthLayout
The shell of an authentication route, a measured form column, a panel to draw it on, a heading, and an optional media column beside it.
An authentication route is one form and very little else, so the page around it is mostly a decision about where the form sits. AuthLayout supplies that: the column is centred in the height it is given, it keeps a readable measure, it can be drawn on a panel, and it has somewhere to put the brand, the heading, the supporting sentence and the link to the other route.
It carries no authentication of its own. There is no field registry, no validation and no request:
the form is children, and everything the reader submits is the page's.
Reach for it when the whole screen is a way in, sign in, sign up, reset, verify. For a screen
behind that door, the shell is SidebarLayout or Page.
Usage
import {
AuthLayout,
Form,
Input,
Link,
PasswordInput,
VStack,
} from "@asheeui/web";
<AuthLayout
brand="Ashee SMS"
title="Sign in"
description="Use the email address your workspace knows."
footer={<Link href="/sign-up">Create an account</Link>}
>
<Form aria-label="Sign in" submitLabel="Sign in" onSubmit={signIn}>
<VStack gap="md">
<Input label="Email" type="email" name="email" autoComplete="email" />
<PasswordInput label="Password" name="password" />
</VStack>
</Form>
</AuthLayout>;
That is the whole contract. brand, title and description fill the block above the form,
children is the form, and footer is the row under it. The shell decides where those sit; the
page decides what they say, every field, the submit control and the form's own name included.
The media column
media is a slot rather than a picture prop: pass a screenshot, a card of numbers, a quotation,
whatever the page wants beside the form. With content in it the shell becomes two columns from the
lg breakpoint (1024 pixels), the media taking half of the width, and mediaPosition states which
half.
Below lg there is only one column, so the media stacks in the order the side puts it in the
flow: above the form for start, below it for the registered end. That is deliberate, a
product shot under a short form still reads as part of the page, while a figure above a long form
would push the first field past the fold.
The panel and the measure
Three options decide what the form is drawn on and how wide it is. panel (registered true)
wraps the form in a bordered surface with its own padding; without it the form sits directly on the
page background. align (registered center) centres the column vertically, or holds it at the
top for a route with a long form or a message above it. contentSize (registered sm) is the
maximum width of that column, taken from the width tokens.
The three are independent on purpose: a sign-up route usually wants panel={false}, align="start"
and a wider measure, and stating one of them should not quietly change the others.
Props
All four layout options are registered by the component, so each resolves from the instance, then
from components.authlayout, then from the registration: panel true, align center,
mediaPosition end, contentSize sm. brand, title, description, children, footer
and media are instance-only, because they are the page's own words, and as is instance-only
too. There is no colour or variant option: the panel is the framework's own bordered surface, so
it follows the theme's border and background rather than asking the page. Its corners are not a
layout option either, the radius resolves from the application's defaultRadius, with md as
the hard fallback when no configuration supplies one, so a product that rounds every surface
rounds the sign-in panel with them.
Accessibility
- The shell renders no landmark. It is a
divunlessassays otherwise, so place it inside the document'smain, or passas="main"when the shell is the route's whole page. titlerenders an<h2>, not the page's<h1>. It goes through the shared section heading at thelgstep, and that heading renders an<h2>at every size by default; this layout has notitleAsto raise it, because a layout that decided the page's top-level heading for it would be deciding the route's outline. So a route that states its own<h1>, a line of thebrand, or a heading at the top ofchildren, keepstitleas the section heading beneath it, and a route whose title is the page's only heading states that<h1>itself rather than expecting the shell to render one.- The form is yours, including its name. The shell renders no
formelement and adds noaria-label, so the name and the submit control come from theFormyou pass (itslegend, or itsaria-label). paneland the media column are visual boundaries only: neither is a landmark, a region or a name, and alternative text belongs to the media you pass into the slot.
The tokens behind contentSize and the gaps inside the form are the ones
Layout and spacing describes; which shell a product should start
from is the argument in Page compositions.
Native
@asheeui/native ships AuthLayout with the same props and the same cascade. The platform's
differences are the platform's: the shell fills the screen the platform gives it rather than
claiming a viewport height, nothing scrolls, and the media column is placed from the same lg
width by the platform's own measurement instead of by a media query. See
React Native.