npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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.

npm version License: Proprietary


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 modosembed, modal, button · full, gallery-only, upload-only, crop-only, ia-only
  • AutoInputs — Integración automática con formularios HTML existentes
  • Métodos prefabopenGallery(), 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-component

CDN (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 tokenProvider o manual. 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/*,.pdf

El 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 ESC o 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:

  1. Selección (Upload, IA, Stock, Portales) → Imagen en memoria como File/Blob
  2. Preview → Vista previa unificada con edición de nombre, descarte, descarga
  3. Recortador → Al clic en "Guardar" → se sube la imagen y se crean los recortes
  4. 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.

Links