Sheet
Un panel que se desliza desde cualquier borde, con deslizamiento para descartar, bloqueo de scroll y anidamiento apilado.
pnpm dlx shadcn@latest add https://hextaui.com/r/sheet.jsonAñade el componente, los tokens del tema de HextaUI y los componentes de HextaUI de los que depende.
Añade los tokens del tema a tu CSS global, si aún no lo has hecho.
Instala las dependencias.
pnpm add @base-ui/react @tabler/icons-react class-variance-authority cnCopia y pega el siguiente código en tu proyecto.
components/ui/sheet.tsx components/ui/button.tsx Actualiza las rutas de importación para que coincidan con la configuración de tu proyecto.
Lados
Define side para que entre desde cualquier borde. Cada sheet se puede deslizar de vuelta hacia su propio borde, y el gesto de cierre sigue tu dedo con inercia.
Contenido largo
<SheetBody /> se desplaza por sí solo, así que el encabezado y el pie permanecen en su sitio por largo que sea el contenido.
Sin el botón de cierre
Define showCloseButton={false} cuando el pie ya tiene una forma de salir. Escape, el fondo y el deslizamiento siguen cerrándolo.
Anidado
Un sheet o alert dialog abierto desde un sheet se coloca encima. El padre se reduce ligeramente y cada capa adicional añade un fondo más claro, para que la pila siga siendo legible. Escape cierra solo la capa superior.
Controlado
Pasa open y onOpenChange para abrirlo desde cualquier lugar, sin un trigger.
Triggers desacoplados
Comparte un sheet entre varios triggers con createSheetHandle. Cada trigger pasa un payload que el sheet renderiza mediante un hijo función.
De derecha a izquierda
Con dir="rtl", el lado derecho se refleja al borde izquierdo, entra desde allí y se desliza para salir en el mismo sentido.
| Key | Acción |
|---|---|
| EnterSpace | En el trigger, abre el sheet y mueve el foco a su interior. |
| TabShift + Tab | Se mueve entre elementos enfocables. El foco permanece dentro del sheet. |
| Esc | Cierra el sheet superior y devuelve el foco a su trigger. |
- El sheet es un dialog modal.
<SheetTitle />lo etiqueta y<SheetDescription />lo describe, así que incluye siempre un título. - El scroll de la página se bloquea y el contenido de detrás se oculta a las tecnologías de asistencia mientras está abierto.
- El botón de cierre tiene la etiqueta “Close”. El tirador del borde interior indica que el sheet se puede arrastrar y se oculta a las tecnologías de asistencia.
- Con movimiento reducido activado, el sheet aparece y desaparece con un fundido en lugar de deslizarse.
Construido sobre el drawer de Base UI. Cada parte acepta las props de la primitiva que envuelve.
| Prop | Tipo | Predeterminado |
|---|---|---|
defaultOpen | boolean | false |
open | boolean | – |
onOpenChange | (open: boolean, details) => void | – |
onOpenChangeCompleteSe llama cuando termina la animación de apertura o cierre. | (open: boolean) => void | – |
modal | boolean | "trap-focus" | true |
disablePointerDismissalLo mantiene abierto al hacer clic en el fondo. | boolean | false |
swipeDirectionSe define automáticamente según el lado y la dirección del contenido. | "up" | "down" | "left" | "right" | – |
handle | SheetHandle<Payload> | – |
children | ReactNode | ({ payload }) => ReactNode | – |
| Prop | Tipo | Predeterminado |
|---|---|---|
handle | SheetHandle<Payload> | – |
payload | Payload | – |
render | ReactElement | (props, state) => ReactElement | <button> |
| Atributo | Descripción |
|---|---|
data-slot="sheet-trigger" | Apunta al trigger en CSS. |
data-popup-open | Presente mientras su sheet está abierto. |
Renderiza el portal, el fondo, el viewport y el popup, además del tirador de arrastre y el botón de cierre.
| Prop | Tipo | Predeterminado |
|---|---|---|
side | "top" | "right" | "bottom" | "left" | "right" |
showCloseButton | boolean | true |
dirDefine la dirección del sheet. right y left se reflejan en rtl. | "ltr" | "rtl" | – |
initialFocus | boolean | RefObject | (type) => HTMLElement | boolean | – |
finalFocus | boolean | RefObject | (type) => HTMLElement | boolean | – |
classNameLos sheets laterales ocupan el 75% del ancho, hasta 24rem desde el breakpoint sm. | string | (state) => string | – |
render | ReactElement | (props, state) => ReactElement | <div> |
| Atributo | Descripción |
|---|---|
data-slot="sheet-content" | El panel del sheet. |
data-side | El lado desde el que se abre. |
data-open | Presente mientras el sheet está abierto. |
data-starting-style | Presente mientras se anima la entrada. |
data-ending-style | Presente mientras se anima la salida. |
data-swiping | Presente mientras se arrastra. |
data-swipe-direction | La dirección que lo descarta. |
data-nested-drawer-open | Presente mientras hay un sheet anidado abierto encima. |
data-slot="sheet-handle" | El tirador de arrastre del borde interior. |
data-slot="sheet-close-button" | El botón de cierre integrado. |
--drawer-swipe-movement-x | Distancia de arrastre horizontal. También existe una variable -y. |
--nested-drawers | Cuántos sheets anidados hay abiertos encima. |
Lo renderiza <SheetContent />. Las capas anidadas reciben un fondo más claro.
| Atributo | Descripción |
|---|---|
data-slot="sheet-overlay" | El fondo. |
data-nested | Presente en los fondos de las capas anidadas. |
Elementos <div> simples que disponen el sheet. El encabezado deja espacio para el botón de cierre, el cuerpo hace scroll y ocupa el alto restante, y el pie apila sus acciones en pantallas pequeñas y las alinea al final desde el breakpoint sm.
| Atributo | Descripción |
|---|---|
data-slot="sheet-header" | Título y descripción. |
data-slot="sheet-body" | Contenido desplazable. |
data-slot="sheet-footer" | Acciones. |
| Prop | Tipo | Predeterminado |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <h2> |
| Atributo | Descripción |
|---|---|
data-slot="sheet-title" | Etiqueta el sheet. |
| Prop | Tipo | Predeterminado |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <p> |
| Atributo | Descripción |
|---|---|
data-slot="sheet-description" | Describe el sheet. |
| Prop | Tipo | Predeterminado |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <button> |
| Atributo | Descripción |
|---|---|
data-slot="sheet-close" | Cierra el sheet al pulsarlo. |
createSheetHandle<Payload>() devuelve un handle que conecta un <Sheet /> con triggers renderizados en otro lugar. Créalo una sola vez, fuera de tu componente.
- ButtonBotones en todas las variantes y tamaños, con un flujo integrado de carga, éxito y error que omite el spinner en las peticiones rápidas.
- Alert dialogUn diálogo de confirmación para acciones destructivas o importantes que espera el trabajo asíncrono y se convierte en una hoja inferior en móviles.
- CommandUna lista de acciones con búsqueda, en línea o como paleta ⌘K, con páginas, atajos y coincidencias resaltadas.
- Context menuUn menú de acciones con clic derecho o pulsación larga, con submenús, elementos de casilla y de radio, y respuesta al mantener pulsado en pantallas táctiles.
- DialogUna ventana sobre la página para formularios y tareas concretas, con encabezado y pie fijados, anidamiento y una hoja inferior deslizable en móviles.
- DrawerUn panel que se desliza desde cualquier borde y sigue tu dedo, con puntos de anclaje, un tirador funcional y drawers anidados que se apilan.
Usado en bloques
Bloques que se construyen sobre Sheet.