Slideout
Panel lateral derecho para ver o editar el detalle de un elemento sin perder la lista de fondo.
Cuándo usarlo
Props. open, title, description, children, actions (botones del pie, a la derecha), onClose, width (400 por defecto), contained.
Visual. Panel bg-primary_alt a toda la altura, shadow-xl; cabecera con padding spacing-3xl y botón de cerrar; pie con línea border-secondary. Fondo bg-overlay al 70% con desenfoque, igual que el modal.
Slideout o Modal. Si hay que leer o rellenar más de tres campos, o el usuario quiere comparar con la lista, slideout. Para confirmar una decisión, Modal.
Accesibilidad. Igual que Modal: el foco no sale del panel, Escape, la X o un clic fuera lo cierran, el foco vuelve a quien lo abrió y la página no se desplaza debajo. Sin onClose no hay X ni se puede descartar.
Detalles. El cuerpo se desplaza si el contenido no cabe; cabecera y pie se quedan fijos. contained lo pinta dentro de su contenedor sin atrapar el foco, como en esta página.
Ejemplos
Props
| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
open | boolean | true | Visible. Con false no se pinta. |
titleobligatoria | ReactNode | — | |
description | ReactNode | — | |
children | ReactNode | — | Contenido: detalle o formulario. Se desplaza si no cabe. |
actions | ReactNode | — | Botones del pie, alineados a la derecha. |
onClose | (() => void) | — | Cierra con la X, Escape o un clic fuera. Sin él no hay X y el panel no se puede descartar. |
width | string | number | 400 | Ancho máximo del panel. |
contained | boolean | — | Se pinta dentro de su contenedor (posición relativa) en vez de sobre toda la página, sin atrapar el foco. |
Código
import { Slideout } from "@jotis-me/react";
export default function Page() {
return (
<>
<Slideout
open={abierto}
title="Alquiler"
description="Movimiento del 1 de octubre"
onClose={cerrar}
actions={<Button onClick={guardar}>Guardar</Button>}
>
<Input label="Concepto" defaultValue="Alquiler" />
</Slideout>
</>
);
}---
import { Slideout } from "@jotis-me/react";
---
<Slideout client:load
open={abierto}
title="Alquiler"
description="Movimiento del 1 de octubre"
onClose={cerrar}
actions={<Button onClick={guardar}>Guardar</Button>}
>
<Input label="Concepto" defaultValue="Alquiler" />
</Slideout>onClose es una función y abrirlo necesita estado: envuélvelo en un .tsx con el botón que lo abre y úsalo con client:load.