Ir al contenido
Navegación

SplitView

El master-detail de iCloud Mail: sidebar, lista y detalle separados por la línea entre paneles, que en el teléfono pasa a un panel por vez con «‹ Atrás».

import { SplitView, SplitViewBack, SplitViewDetail, SplitViewList, … } from "sebs7n-ui/split-view"

Ejemplos

Sidebar, lista y detalle

El master-detail de Mail: se acomoda al ancho que le toca. Ancho, los tres paneles; mediano, lista y detalle; angosto (el teléfono), un panel por vez y «‹ Atrás» vuelve al anterior. Achicá la ventana para verlo.

function Basico() {
  return <Correo />
}

Redimensionable

Con `resizable`, el sidebar y la lista llevan el separador de `Resizable` en su borde: se arrastra o se enfoca con Tab y se mueve con las flechas (10 px, Shift 40). Por defecto no, como Mail.

function Redimensionable() {
  return <Correo resizable />
}

Props

Generadas del TypeScript del paquete. Las propias del componente, más las heredadas del primitivo que tienen algo que explicar —marcadas «heredada de Base UI»—. El resto está en la línea «hereda de».

SplitView

Hereda las props de <div>.

PropTipoPor defectoDescripción
defaultPane"list" | "sidebar" | "detail""list"El panel activo al arrancar. Por defecto list.
defaultWidthsPartial<SplitViewWidths>—Los anchos al arrancar, en px ({ sidebar, list }). Por defecto 230 y 380.
onPaneChange(pane: SplitViewPane) => void—Se llama con el panel nuevo.
onWidthsChange(widths: SplitViewWidths) => void—Se llama con los anchos al soltar un separador o con cada tecla.
pane"list" | "sidebar" | "detail"—El panel activo (sidebar, list, detail): el que se ve en angosto. Pasarlo lo vuelve controlado.
resizablebooleanfalseEl sidebar y la lista se redimensionan con un separador en su borde. Por defecto no, como Mail.
classNamestring—Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana.

SplitViewBack

Hereda las props de <button>.

PropTipoPor defectoDescripción
onClickMouseEventHandler<T>—Se llama antes de volver. Con event.preventDefault() no vuelve (para confirmar un cambio sin guardar).
to"list" | "sidebar" | "detail"—Adónde vuelve. Por defecto, el anterior: del detalle a la lista, de la lista al sidebar. El texto del botón (los hijos) es el nombre de ese panel («Facturas»).
classNamestring—Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana.

SplitViewDetail

Sin props propias: pasa todo al primitivo.

SplitViewList

Sin props propias: pasa todo al primitivo.

SplitViewSidebar

Sin props propias: pasa todo al primitivo.

Teclado

Tab
Recorre los paneles en orden: sidebar, lista, detalle. En angosto, solo el que se ve.
Enter
En SplitViewBack, vuelve al panel anterior.
← → (en un separador, con `resizable`)
Cambian el ancho del panel de a 10 px; con Shift, 40. Home y End, al mínimo y al máximo.

Accesibilidad

  • Cada panel es un <section>: con aria-label es una región con nombre, y el lector salta entre paneles con los atajos de regiones.
  • En angosto los paneles que no se ven llevan display: none: no quedan en el orden de Tab ni los lee el lector.
  • Al pasar de panel en angosto, el foco va solo: si estaba en el panel que se oculta, pasa al que llega —a la fila elegida (aria-current o data-state="selected") al volver a la lista, o al primer título del panel—. En ancho, donde el de antes sigue a la vista, no se mueve.
  • SplitViewBack es un <button> con el nombre del panel al que vuelve («‹ Facturas»), como iOS: nunca solo el chevron.
  • Con resizable, cada separador es un role="separator" tabulable con el ancho en px (aria-valuenow/min/max), aria-controls al panel y el nombre del panel («Cambiar el tamaño: Facturas»). En angosto no se ve.

Reglas de uso

  • Para recorrer una colección y ver un ítem al lado: comprobantes, clientes, mensajes. Si el detalle es otra pantalla, es una List con chevron.
  • Anchos de iCloud: sidebar 230, lista 380 (320 en mediano), detalle el resto. Se acomoda al ancho del contenedor (container query), no al de la ventana: adentro de un panel angosto también pasa a un panel.
  • La fila de la lista llama `setPane("detail")` (useSplitView()) al elegirse: en ancho no cambia nada, en angosto muestra el detalle.
  • Dos paneles: omití el que sobra. Sin lista, SplitViewBack del detalle vuelve al sidebar con to="sidebar".
  • No se redimensiona, como iCloud. Con resizable, el sidebar (180–360) y la lista (260–560) llevan el separador de Resizable en su borde; guardá los anchos de onWidthsChange y devolvelos en defaultWidths. Para repartir en % otra cosa, Resizable.
  • El alto lo pone quien lo contiene (h-full adentro de AppShell, o un alto fijo); cada panel scrollea por su cuenta.
  • Solo por subpath (sebs7n-ui/split-view): no está en el barrel, por peso.

Relacionados