limbo-component
v3.6.4
Published
Limbo - Highly configurable React image manager component for web portals
Downloads
1,939
Readme
Limbo Component
Componente React embebible para gestión completa de activos digitales (DAM). Soporta imágenes, vídeos, audio, documentos PDF, Office y texto. Incluye galería, subida, recortador, visualizadores, generación con IA, búsqueda en Stock y gestión de carpetas.
Características
- Galería multi-tipo — Navega imágenes, vídeos, audio, documentos y texto del portal
- Subida de archivos — Drag & drop, validación por tipo/tamaño, preview por formato
- Recortador avanzado — Cropper.js 2.0 con presets, recortes obligatorios y libres
- Visualizadores nativos — ImageViewer (zoom/pan), VideoViewer, AudioViewer, PdfViewer, DocumentViewer, TextViewer
- Generación con IA — DALL-E, Midjourney y más a través de Atenea
- Stock de imágenes — Shutterstock y otros proveedores
- Portales externos — Acceso a activos de otros portales Limbo
- Sistema de carpetas — Organización, filtrado y movimiento de activos entre carpetas
- Filtro
accept— Control granular de tipos de archivo permitidos por instancia - GIF inteligente — Preserva animación original, hover-to-animate en galería
- Múltiples modos —
embed,modal,button·full,gallery-only,upload-only,crop-only,ia-only - AutoInputs — Integración automática con formularios HTML existentes
- Métodos prefab —
openGallery(),openUploader(),openCropper()y más - Autenticación JWT — 3 modos: session, manual, tokenProvider
- Multi-formato — ESM, CJS, UMD (con React 19 incluido en UMD)
- CSS aislado — Prefijo
lb:evita colisiones con estilos del portal - Accesible — ARIA, navegación por teclado, focus trap, screen readers
- Responsive — Mobile-friendly con container queries
Instalación
NPM / Yarn / PNPM
npm install limbo-component
# o
yarn add limbo-component
# o
pnpm add limbo-componentCDN (UMD — React incluido)
<!-- CSS -->
<link
rel="stylesheet"
href="https://limbo.lefebvre.es/cdn/component-limbo/latest/limbo.css"
/>
<!-- JS -->
<script src="https://limbo.lefebvre.es/cdn/component-limbo/latest/limbo.min.js"></script>NOTA: También puedes usar CDNs como jsdelivr
JS: https://cdn.jsdelivr.net/npm/limbo-component@latest/dist/limbo.min.js
CSS: https://cdn.jsdelivr.net/npm/limbo-component@latest/dist/limbo.css
Autenticación
El componente soporta 3 modos de autenticación:
// MODO 1: JWT con tokenProvider (RECOMENDADO para producción)
// Tu backend genera el token y lo expone en un endpoint propio
Limbo.configure({
publicKey: "pk_tu_clave_publica",
authMode: "jwt",
tokenProvider: async () => {
const res = await fetch("/api/limbo-token");
return (await res.json()).token;
},
});
// MODO 2: Manual (token proporcionado directamente)
Limbo.configure({
publicKey: "pk_tu_clave_publica",
authMode: "manual",
token: "eyJ0eXAiOiJKV1Q...",
});
// MODO 3: Session (usa cookies de sesión)
Limbo.configure({
publicKey: "pk_tu_clave_publica",
authMode: "session",
});Seguridad: En producción, usa siempre
tokenProvideromanual. Nunca expongas la API Key (sk_...) en código cliente.
Uso Rápido
Modo Embed (ESM)
import Limbo from "limbo-component";
import "limbo-component/css";
Limbo.configure({
publicKey: "pk_tu_clave_publica",
prod: true,
authMode: "jwt",
tokenProvider: async () => {
const res = await fetch("/api/limbo-token");
return (await res.json()).token;
},
});
// Selector completo: galería + subida + recortador
Limbo.create({
container: "#limbo-container",
mode: "embed",
modeUI: "full",
callbacks: {
onSelect: (data) => console.log("Seleccionado:", data),
onUpload: (data) => console.log("Subido:", data),
onCropsSaved: (data) => console.log("Recortes:", data),
},
});Modo UMD (HTML puro)
<!DOCTYPE html>
<html>
<head>
<link
rel="stylesheet"
href="https://limbo.lefebvre.es/cdn/component-limbo/latest/limbo.css"
/>
</head>
<body>
<div id="limbo-app"></div>
<script src="https://limbo.lefebvre.es/cdn/component-limbo/latest/limbo.min.js"></script>
<script>
Limbo.configure({
publicKey: "pk_tu_clave_publica",
prod: true,
authMode: "session",
});
Limbo.create({
container: "#limbo-app",
mode: "embed",
modeUI: "full",
});
</script>
</body>
</html>Filtro accept — Control de tipos de archivo
El parámetro accept permite controlar qué tipos de archivo puede seleccionar o subir el usuario. Usa la misma sintaxis que el atributo HTML <input accept>:
| Valor | Descripción |
| -------------------- | --------------------------------------------------- |
| "image/*" | Todas las imágenes (JPEG, PNG, GIF, WebP, SVG) |
| "video/*" | Todos los vídeos (MP4, WebM, MOV, AVI) |
| "audio/*" | Todo el audio (MP3, WAV, OGG, AAC, FLAC) |
| "document/*" | Todos los documentos (PDF, DOC, XLS, PPT, TXT, CSV) |
| ".pdf" | Solo archivos PDF |
| ".pdf,.docx,.xlsx" | Solo esos formatos específicos |
| "image/*,.pdf" | Imágenes + PDFs |
| null / omitido | Todo permitido (por defecto) |
Adaptación automática de la UI
Cuando las imágenes están excluidas del accept, el componente adapta la interfaz automáticamente:
| Elemento | Con imágenes | Sin imágenes | | --------------------- | ------------ | --------------------------------- | | Tab "Generar con IA" | Visible | Oculta (solo genera imágenes) | | Tab "Buscar en Stock" | Visible | Oculta (solo busca imágenes) | | Tab "Otros portales" | Visible | Oculta | | Recortador (Cropper) | Activo | Desactivado | | Tab "Subir archivo" | Visible | Visible (filtrado por accept) | | Galería | Muestra todo | Filtrada por tipos permitidos |
Ejemplos
// Selector de imágenes — UI completa (IA, Stock, Portales, Cropper)
Limbo.openGallery({
accept: "image/*",
onSelect: (img) => console.log("Imagen:", img),
});
// Selector de PDFs — Solo galería + subida, sin Cropper/IA/Stock
Limbo.openGallery({
accept: ".pdf",
onSelect: (doc) => console.log("PDF:", doc),
});
// Selector de documentos Office
Limbo.openUploader({
accept: ".pdf,.docx,.xlsx,.pptx",
onUpload: (doc) => console.log("Documento:", doc),
});
// Selector mixto: imágenes + PDFs
Limbo.createFullSelector("#file-picker", {
accept: "image/*,.pdf",
onSelect: (asset) => console.log("Archivo:", asset),
});
// Todo permitido (por defecto)
Limbo.openGallery({
onSelect: (asset) => console.log("Cualquier tipo:", asset),
});Con AutoInputs
<!-- Selector de imágenes -->
<input data-limbo-input-file data-accept="image/*" name="avatar" />
<!-- Solo PDFs -->
<input
data-limbo-input-file
data-accept=".pdf"
data-returntype="url"
name="contrato"
/>
<!-- Imágenes + PDFs -->
<input data-limbo-input-file data-accept="image/*,.pdf" name="adjunto" />
<!-- Vídeos solamente -->
<input data-limbo-input-file data-accept="video/*" name="video_promo" />
<!-- Todo permitido (sin data-accept) -->
<input data-limbo-input-file name="archivo_generico" />En la API
La galería envía el filtro automáticamente al backend:
GET /api/assets?accept=image/*,.pdfEl backend resuelve las extensiones y categorías y filtra por originalMime.
AutoInputs — Integración automática con formularios
El sistema AutoInputs transforma inputs HTML existentes en selectores de archivos Limbo. Detecta automáticamente inputs con el atributo configurado, oculta el input original y añade un botón estilizado.
Configuración global
Limbo.configure({
publicKey: "pk_tu_clave_publica",
prod: true,
authMode: "session",
});
Limbo.configureAutoInputs({
// Selector — puede ser dataset o selector CSS
dataset: "data-limbo-input-file", // por defecto
// selector: ".js-limbo", // alternativa: selector CSS directo
// Formato de retorno del valor al input
return: "url", // "url" | "json" | "assetId" | "base64" | "object" | "fileName"
// Modo y UI
mode: "modal",
modeUI: "full",
modalSize: "fullscreen",
// Botón
buttonText: "Seleccionar archivo",
buttonStyle: "primary", // "primary" | "secondary" | "outline" | "ghost"
buttonClass: "limbo-auto-button",
// Comportamiento
showPreview: true,
autoAssign: true, // Asignar valor automáticamente al input
});Configuración por input via data-*
Cada input puede sobreescribir la configuración global usando atributos:
<!-- Ejemplo básico -->
<input
type="hidden"
name="avatar"
data-limbo-input-file
data-returntype="url"
/>
<!-- Configuración completa por input -->
<input
type="hidden"
name="banner"
data-limbo-input-file
data-returntype="json"
data-accept="image/*"
data-modeui="full"
data-crop="16:9"
data-quality="0.85"
data-format="webp"
data-limbo-max-size="5MB"
data-limbo-button-text="Elegir banner"
data-limbo-button-style="outline"
data-mandatorycrops='[
{"label":"Desktop","width":1920,"height":400,"required":true},
{"label":"Mobile","width":640,"height":300,"required":true}
]'
/>
<!-- Solo galería, devuelve ID del asset -->
<input
type="hidden"
name="imagen_existente"
data-limbo-input-file
data-modeui="gallery-only"
data-returntype="assetId"
/>
<!-- Solo PDFs, devuelve URL -->
<input
type="hidden"
name="contrato_pdf"
data-limbo-input-file
data-accept=".pdf"
data-returntype="url"
data-limbo-button-text="Seleccionar PDF"
/>
<!-- Varios inputs diferentes en la misma página -->
<input data-limbo-input-file data-accept="image/*" name="hero" />
<input data-limbo-input-file data-accept=".pdf" name="terms" />
<input data-limbo-input-file data-accept="video/*" name="promo" />Atributos data-* soportados
| Atributo | Valores | Defecto | Descripción |
| ----------------------------------- | -------------------------------------------------------- | ------------------------ | ---------------------------------------------- |
| data-returntype | url, json, assetId, base64, object, fileName | json | Formato del valor devuelto al input |
| data-accept | Sintaxis HTML accept | null (todo) | Filtro de tipos de archivo |
| data-modeui | full, gallery-only, upload-only, crop-only | full | Modo funcional de la UI |
| data-mode | modal, embed | modal | Modo de renderizado |
| data-features | gallery,upload,cropper | gallery,upload,cropper | Features habilitadas (separadas por coma) |
| data-crop | free, 1:1, 16:9, 4:3, none | free | Ratio de recorte |
| data-quality | 0.0 - 1.0 | 0.9 | Calidad de salida |
| data-format | webp, jpg, png | webp | Formato de salida |
| data-modalsize | small, medium, large, fullscreen | fullscreen | Tamaño del modal |
| data-theme | light, dark | light | Tema visual |
| data-compact | true, false | false | Modo compacto |
| data-limbo-max-size | 5MB, 1024KB | 10MB | Tamaño máximo de archivo |
| data-limbo-formats | jpg,png,webp | jpg,jpeg,png,webp | Formatos permitidos (legacy) |
| data-limbo-min-width | Píxeles | null | Ancho mínimo de imagen |
| data-limbo-min-height | Píxeles | null | Alto mínimo de imagen |
| data-limbo-max-width | Píxeles | null | Ancho máximo de imagen |
| data-limbo-max-height | Píxeles | null | Alto máximo de imagen |
| data-limbo-button-text | Texto | Seleccionar archivo | Texto del botón |
| data-limbo-button-style | primary, secondary, outline, ghost | primary | Estilo del botón |
| data-limbo-button-class | Clase CSS | limbo-auto-button | Clase CSS adicional del botón |
| data-limbo-show-preview | true, false | true | Mostrar preview al seleccionar |
| data-limbo-auto-assign | true, false | true | Asignar valor al input automáticamente |
| data-limbo-required | true, false | false | Campo requerido |
| data-limbo-disabled | true, false | false | Input deshabilitado |
| data-mandatorycrops | JSON array | null | Recortes obligatorios |
| data-limbo-allow-additional-crops | true, false | true | Permitir recortes adicionales |
| data-limbo-max-crops | Número | null | Máximo de recortes seleccionables |
| data-limbo-allow-select-new | true, false | true | Permitir seleccionar nueva imagen en crop-only |
Eventos DOM de AutoInputs
// Resultado listo — se dispara en el input cuando se completa la selección
document.addEventListener("limbo:resultReady", (e) => {
const { input, value, imageData, config } = e.detail;
console.log(`Input "${input.name}" recibió:`, value);
});
// Compatibilidad con evento anterior
document.addEventListener("limbo:imageSelected", (e) => {
const { input, value, imageData } = e.detail;
});
// Errores
document.addEventListener("limbo:error", (e) => {
console.error("Error en input:", e.detail.error);
});Re-escaneo dinámico
Si añades inputs al DOM dinámicamente (SPA, AJAX), el MutationObserver los detecta automáticamente. También puedes forzar un re-escaneo:
// Re-escanear todo el documento
Limbo.rescan();
// Re-escanear un contenedor específico
Limbo.rescan(document.getElementById("formulario-dinamico"));
// Escanear y activar con selector personalizado
Limbo.scanAndActivate(".js-limbo-new");Métodos Prefab
Métodos de conveniencia para los casos de uso más comunes. Todos aceptan el parámetro accept para filtrar tipos.
Modales
Limbo.openGallery(options)
Abre la galería en modal para seleccionar un archivo existente.
// Galería de imágenes
Limbo.openGallery({
accept: "image/*",
onSelect: (data) => {
document.getElementById("preview").src = data.url;
},
});
// Galería de PDFs
Limbo.openGallery({
accept: ".pdf",
title: "Seleccionar documento",
onSelect: (data) => {
document.getElementById("pdf-link").href = data.url;
},
});
// Galería de cualquier tipo
Limbo.openGallery({
onSelect: (data) => console.log("Seleccionado:", data),
autoClose: true, // Cerrar modal al seleccionar (por defecto: true)
size: "large", // "small" | "medium" | "large" | "fullscreen"
});Limbo.openUploader(options)
Abre el uploader en modal para subir un archivo nuevo.
// Subir imagen y navegar a galería tras subida
Limbo.openUploader({
accept: "image/*",
redirectToGallery: true, // Muestra galería tras subida (por defecto: true)
onUpload: (data) => console.log("Subido:", data),
});
// Subir documento y cerrar inmediatamente
Limbo.openUploader({
accept: ".pdf,.docx",
redirectToGallery: false,
onUpload: (data) => {
console.log("Documento subido:", data);
},
});Limbo.openCropper(imageUrl, options)
Abre el recortador con una imagen externa (URL) para crear recortes.
// Recortar imagen con dimensiones obligatorias
Limbo.openCropper("https://example.com/foto.jpg", {
mandatoryCrops: [
{ label: "Desktop", width: 1920, height: 400, required: true },
{ label: "Mobile", width: 640, height: 300, required: true },
{ label: "Thumbnail", width: 300, height: 300, required: true },
],
onComplete: (data) => {
console.log("Recortes creados:", data.crops);
data.crops.forEach((crop) => {
console.log(`${crop.name}: ${crop.url} (${crop.width}x${crop.height})`);
});
},
onCancelled: () => console.log("Cancelado por el usuario"),
onError: (err) => console.error("Error:", err),
});
// Recorte libre
Limbo.openCropper("https://example.com/banner.jpg", {
allowCustomCrops: true,
onComplete: (data) => console.log("Recortes:", data.crops),
});Embebidos
Limbo.createInlineGallery(container, options)
Galería permanente embebida en un contenedor.
// Galería embebida de imágenes
const gallery = Limbo.createInlineGallery("#gallery-container", {
accept: "image/*",
onSelect: (data) => {
document.getElementById("selected-image").src = data.url;
},
onDelete: (assetId) => console.log("Eliminado:", assetId),
});Limbo.createInlineUploader(container, options)
Formulario de subida permanente embebido.
// Uploader embebido solo para PDFs
const uploader = Limbo.createInlineUploader("#upload-area", {
accept: ".pdf",
onUpload: (data) => console.log("PDF subido:", data),
});Limbo.createStandaloneCropper(container, imageUrl, options)
Recortador embebido para una imagen específica.
// Recortador embebido con recortes obligatorios
const cropper = Limbo.createStandaloneCropper(
"#cropper-container",
"https://example.com/imagen.jpg",
{
mandatoryCrops: [
{ label: "Avatar", width: 200, height: 200, required: true },
],
autoHideOnComplete: true,
onComplete: (data) => {
fetch("/api/save-avatar", {
method: "POST",
body: JSON.stringify({ url: data.crops[0].url }),
});
},
},
);Limbo.createFullSelector(container, options)
Selector completo con galería + subida + recortador.
// Selector completo embebido
const selector = Limbo.createFullSelector("#limbo-full", {
accept: "image/*,.pdf",
onSelect: (data) => console.log("Seleccionado:", data),
onUpload: (data) => console.log("Subido:", data),
onCropsSaved: (data) => console.log("Recortes:", data),
});Configuración de Instancias
Limbo.create(options) — Referencia completa
Limbo.create({
// ── Contenedor (requerido para modo embed) ──
container: "#limbo-gallery", // Selector CSS o elemento DOM
// ── Modo de renderizado ──
mode: "embed", // "embed" | "modal" | "button"
// ── Modo funcional ──
modeUI: "full", // "full" | "gallery-only" | "upload-only" | "crop-only" | "ia-only"
// ── Features habilitadas ──
features: ["gallery", "upload", "cropper"], // Tabs visibles
// ── Validación de archivos ──
validation: {
accept: null, // Filtro accept: "image/*", ".pdf", etc. (null = todo)
maxSize: "10MB", // Tamaño máximo por archivo
allowedCategories: null, // (legacy) ["image", "video", "document", "audio"]
},
// ── Configuración de galería ──
gallery: {
filters: {
showNameFilter: true,
showDateFilter: true,
showTypeFilter: false, // Dropdown de tipo de archivo
showUploadedByFilter: false,
},
loading: {
showPlaceholders: true,
placeholderCount: 10,
},
pagination: {
itemsPerPage: 20,
},
},
// ── Configuración de carpetas ──
folders: {
showFolderFilter: true, // Filtro de carpeta en galería
showFolderSelector: true, // Selector de carpeta en subida
showFolderInfo: true, // Badge de carpeta en tarjetas
allowMoveFolder: true, // Permitir mover archivos entre carpetas
allowCreateFolder: false, // Permitir crear carpetas nuevas
include: [], // Whitelist de slugs de carpeta
exclude: [], // Blacklist de slugs de carpeta
defaultFolder: null, // Carpeta por defecto para subidas
},
// ── Acciones permitidas ──
allowedActions: {
select: true,
download: true,
copy: true,
delete: true,
crop: true,
variants: true,
},
// ── Recortador ──
cropper: {
mandatoryCrops: [],
allowCustomCrops: true,
maxCrops: null,
quality: 0.9,
format: "webp",
},
// ── Modal (solo para mode: "modal") ──
modal: {
size: "fullscreen", // "small" | "medium" | "large" | "xlarge" | "fullscreen"
title: "Limbo - Gestor de Archivos",
closeOnEscape: true,
closeOnBackdrop: true,
},
// ── UI ──
ui: {
theme: "light", // "light" | "dark"
language: "es",
compactMode: false,
},
// ── Callbacks ──
callbacks: {
onSelect: (data) => {}, // Selección de archivo desde galería
onUpload: (data) => {}, // Archivo subido
onCropsSaved: (data) => {}, // Recortes guardados
onCropperComplete: (data) => {}, // Cropper standalone completado
onCropperCancelled: () => {}, // Cropper cancelado
onCropperError: (error) => {}, // Error en cropper
onDelete: (assetId) => {}, // Archivo eliminado
onClose: () => {}, // Modal cerrado
onError: (error) => {}, // Error general
},
});Sistema de Carpetas
El componente permite organizar archivos en carpetas configurables por portal.
En la galería
Limbo.create({
container: "#limbo",
mode: "embed",
modeUI: "full",
folders: {
showFolderFilter: true, // Dropdown de carpeta en filtros de galería
showFolderInfo: true, // Badge con nombre de carpeta en cada tarjeta
allowMoveFolder: true, // Acción de mover archivo a otra carpeta
allowCreateFolder: true, // Permitir crear carpetas al mover
include: ["productos", "marketing"], // Solo mostrar estas carpetas
// exclude: ["privado"], // O excluir estas
},
});En la subida
Limbo.create({
container: "#uploader",
mode: "embed",
modeUI: "upload-only",
folders: {
showFolderSelector: true,
allowCreateFolder: true,
defaultFolder: "marketing",
},
});Visualizadores
El componente incluye visualizadores nativos para cada tipo de archivo. Se abren automáticamente al hacer clic en una tarjeta de la galería.
| Tipo | Visualizador | Características |
| ----------------- | ---------------- | -------------------------------------------------------------------- |
| Imágenes | ImageViewer | Zoom con rueda, arrastrar para mover, doble clic para zoom, descarga |
| Vídeos | VideoViewer | Reproductor HTML5, play/pause con espacio, descarga |
| Audio | AudioViewer | Reproductor con timeline, progreso visual, tiempo transcurrido |
| PDF | PdfViewer | Iframe nativo del navegador con controles de zoom/página |
| Documentos Office | DocumentViewer | Información del archivo (tipo, tamaño) con botón de descarga |
| Texto / CSV | TextViewer | Renderizado inline del contenido con scroll |
Todos los visualizadores comparten el componente ViewerShell:
- Overlay oscuro a pantalla completa
- Cierre con tecla
ESCo clic en el fondo - Bloqueo de scroll del body
- Cabecera con nombre de archivo y acciones
- Botón de descarga directa
Tipos de archivo soportados
| Categoría | Extensiones | MIME Types |
| -------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| Imágenes | jpg, jpeg, png, gif, webp, svg | image/jpeg, image/png, image/gif, image/webp, image/svg+xml |
| Vídeos | mp4, webm, mov, avi, mkv | video/mp4, video/webm, video/quicktime, video/x-msvideo, video/x-matroska |
| Documentos | pdf, doc, docx, xls, xlsx, ppt, pptx, txt, csv | application/pdf, application/msword, application/vnd.openxmlformats-*, text/plain, text/csv |
| Audio | mp3, wav, ogg, aac, flac | audio/mpeg, audio/wav, audio/ogg, audio/aac, audio/flac |
GIFs
Los GIFs reciben un tratamiento especial:
- Backend: Se almacena el GIF original sin conversión a WebP (preserva la animación)
- Galería: Muestra thumbnail estático por defecto, anima al pasar el ratón (hover-to-animate)
- Visualizador: Reproduce la animación completa en ImageViewer
- Cropper: Deshabilitado para GIFs (no tiene sentido recortar animaciones)
Eventos DOM
// ── Eventos globales ──
// Archivo seleccionado desde galería
document.addEventListener("limbo:select", (e) => {
const { assetId, url, fileName, mime, width, height } = e.detail;
});
// Archivo subido
document.addEventListener("limbo:upload", (e) => {
const { assetId, url, fileName } = e.detail;
});
// Recortes guardados
document.addEventListener("limbo:cropsSaved", (e) => {
const { crops, assetId, instanceId } = e.detail;
crops.forEach((crop) =>
console.log(crop.name, crop.url, crop.width, crop.height),
);
});
// Cropper completado (modo crop-only)
document.addEventListener("limbo:cropperComplete", (e) => {
const { crops, instanceId } = e.detail;
});
// Cropper cancelado
document.addEventListener("limbo:cropperCancelled", (e) => {
console.log("Cancelado:", e.detail);
});
// Error
document.addEventListener("limbo:error", (e) => {
console.error("Error:", e.detail);
});
// ── Eventos de AutoInputs (se disparan en el input) ──
// Resultado asignado al input
myInput.addEventListener("limbo:resultReady", (e) => {
const { value, imageData, config } = e.detail;
});Personalización de Tema
Via JavaScript
Limbo.setTheme({
primary: "#2563eb",
secondary: "#64748b",
background: "#ffffff",
surface: "#f8fafc",
text: "#1e293b",
border: "#e2e8f0",
borderRadius: "8px",
});Via CSS
:root {
--lb-color-primary: #2563eb;
--lb-color-secondary: #64748b;
--lb-color-background: #ffffff;
--lb-color-surface: #f8fafc;
--lb-color-text: #1e293b;
--lb-color-border: #e2e8f0;
--lb-border-radius: 8px;
}Gestión de Instancias
// Crear instancia
const instance = Limbo.create({ container: "#limbo", mode: "modal" });
// Controlar instancia
instance.open(); // Abrir modal
instance.close(); // Cerrar modal
instance.mount(); // Montar componente (embed)
instance.unmount(); // Desmontar componente
instance.destroy(); // Destruir instancia y limpiar recursos
// Obtener todas las instancias activas
const instances = Limbo.getInstances();
// Destruir todo
Limbo.destroy();Arquitectura de Subida Diferida (v2.0+)
Las imágenes no se suben inmediatamente al seleccionarlas. Permanecen en memoria hasta que el usuario confirma en el recortador:
- Selección (Upload, IA, Stock, Portales) → Imagen en memoria como
File/Blob - Preview → Vista previa unificada con edición de nombre, descarte, descarga
- Recortador → Al clic en "Guardar" → se sube la imagen y se crean los recortes
- Cancelar → Descarta sin tocar el backend
Beneficios:
- No se desperdician subidas para imágenes descartadas
- UX más rápida (sin espera antes del recorte)
- Menor carga en el backend
Compatibilidad
| Requisito | Versión mínima | | ----------- | --------------------------------------------- | | React | 19.x (incluido en UMD) | | Navegadores | Chrome 90+, Firefox 90+, Safari 15+, Edge 90+ | | Node.js | 18+ (para bundlers) |
Formatos de distribución
| Formato | Archivo | Uso |
| --------- | ------------------------------- | ------------------------------------------------ |
| ESM | limbo.es.js | Bundlers modernos (Vite, Webpack 5+) |
| CJS | limbo.cjs.js | Node.js, Webpack legacy |
| UMD | limbo.umd.js / limbo.min.js | <script> directo en navegador (React incluido) |
| CSS | limbo.css | Estilos del componente (requerido) |
| Types | index.d.ts | Definiciones TypeScript |
Licencia
Proprietary © Lefebvre El Derecho S.A.
