componente · @solu30/ui-kit/feedback
Modal
El componente, montado
Cargando el espécimen…
Cargando el chunk del paquete instalado…
De dónde se importa
import { Modal } from '@solu30/ui-kit/feedback'Props
| Prop | Requerida | Tipo | Qué hace |
|---|---|---|---|
| isOpen | sí | boolean | — |
| onClose | sí | () => void | — |
| title | opcional | string | — |
| subtitle | opcional | string | — |
| description | opcional | string | — |
| icon | opcional | ReactNode | Optional icon rendered in a circle to the left of the title. Pair with `iconBgColor` to control the circle background. |
| iconBgColor | opcional | string | Tailwind background class for the icon circle. @default 'bg-primary-muted' |
| subtitleColor | opcional | string | Tailwind text color class for the subtitle. @default 'text-content/60' |
| size | opcional | ModalSize | — |
| children | sí | ReactNode | — |
| footer | opcional | ReactNode | — |
| className | opcional | string | — |
| style | opcional | CSSProperties | — |
| static | opcional | boolean | Prevent closing on backdrop click |
| dismissible | opcional | boolean | Cuando 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 |
| initialFocusRef | opcional | RefObject<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. |
| variant | opcional | ModalVariant | Visual variant |
| renderHeader | opcional | (props: { | Override the entire header |
| title | opcional | string | — |
| onClose | sí | () => void | — |
| hideCloseButton | opcional | boolean | Hide the close button |
| fillHeight | opcional | boolean | Side/left panels fill entire height |
| noContentPadding | opcional | boolean | Remove content padding (for maps, etc.) |
| manageHistory | opcional | boolean | Si 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 |