AppShell
Wrapper de más alto nivel sobre OrbitSidebar — arma el layout completo de
una app (riel + área de contenido) y decide él mismo, según el ancho
disponible (no el viewport, el ancho medido del propio componente — la
misma lógica “container query” que usa OrbitTable para su stack
responsive), en cuál de tres modos mostrarse:
- Expandido (≥ 900px): sidebar fijo a
width, con labels. - Colapsado (600px–900px): sidebar reducido a
collapsedWidth, solo íconos. - Drawer (< 600px): el sidebar desaparece del layout y pasa a vivir dentro
de un
OrbitDrawerque se abre bajo demanda.
No hay un botón de menú incorporado — igual que OrbitSidebar no trae su
propio toggle de colapso, dónde va ese botón varía demasiado por producto.
En su lugar, el slot de contenido recibe una señal (evento en web, callback
en Kotlin) para saber si corresponde mostrar uno, y un método/función para
abrir el drawer cuando se lo toca.
En web, este elemento no crea el <orbit-sidebar> que ves — lo arma
internamente y reubica ahí mismo cualquier hijo que no sea
slot="content" (así que slot="header", slot="footer", y los
<orbit-nav-item>/<orbit-nav-group> sueltos van exactamente donde irían
si los pusieras directo en <orbit-sidebar>). Esa misma instancia se mueve
físicamente entre el layout anclado y el <orbit-drawer> interno al cruzar
los breakpoints, en vez de duplicarse.
Uso
Arrastrá la esquina inferior derecha del demo para achicarlo y ver los tres modos.
<orbit-app-shell id="shell"> <div slot="header">DragBuilder</div> <orbit-nav-group title="ESPACIOS"> <orbit-nav-item value="board" label="Board" icon="grid" selected></orbit-nav-item> <orbit-nav-item value="projects" label="Proyectos" icon="clipboard"></orbit-nav-item> </orbit-nav-group> <div slot="footer"> <orbit-nav-item value="settings" label="Ajustes" icon="sliders"></orbit-nav-item> </div> <div slot="content"> <button id="menu-btn" hidden>Menú</button> <!-- resto del contenido --> </div></orbit-app-shell>
<script> shell.addEventListener('orbit-shell-mode-change', (e) => { menuBtn.hidden = !e.detail.isDrawerMode; }); menuBtn.addEventListener('click', () => shell.openDrawer());</script>OrbitAppShell( header = { collapsed -> if (!collapsed) Text("DragBuilder", fontWeight = FontWeight.Bold) }, footer = { collapsed -> OrbitNavItem(label = "Ajustes", icon = OrbitIcon.Sliders, collapsed = collapsed, selected = false, onClick = {}) }, sidebarContent = { collapsed -> OrbitNavGroup( title = if (collapsed) null else "ESPACIOS", items = listOf( OrbitNavGroupItem(id = "board", label = "Board", icon = OrbitIcon.Grid), OrbitNavGroupItem(id = "projects", label = "Proyectos", icon = OrbitIcon.Clipboard), ), selectedId = "board", onSelect = { /* ... */ }, collapsed = collapsed, ) }, content = { isDrawerMode, onOpenDrawer -> if (isDrawerMode) { Box(Modifier.padding(end = 8.dp)) { OrbitIconButton(icon = OrbitIcon.Menu, onClick = onOpenDrawer) } } // resto del contenido },)Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
width (Kotlin) / attr width (web) | Dp / css length | 240.dp / "240px" | Ancho del sidebar expandido. |
collapsedWidth (Kotlin) / attr collapsed-width (web) | Dp / css length | 60.dp / "60px" | Ancho del sidebar en modo colapsado. |
selectedId / onSelect | String? / (String) -> Unit | null / no-op | Selección compartida por cualquier OrbitNavGroup dentro de los slots — ver OrbitNavGroup. |
header (Kotlin) / slot header (web) | slot | null | Contenido libre arriba de la navegación. En Kotlin recibe collapsed para adaptar su propio contenido. |
footer (Kotlin) / slot footer (web) | slot | null | Contenido libre abajo, con un divisor arriba. |
sidebarContent (Kotlin) / children sin slot (web) | slot | — | Los OrbitNavItem/OrbitNavGroup de la navegación. |
content (Kotlin) / slot content (web) | slot | — | El área principal. En Kotlin recibe (isDrawerMode, onOpenDrawer); en web, escuchá orbit-shell-mode-change (detail.isDrawerMode) y llamá al método openDrawer(). |