Saltar al contenido
El Muestrario

componente · @solu30/ui-kit/feedback

Modal

Overlay configurado por props, con encabezado, pie y cinco posiciones: centro, lateral, inferior o pantalla completa.

336 sitios de import en 10 de 15 verticales — un archivo que la importa cuenta una vez, monte una instancia o veinte.

  • TheCharterPanel
  • carlosmartinpavon
  • cmp-packages
  • dietaly
  • easycharter
  • elliot
  • gestorsalon
  • luigi
  • raquetea
  • zentrya

El componente, montado

Cargando el espécimen…

Cómo se usa

import { Modal } from '@solu30/ui-kit/feedback'

Props

22 props declaradas en los tipos de la versión instalada.
PropRequeridaTipoQué hace
isOpensíboolean—
onClosesí() => void—
titleopcionalstring—
subtitleopcionalstring—
descriptionopcionalstring—
iconopcionalReactNodeOptional icon rendered in a circle to the left of the title. Pair with `iconBgColor` to control the circle background.
iconBgColoropcionalstringTailwind background class for the icon circle. @default 'bg-primary-muted'
subtitleColoropcionalstringTailwind text color class for the subtitle. @default 'text-content/60'
sizeopcionalModalSize—
childrensíReactNode—
footeropcionalReactNode—
classNameopcionalstring—
styleopcionalCSSProperties—
staticopcionalbooleanPrevent closing on backdrop click
dismissibleopcionalbooleanCuando es `false`, el modal es genuinamente no-cerrable: bloquea Escape, click en el backdrop (independiente de `static`) Y el botón X (se oculta, sin importar `hideCloseButton`). `role` pasa de `dialog` a `alertdialog` — misma semántica ARIA que usa `AlertDialog` para "hay que responder sí o sí". El back button del navegador también queda tragado mientras `manageHistory` esté activo (mismo criterio que `AlertDialog`). Usalo SOLO cuando existe una salida alcanzable por teclado dentro del propio modal — típicamente un botón de aceptar en `footer` — porque sin eso es una trampa de teclado (WCAG 2.1.2). Pasá `initialFocusRef` apuntando a ese botón para que el foco llegue ahí al abrir. NO usar para confirmaciones de rutina, formularios o cualquier flujo con una vía de "cancelar" razonable — para eso `static` (bloquea solo el backdrop) alcanza y no genera este riesgo de a11y. Reservalo para avisos que de verdad exigen una respuesta explícita: cambio de precios, cambio de protocolo operativo, aviso de gerencia. @default true
initialFocusRefopcionalRefObject<HTMLElement | null>Elemento que recibe foco al abrir. Si no se pasa y `dismissible={false}`, el foco cae en el último elemento focuseable del modal (por convención del kit, la acción primaria del `footer` va al final — ver `ConfirmDialog`/`AlertDialogFooter`). Con `dismissible` en su default `true` no cambia nada: sigue yendo al primer elemento focuseable.
variantopcionalModalVariantVisual variant
renderHeaderopcional(props: { title?: string; onClose: () => void; }) => ReactNodeOverride the entire header
hideCloseButtonopcionalbooleanHide the close button
fillHeightopcionalbooleanSide/left panels fill entire height
noContentPaddingopcionalbooleanRemove content padding (for maps, etc.)
manageHistoryopcionalbooleanSi este modal maneja su propia entrada de `window.history` (pushState al abrir, "atrás" lo cierra). Default `true` — sin cambios de comportamiento para consumidores existentes. Poné `false` cuando `isOpen`/`onClose` YA están sincronizados con la URL de la app (Next.js App Router: `?param=` + `router.push`/`searchParams`), o cuando el modal se abre ANIDADO dentro de un overlay URL-driven — en ambos casos el pushState propio del kit mete una entrada espuria en el historial y "atrás" necesita un press de más para cerrar lo de afuera (ADR-262). @default true

Ejemplo del paquete

// Controlado siempre: el que lo abre es dueño de `isOpen`.
const [abierto, setAbierto] = useState(false)

<Modal
  isOpen={abierto}
  onClose={() => setAbierto(false)}
  title="Nueva reserva"
  size="lg"
  footer={<Button onClick={guardar}>Guardar</Button>}
>
  <FormularioReserva />
</Modal>

Del @example del JSDoc de @solu30/ui-kit, sin editar: son 65 de los 541 símbolos. La sangría y los renglones en blanco son los del paquete.