Navegación
AppShell
El layout de un panel: sidebar sticky desde lg y, debajo, una barra de 56px con hamburguesa.
import { AppShell } from "sebs7n-ui/app-shell"Ejemplos
El layout completo
Achicá la ventana por debajo de 1024px: el sidebar pasa a un Sheet detrás de la hamburguesa. El alto sale de `--app-shell-height`; acá está fijado en 560px para que entre en la página.
Ir al contenido
Facturas
Todo lo emitido en septiembre.
Facturado
$ 1.284.000
+12,4 %vs. agosto
Vencido
$ 142.900
6 facturas
import { AppShell } from "sebs7n-ui/app-shell"
import { AppShellContent } from "sebs7n-ui/app-shell-content"
import { Button } from "sebs7n-ui/button"
import { Card, CardContent } from "sebs7n-ui/card"
import { DropdownMenuItem } from "sebs7n-ui/dropdown-menu"
import { FileTextIcon, LogOutIcon, UsersIcon } from "lucide-react"
import { PageHeader, PageHeaderActions, PageHeaderDescription, PageHeaderTitle } from "sebs7n-ui/page-header"
import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupLabel, SidebarHeader, SidebarItem } from "sebs7n-ui/sidebar"
import { Stat } from "sebs7n-ui/stat"
import { UserMenu } from "sebs7n-ui/user-menu"
function Completo() {
const usuario = { name: "Ana Pérez", email: "ana@acme.com" }
return (
<div className="overflow-hidden rounded-xl border border-gray-400">
<AppShell
className="[--app-shell-height:560px]"
mobileBar={
<>
<div className="size-6 rounded-md bg-gray-1000" />
<span className="ml-auto" />
<UserMenu collapsed user={usuario} />
</>
}
sidebar={
<Sidebar>
<SidebarHeader>
<div className="flex h-8 items-center gap-2 px-1">
<div className="size-6 shrink-0 rounded-md bg-gray-1000" />
<span className="text-label-14 font-medium">Acme</span>
</div>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Operación</SidebarGroupLabel>
<SidebarItem active icon={<FileTextIcon />}>
Facturas
</SidebarItem>
<SidebarItem icon={<UsersIcon />}>Clientes</SidebarItem>
</SidebarGroup>
</SidebarContent>
<SidebarFooter>
<UserMenu
signOut={
<DropdownMenuItem>
<LogOutIcon />
Cerrar sesión
</DropdownMenuItem>
}
user={usuario}
/>
</SidebarFooter>
</Sidebar>
}
>
<AppShellContent>
<PageHeader>
<PageHeaderTitle>Facturas</PageHeaderTitle>
<PageHeaderDescription>Todo lo emitido en septiembre.</PageHeaderDescription>
<PageHeaderActions>
<Button variant="accent">Nueva factura</Button>
</PageHeaderActions>
</PageHeader>
<div className="grid gap-4 sm:grid-cols-2">
<Card size="sm">
<CardContent>
<Stat delta="+12,4 %" hint="vs. agosto" label="Facturado" trend="up" value="$ 1.284.000" />
</CardContent>
</Card>
<Card size="sm">
<CardContent>
<Stat delta="6 facturas" label="Vencido" trend="down" value="$ 142.900" />
</CardContent>
</Card>
</div>
</AppShellContent>
</AppShell>
</div>
)
}Props
Generadas del TypeScript del paquete. Solo las props propias: las heredadas del primitivo de Base UI o del elemento HTML están en la línea «hereda de».
AppShell
Hereda las props de <div>.
| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
sidebar* | React.ReactNode | — | Un <Sidebar>. Se renderiza fijo en desktop y dentro de un Sheet en mobile. |
labels | Partial<AppShellLabels> | — | |
mainId | string | "contenido" | id del <main>; es a donde apunta el skip link. |
mobileBar | React.ReactNode | — | Contenido de la barra de 56px a la derecha de la hamburguesa. |
pathname | string | — | La ruta actual. Cuando cambia, el Sheet mobile se cierra. |
className | string | — |
Teclado
- Tab (primera parada)
- «Ir al contenido», el skip link que salta al
<main>. - Escape
- Cierra el Sheet mobile.
Accesibilidad
- Trae el skip link «Ir al contenido» apuntando al
<main>: es la primera parada de tabulación de toda la app. - El
<main>tieneid(mainId, por defectocontenido) y es enfocable por programa. - Al elegir un ítem en el Sheet mobile, se cierra y el foco va al
<main>. - Los textos son configurables por
labels, para traducir la app entera.
Reglas de uso
- Pasale `pathname={usePathname()}`: cualquier navegación —un link del contenido, un
router.push— cierra el Sheet mobile. - Usá `AppShellContent` como hijo directo: es el contenedor de página, así todas las pantallas tienen el mismo ancho.
- El alto sale de
--app-shell-height(100dvh). Para embeberlo en una caja:className="[--app-shell-height:720px]". - Para cerrar el Sheet desde un caso propio:
useAppShell().closeMobile({ focusMain: true }).