/v1.0

MultiSelectModal

Modal a pantalla completa que combina una barra de búsqueda Autocomplete con un DynamicList para permitir a los usuarios construir una colección de ítems seleccionados. Los ítems pueden agregarse mediante búsqueda y eliminarse individualmente. Cuando savePath está definido, el botón flotante de guardar envía la selección final a la API. Los cambios se rastrean comparando la lista actual con su estado inicial, por lo que el botón de guardar solo se habilita cuando la selección ha cambiado efectivamente. El modal también puede usarse en modo de solo lectura.

Props

| Prop | Tipo | Requerido | Por defecto | Descripción | |------|------|-----------|-------------|-------------| | isOpen | boolean | Sí | — | Controla si el modal está visible. | | onClose | (reason: 'cancel' \| 'success' \| 'error' \| 'custom') => void | Sí | — | Se llama cuando el modal se cierra. Recibe una cadena de razón. | | title | string | Sí | — | Título mostrado en el encabezado del modal. | | searchPath | string | Sí | — | Ruta de API para las solicitudes de autocompletado. | | subtitle | string | No | — | Subtítulo mostrado en el encabezado del modal. | | data | any[] \| null | No | — | Arreglo inicial de ítems seleccionados. | | backdropStyle | React.CSSProperties | No | — | Estilos en línea para el backdrop del modal. | | windowStyle | React.CSSProperties | No | — | Estilos en línea fusionados en la ventana del modal. | | closeButtonStyle | React.CSSProperties | No | — | Estilos para el botón de cierre. | | closeIcon | string | No | — | Nombre del ícono del botón de cierre. | | closeIconPaths | any[] | No | — | Rutas de ícono personalizadas para el botón de cierre. | | closeIconSize | number | No | — | Tamaño del ícono del botón de cierre. | | zIndex | number | No | 99999 | z-index CSS del overlay del modal. | | id | string | No | — | id HTML del elemento modal. | | fullScreen | boolean | No | — | Cuando es true, el modal ocupa toda la pantalla. | | apiBaseUrl | string | No | — | URL base del cliente HTTP. | | useAuthToken | boolean | No | — | Cuando es true, usa el cliente HTTP autenticado. | | noContentText | string | No | 'No content available' | Texto mostrado cuando la lista está vacía. | | noContentIcon | string | No | 'records' | Ícono mostrado cuando la lista está vacía. | | startSlots | Slot[] | No | [] | Slots al inicio de cada ítem de la lista. | | endSlots | Slot[] | No | [] | Slots al final de cada ítem (siempre se agrega un botón de eliminar a menos que readonly sea true). | | searchPlaceholder | string | No | "Buscar..." | Texto placeholder para el campo de búsqueda. | | searchItemLabelKey | string | No | — | Clave usada como etiqueta en los ítems de resultados de búsqueda. | | searchItemDescriptionKey | string | No | — | Clave usada como descripción en los ítems de resultados de búsqueda. | | searchItemImageKey | string | No | — | Clave usada como imagen en los ítems de resultados de búsqueda. | | fetchPath | string | No | — | Ruta de API para cargar la lista inicial de ítems seleccionados. | | savePath | string | No | — | Ruta de API para hacer POST/PUT/PATCH de la selección final. | | saveMethod | 'POST' \| 'PUT' \| 'PATCH' \| 'DELETE' | No | — | Método HTTP para la petición de guardado. | | payloadKey | string | No | — | Clave bajo la cual se envía el arreglo de ítems en el payload. Por defecto 'data'. | | searchBarWidth | number \| string | No | 400 | Ancho de la barra de búsqueda. | | listWidth | number \| string | No | 500 | Ancho máximo de la lista de ítems. | | readonly | boolean | No | — | Cuando es true, oculta la barra de búsqueda y los botones de eliminar. | | onSaveSuccess | (data: any) => void | No | — | Se llama tras una petición de guardado exitosa. | | onSaveError | (error: any) => void | No | — | Se llama tras una petición de guardado fallida. |

Uso

Básico

import React from 'react';
import MultiSelectModal from '@/components/modals/MultiSelectModal';

export default function Example() {
  const [open, setOpen] = React.useState(false);
  const [members, setMembers] = React.useState([]);

  return (
    <>
      <button onClick={() => setOpen(true)}>Manage Members</button>
      <MultiSelectModal
        isOpen={open}
        onClose={(reason) => {
          console.log('Closed:', reason);
          setOpen(false);
        }}
        title="Team Members"
        searchPath="/v1/users/search"
        searchItemLabelKey="name"
        searchItemDescriptionKey="email"
        savePath="/v1/team/members"
        saveMethod="PUT"
        payloadKey="members"
        data={members}
        useAuthToken
        onSaveSuccess={() => console.log('Saved!')}
      />
    </>
  );
}