Dialog File Preview para Quasar
🇬🇧 English version | 🇧🇷 Versão em português
Extensión Quasar para previsualizar archivos en un diálogo modal en apps Vue 3 + Quasar, con API imperativa basada en composable.
Tabla de contenidos
- En 30 segundos
- Qué es y qué incluye
- Requisitos y compatibilidad
- Instalación en app Quasar
- Qué agrega la extensión al host
- Defaults globales (boot)
- Idioma (i18n)
- Uso rápido
- TypeScript en tu IDE
- API pública
- Opciones de sesión (
PreviewSessionOptions) - Límites de tamaño para vista previa
- Fuentes de archivo aceptadas
- Tipos de archivo soportados
- Tipos TypeScript exportados
- Utilidades MIME
- Extensiones opcionales relacionadas
- Entrypoints públicos
- Troubleshooting
En 30 segundos
Flujo base recomendado:
- Instalar la extensión en tu app Quasar (
quasar ext add). - Asegurar que el boot de Pinia del host corre antes que el boot de esta extensión.
- Importar
useDialogFilePreview()donde necesites abrir la vista previa. - Llamar
void preview.show(archivo)— el diálogo se monta globalmente; no hace falta añadir componentes a tus plantillas.
La extensión registra boots y CSS en el proyecto host automáticamente tras quasar ext add.
Qué es y qué incluye
Diálogo modal global controlado por useDialogFilePreview() — no es un componente embebible.
show()/hide()/canPreview();File,Blob, URL u objeto descriptor; galería multi-archivo.- Visores: imagen (zoom), PDF adaptativo, video, audio, texto; fallback + descarga.
- Opciones de sesión en
show(input, options); defaults globales en boot. - i18n integrado
en,es,pt— sigue$q.langde Quasar; overrides en boot (locale,messages). canPreview()síncrono (MIME + tamaño local);show()puede sondear URLs remotas.- Integración opcional con Form Builder (
InputFile/showPreview).
Requisitos y compatibilidad
| Item | Valor |
|---|---|
| Node | >= 20.0.0 |
| Quasar | ^2.6.0 |
| Vue | ^3.4.18 |
| Pinia | ^2.0.11 | ^3.0.0 |
| Formato del paquete | ES modules |
| CLI recomendado | @quasar/app-vite ^2.x o ^3.x |
| PDF en el paquete | vue-pdf-embed / pdf.js incluidos (sin dependencia extra en el host) |
El boot de Pinia del host debe ejecutarse antes del boot de esta extensión.
Instalación en app Quasar
Agregar la extensión en tu app Quasar:
quasar ext add @benjaminor-dev/dialog-file-preview
Remover:
quasar ext remove @benjaminor-dev/dialog-file-preview
Tras quasar ext add, la extensión registra boots y CSS en tu app automáticamente. No necesitas pasos adicionales en una instalación normal desde npm.
Qué agrega la extensión al host
Recursos que instala o registra la extensión:
| Recurso | Ruta npm |
|---|---|
| Boot del diálogo | ~@benjaminor-dev/quasar-app-extension-dialog-file-preview/boot/dialog |
| Estilos | ~@benjaminor-dev/quasar-app-extension-dialog-file-preview/main.css |
| Defaults boot (host) | src/boot/bor/bor-dialog-file-preview-defaults.ts — creado en install; Skip/Overwrite si ya existe |
Install (quasar ext add / invoke): crea src/boot/bor/bor-dialog-file-preview-defaults.ts (o .js) y lo registra en quasar.config → boot: [] automáticamente. No hace falta editarlo a mano en una instalación normal. El boot de paquete (boot/dialog) y main.css los inyecta la extensión en cada dev/build (no aparecen como entradas cortas en quasar.config).
Remove (quasar ext remove): elimina el defaults boot y su entrada en quasar.config.
Orden de boots (esta extensión): Pinia → boot dialog DFP → bor/bor-dialog-file-preview-defaults → resto. En quasar.config verás bor/bor-dialog-file-preview-defaults; el boot boot/dialog lo añade el runner al compilar.
El boot monta el diálogo en el documento y conecta la store de Pinia del host. No necesitas importar DialogFilePreview en App.vue.
Defaults globales (boot)
Evita repetir showPrint / restrictInteraction en cada show(). Prioridad: show(input, options) → boot (configureDialogFilePreviewDefaults) → built-in.
Tras quasar ext add, revisa src/boot/bor/bor-dialog-file-preview-defaults.ts — plantilla con todas las opciones boot (// recomendado: …). El boot no admite title ni forcePreview — esas opciones van solo en show(input, options).
// src/boot/bor/bor-dialog-file-preview-defaults.ts
import { configureDialogFilePreviewDefaults } from "@benjaminor-dev/quasar-app-extension-dialog-file-preview";
configureDialogFilePreviewDefaults({
showPrint: false,
restrictInteraction: true,
});
configureDialogFilePreview es alias de configureDialogFilePreviewDefaults.
Idioma (i18n)
Integrado en, es y pt. Por defecto etiquetas de toolbar, tooltips, controles PDF y mensajes fallback siguen el idioma de Quasar ($q.lang.isoName); si Quasar no tiene idioma, fallback en.
Resolución de locale: boot locale → prefijo de $q.lang.isoName (es* → es, pt* → pt) → en.
| Opción | Cuándo usarla |
|---|---|
locale: 'es' en boot |
Fijar idioma (en | es | pt); ignora cambios de $q.lang |
messages: { download: '…' } |
Cambiar un texto sin fijar locale |
Ejemplo en quasar.config (español para toda la app):
framework: {
lang: "es",
},
Plantilla boot (tras install):
configureDialogFilePreviewDefaults({
// locale: "es", // descomenta para fijar solo el idioma de Dialog File Preview
showPrint: true,
});
Override de un solo string:
configureDialogFilePreviewDefaults({
messages: { loadingFile: "Abriendo archivo…" },
});
Uso rápido
<script setup lang="ts">
import { useDialogFilePreview } from "@benjaminor-dev/quasar-app-extension-dialog-file-preview";
const preview = useDialogFilePreview();
function onViewPdf(file: File) {
if (preview.canPreview(file)) {
void preview.show(file);
}
}
</script>
<template>
<q-btn label="Ver PDF" @click="onViewPdf(selectedFile)" />
</template>
Varios archivos (galería o adjuntos):
void preview.show([imageFile, pdfFile, anotherImage]);
URL remota con nombre explícito:
void preview.show({
source:
"https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf",
name: "tracemonkey-pldi-09.pdf",
mimeType: "application/pdf",
});
TypeScript en tu IDE
El composable expone una API tipada: úsala con autocompletado en lugar de adivinar opciones.
useDialogFilePreview()devuelveDialogFilePreviewApi— métodos y refs aparecen al escribirpreview..- En
show(archivo, opciones), el segundo argumento esPreviewSessionOptions: Ctrl+Space (Windows/Linux) o Cmd+Space (macOS) listashowPrint,showDownload,restrictInteraction,forcePreview, etc. - Descriptores tipados:
PreviewItemInput,PreviewSourceInputen el entrypoint principal o/types. titleyforcePreviewvan solo enshow()— no enconfigureDialogFilePreviewDefaults(el boot usaDialogFilePreviewDefaults, más acotado).- En boot,
localeacepta"en" \| "es" \| "pt";messagesaceptaDialogFilePreviewMessagesparcial (toolbar, PDF, fallback). - Pasa el cursor sobre un método: el tooltip muestra parámetros y JSDoc.
Para comprobar si un archivo se puede previsualizar antes de abrir el modal, canPreview() también está tipado según la fuente que pases.
API pública
Punto de entrada: useDialogFilePreview().
import { useDialogFilePreview } from "@benjaminor-dev/quasar-app-extension-dialog-file-preview";
const preview = useDialogFilePreview();
Métodos
| Método | Descripción |
|---|---|
show(input, options?) |
Abre el diálogo de inmediato y devuelve una Promise que resuelve cuando terminó la normalización/sondeo MIME de las fuentes. El segundo argumento options configura la sesión (toolbar, título, restricciones, forcePreview). Por defecto, archivos locales que superan el límite de tamaño abren en modo fallback (mensaje + descarga); ver forcePreview para forzar el visor embebido. Mientras tanto, y hasta que el visor emita estado listo, el viewport muestra «Cargando archivo...». |
hide() |
Cierra el diálogo y libera URLs blob: creadas por la extensión. |
next() |
Siguiente archivo (si hay varios). |
previous() |
Archivo anterior. |
downloadCurrent() |
Descarga el archivo visible (desde File/Blob o enlace si solo hay URL). |
canPreview(source) |
true si el MIME tiene visor en el diálogo y el archivo local no supera el límite de tamaño. Evaluación síncrona (sin sondeo remoto). |
canPreviewAll(sources) |
true si todos los ítems del arreglo son previsualizables (también síncrono). |
Estado reactivo (solo lectura)
| Ref | Descripción |
|---|---|
visible |
Si el diálogo está abierto. |
current |
Metadatos del ítem actual (PreviewItem) o null. |
hasPrevious / hasNext |
Navegación en listas multi-archivo. |
hasMultiple |
Hay más de un archivo en la sesión actual. |
Usa canPreview() para mostrar u ocultar botones «Ver» en tu UI sin abrir el diálogo. Si la URL no tiene extensión ni MIME conocido, pasa mimeType en el descriptor o llama show() directamente (el sondeo remoto ocurre al abrir, no en canPreview). Si el archivo local supera el límite de tamaño, canPreview() devuelve false aunque el MIME sea válido; show() muestra fallback salvo que pases forcePreview: true (bajo tu responsabilidad).
Comportamiento al abrir (show)
- El diálogo se hace visible al instante.
- Un único overlay de carga cubre el viewport (fondo oscuro, spinner blanco, «Cargando archivo...») mientras:
- se enriquecen las fuentes (
File/Blob/URL → ítems con MIME y URL de visualización), y - el visor del ítem actual termina su carga visible (en PDF: primer render del canvas, no solo metadatos del documento).
- se enriquecen las fuentes (
- Los botones imprimir y descargar en la toolbar aparecen solo cuando el visor emite estado listo (
ready) y la opción de sesión correspondiente está activa (showPrint/showDownload). - Imprimir solo se ofrece para PDF, imágenes y texto; video y audio no muestran el botón aunque
showPrintseatrue. - Al cambiar de archivo en una galería (
next/previous), el loader vuelve hasta que el nuevo visor esté listo. - Al imprimir (botón o Ctrl/Cmd+P), si la preparación del iframe/PDF tarda, el mismo overlay muestra «Preparando impresión...» tras ~250 ms y se oculta en el instante en que aparece el diálogo del sistema (no espera a que confirmes o canceles).
El estado interno de preparación no se expone en useDialogFilePreview(); basta con visible y la UX del overlay.
Opciones de sesión (PreviewSessionOptions)
Segundo argumento opcional de show(). Aplica a toda la sesión del diálogo (incluida la galería multi-archivo).
import type { PreviewSessionOptions } from "@benjaminor-dev/quasar-app-extension-dialog-file-preview";
void preview.show(confidentialPdf, {
showPrint: false,
showDownload: true,
restrictInteraction: true,
title: "Contrato confidencial",
});
void preview.show([scan1, scan2], {
showGalleryNav: true,
showPdfZoom: false,
});
// Forzar visor embebido aunque supere el límite de tamaño (riesgo de rendimiento / crash)
void preview.show(heavyLocalPdf, { forcePreview: true });
| Opción | Default | Descripción |
|---|---|---|
showPrint |
true |
Muestra el botón imprimir cuando el tipo lo permite (PDF, imagen, texto). |
showDownload |
true |
Muestra el botón descargar en la toolbar. |
showGalleryNav |
true |
Muestra navegación anterior/siguiente si hay varios archivos. |
showPdfZoom |
true |
Muestra «Zoom: N%» en la toolbar para PDF. |
title |
nombre del archivo | Título centrado en la toolbar. |
restrictInteraction |
false |
Bloquea copiar, cortar, seleccionar, menú contextual y atajos comunes en el visor. No evita capturas de pantalla ni herramientas avanzadas del navegador. |
forcePreview |
false |
Omite el límite de tamaño y abre el visor embebido aunque canPreview() sea false por tamaño. Responsabilidad del desarrollador: archivos muy grandes pueden ralentizar la UI, congelar la pestaña o cerrar el navegador. No cambia el resultado de canPreview(). |
Si omites options, se usan los valores por defecto de la tabla.
Límites de tamaño para vista previa
Para File / Blob con .size conocido, la extensión aplica un tope antes de usar el visor embebido. Los mismos límites usan canPreview() y show() por defecto.
| Visor | MIME / categoría | Límite |
|---|---|---|
| Imagen | image/* |
50 MB |
application/pdf |
100 MB | |
| Video | video/mp4, video/webm, video/ogg |
150 MB |
| Audio | audio/mpeg, audio/wav, audio/ogg, audio/webm |
50 MB |
| Texto | text/plain, text/csv, application/json, application/xml, text/xml |
10 MB |
Constante exportada: PREVIEW_MAX_BYTES_BY_KIND (bytes por tipo de visor).
Comportamiento:
canPreview(file)→falsesi el MIME es válido pero el tamaño supera el límite.show(file)(por defecto) → diálogo con mensaje de archivo demasiado grande, tamaño formateado y botón de descarga.show(file, { forcePreview: true })→ intenta el visor embebido igualmente. Úsalo solo si aceptas el riesgo de rendimiento o cierre del navegador; no alteracanPreview().- URLs remotas sin tamaño conocido: no se bloquean por tamaño en esta comprobación síncrona (el sondeo MIME al abrir no incluye
Content-Lengthde forma fiable en todos los casos).
Fuentes de archivo aceptadas
Tipo unificado PreviewSourceInput:
| Forma | Ejemplo |
|---|---|
File |
Archivo de <input type="file"> o new File(...) |
Blob |
Blob de API o canvas |
string |
URL https://... o blob:... |
| Objeto descriptor | Ver abajo |
// File o Blob directo
void preview.show(file);
void preview.show([imageFile, pdfFile]);
// URL con metadatos explícitos (recomendado sin extensión clara)
void preview.show({
source: "https://ejemplo.com/documento",
name: "contrato.pdf",
mimeType: "application/pdf",
});
// Descriptor con File
void preview.show({
source: selectedFile,
name: "anexo-renombrado.pdf",
});
| Situación | Qué hacer |
|---|---|
File / Blob |
Nombre y MIME se infieren del objeto |
| URL sin extensión | Pasa name y mimeType en el descriptor |
| URL remota al abrir | Puede sondearse (HEAD/GET parcial) para inferir MIME |
canPreview() devuelve false (MIME) |
Evalúa de forma síncrona; con mimeType explícito o tras sondeo, show() puede abrir igual (o fallback si el tipo no tiene visor) |
canPreview() devuelve false (tamaño) |
El File/Blob supera el límite de tamaño. show() abre fallback con descarga; usa { forcePreview: true } solo si asumes el riesgo de rendimiento |
URLs blob: externas |
La extensión no las revoca; solo libera las que crea desde File/Blob |
Tipos de archivo soportados
| Categoría | MIME / prefijos | Visor en el diálogo | Imprimible |
|---|---|---|---|
| Imágenes | image/* |
Imagen centrada y contenida en el viewport; clic para zoom ×2 con pan; sin scroll en el área del visor | Sí |
application/pdf |
pdf.js (vue-pdf-embed): modo adaptativo (ver abajo); barra de página con salto directo, zoom y capas de texto/anotaciones |
Sí | |
| Video | video/mp4, video/webm, video/ogg |
<video controls> |
No |
| Audio | audio/mpeg, audio/wav, audio/ogg, audio/webm |
<audio controls> con icono central y ecualizador al reproducir |
No |
| Texto | text/plain, text/csv, application/json, application/xml, text/xml |
Texto monoespaciado con scroll | Sí |
| Otros | — | Mensaje + botón descargar | No |
Si el MIME no tiene visor, show() igual puede abrir el diálogo en modo fallback para permitir la descarga.
Visor de imágenes
- La imagen se escala para caber en el área visible sin recortes.
- Clic sobre la imagen: zoom ×2 anclado al punto del cursor; mueve el ratón para desplazar la vista ampliada.
- Clic de nuevo (o fuera de la imagen en modo zoom): vuelve al ajuste inicial.
- El cursor indica
zoom-in/zoom-outsolo sobre la imagen.
Visor de PDF (modo adaptativo)
El visor elige automáticamente entre dos presentaciones según el tamaño del documento:
| Modo | Cuándo | Experiencia |
|---|---|---|
| Scroll continuo | Archivo ligero (típicamente ≤ 25 MB, ≤ 40 páginas) | Todas las páginas en columna con separación; scroll vertical; la barra inferior sigue la página visible |
| Paginado | Archivo pesado o muchas páginas | Una página a la vez (adecuado para PDFs muy grandes) |
En ambos modos:
- Barra inferior: primera / anterior / campo numérico / total / siguiente / última.
- El campo de página acepta solo dígitos, limita el valor al rango
1…total, selecciona todo al enfocar y confirma con Enter o al salir del campo (blur). - Los botones y el salto directo posicionan la vista (scroll suave en modo continuo).
- Zoom con botones ± (40–100 %) o Ctrl/Cmd + rueda / Ctrl/Cmd + +/-; el porcentaje aparece en la toolbar si
showPdfZoomno esfalse. - Enlaces internos del PDF navegan a la página correspondiente.
No hay opción pública para forzar un modo: la heurística protege al navegador ante documentos enormes (p. ej. cientos de MB o miles de páginas).
Tipos TypeScript exportados
Desde el entrypoint principal:
import type {
DialogFilePreviewApi,
DialogFilePreviewDefaults,
PreviewBlockReason,
PreviewSourceInput,
PreviewItemInput,
PreviewItem,
PreviewKind,
PreviewSessionOptions,
} from "@benjaminor-dev/quasar-app-extension-dialog-file-preview";
| Tipo | Uso |
|---|---|
DialogFilePreviewApi |
Tipo de retorno de useDialogFilePreview() |
DialogFilePreviewDefaults |
Opciones admitidas en configureDialogFilePreviewDefaults (boot) |
PreviewBlockReason |
Motivo de bloqueo por tamaño ("size", etc.) |
PreviewSourceInput |
Primer argumento de show() y argumento de canPreview() |
PreviewSessionOptions |
Segundo argumento opcional de show() |
PreviewItemInput |
Descriptor con metadatos opcionales |
PreviewItem |
Ítem normalizado del estado reactivo (current); incluye blockedReason: PreviewBlockReason | null cuando aplica |
PreviewKind |
"image" | "pdf" | "video" | "audio" | "text" | "unknown" |
type PreviewItemInput = {
source: File | Blob | string;
name?: string;
mimeType?: string;
};
Utilidades MIME
También se exportan para validar en tu UI sin abrir el diálogo:
import {
isPreviewableMime,
PREVIEWABLE_MIME_PREFIXES,
} from "@benjaminor-dev/quasar-app-extension-dialog-file-preview";
if (isPreviewableMime(file.type)) {
// mostrar botón de vista previa
}
Valores de PREVIEWABLE_MIME_PREFIXES (prefijo con / = familia completa; resto = MIME exacto):
| Entrada | Categoría |
|---|---|
image/ |
Imágenes |
application/pdf |
|
video/mp4, video/webm, video/ogg |
Video |
audio/mpeg, audio/wav, audio/ogg, audio/webm |
Audio |
text/plain, text/csv, application/json, application/xml, text/xml |
Texto |
Extensiones opcionales relacionadas
| Extensión | Propósito | Relación con Dialog File Preview |
|---|---|---|
| @benjaminor-dev/form-builder | Formularios declarativos con defineForm y FormBuilder |
InputFile e InputFileMultiple detectan esta extensión cuando showPreview no es false (default true): botones ver/descargar en el append o en la tabla de gestión. No es dependencia de Dialog File Preview |
Si usas ambas en el host:
quasar ext add @benjaminor-dev/form-builder
quasar ext add @benjaminor-dev/dialog-file-preview
Orden de boots (stack completo):
1. Pinia (host)
2. Form Builder — boot/store
3. bor/bor-form-builder-defaults (host)
4. Table Builder — boot/store
5. bor/bor-table-builder-defaults (host)
6. Dialog File Preview — boot/dialog
7. bor/bor-dialog-file-preview-defaults (host)
8. Dialog Loader — boot/dialog
9. bor/bor-dialog-loader-defaults (host)
10. Dialog Message — boot/dialog
11. bor/bor-dialog-message-defaults (host)
En quasar.config verás el defaults boot de cada extensión (p. ej. bor/bor-dialog-file-preview-defaults); los boots del paquete los inyecta la extensión al compilar — no aparecen como entradas cortas en tu config.
Uso manual desde un callback o botón custom (sin depender de Form Builder):
<script setup lang="ts">
import { useDialogFilePreview } from "@benjaminor-dev/quasar-app-extension-dialog-file-preview";
const preview = useDialogFilePreview();
function onPreviewFile(file: File) {
void preview.show(file);
}
</script>
El boot también expone la API vía provide (DIALOG_FILE_PREVIEW_API_KEY) para integraciones de librerías hermanas — misma instancia que useDialogFilePreview().
Entrypoints públicos
| Entrypoint | Propósito |
|---|---|
@benjaminor-dev/quasar-app-extension-dialog-file-preview |
useDialogFilePreview, configureDialogFilePreviewDefaults, i18n (resolveDialogFilePreviewMessages, resolveExtensionLocale), utilidades MIME — tipos en IDE (PreviewSessionOptions, DialogFilePreviewDefaults, DialogFilePreviewMessages, …) |
@benjaminor-dev/quasar-app-extension-dialog-file-preview/boot/dialog |
Boot Quasar (registrado automáticamente por la extensión) |
@benjaminor-dev/quasar-app-extension-dialog-file-preview/main.css |
Estilos del diálogo (registrado automáticamente) |
Troubleshooting
Los textos de la UI siguen en inglés
- Configura
framework.langenquasar.config(p. ej."es") o llama$q.lang.set()en runtime. - O fija la extensión:
configureDialogFilePreviewDefaults({ locale: "es" })ensrc/boot/bor/bor-dialog-file-preview-defaults.ts.
Boots o estilos no aparecen en quasar.config
En condiciones normales el install registra el defaults boot en boot: [] y el runner inyecta boot/dialog + CSS al compilar. Si falta el defaults boot (proyecto antiguo):
npx quasar ext invoke @benjaminor-dev/dialog-file-preview
Error: Pinia no inicializada / store no disponible
- Verifica que exista un boot de Pinia en el host (
app.use(pinia)o equivalente). - En
quasar.config, el boot de Pinia debe ir antes que el bootdialogde esta extensión.
useDialogFilePreview() fuera de setup
Llámalo dentro de setup, otro composable o <script setup>. Si necesitas usarlo fuera del contexto de componente, asegúrate de que el boot de la extensión ya se ejecutó (app montada).
El botón «Ver» no debería mostrarse
Usa preview.canPreview(file) antes de renderizar la acción. Devuelve false si el MIME no tiene visor o si el archivo local supera el límite de tamaño. isPreviewableMime() solo evalúa MIME, no tamaño.
canPreview() devuelve false por tamaño
El archivo local supera el límite de su tipo (p. ej. imagen > 50 MB). Por defecto show(file) abre fallback con descarga. Para forzar el visor embebido: show(file, { forcePreview: true }) — bajo tu responsabilidad (rendimiento, pestaña congelada o cierre del navegador). canPreview() seguirá siendo false.
canPreview() devuelve false en una URL sin extensión
canPreview() no hace sondeo remoto. Si la URL no tiene extensión ni heurística conocida, pasa mimeType en el descriptor o llama show() directamente.
PDF muy grande: solo veo una página a la vez
Es el comportamiento esperado en modo paginado: archivos por encima de ~25 MB, con más de 40 páginas, o documentos largos sin tamaño conocido (> 15 páginas) se renderizan de una en una para no saturar memoria del navegador. Usa la barra de páginas para navegar.
El contador de página del PDF no cambia al hacer scroll
En modo continuo con zoom alto (≥ 90 %), espera un instante al detener el scroll; el contador sigue la página con mayor área visible. Si el documento entró en modo paginado, el scroll del viewport no aplica — usa los botones de página.
PDF o texto desde URL externa no carga
- CORS: el servidor debe permitir
fetchdesde tu origen (PDF remoto se descarga como blob antes de renderizar). - Pasa
mimeTypeexplícito si la URL no tiene extensión. - Verifica que la URL responda 200 (enlaces rotos muestran el error en el visor).
- Para dominios sin CORS, descarga en tu backend y pasa un
File/Bloblocal.
Ejemplo de URL pública que funciona en pruebas:
preview.show({
source:
"https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf",
name: "tracemonkey-pldi-09.pdf",
mimeType: "application/pdf",
});
El botón de descarga no aparece al abrir
Es esperado al inicio: la descarga en la toolbar solo se habilita cuando el visor emite estado listo (ready) y showDownload no es false. Mientras prepara fuentes o carga PDF/imagen/texto verás «Cargando archivo...» en el viewport. Si el loader no desaparece, revisa errores de red/CORS en la consola.
No aparece el botón imprimir
- Comprueba que
showPrintno seafalseen las opciones de sesión. - Solo PDF, imágenes y texto son imprimibles; en video/audio el botón no se muestra.
- Igual que la descarga, requiere estado listo (
ready) del visor.
El loader de impresión tarda o no aparece
- Texto e imagen ya en caché suelen abrir el diálogo al instante sin overlay (comportamiento esperado).
- PDF o imagen remota pueden mostrar «Preparando impresión...» mientras se prepara el iframe; el overlay se quita en cuanto abre la ventana de impresión del navegador, no al pulsar Imprimir o Cancelar en ese diálogo.
restrictInteraction no bloquea todo
La opción reduce copia, selección y menú contextual en el visor, pero no sustituye DRM ni impide capturas de pantalla. Un usuario con conocimientos técnicos puede seguir accediendo al contenido.
El diálogo abre vacío un instante o tarda en mostrar el archivo
show() abre el modal de inmediato y normaliza las fuentes en segundo plano. Con URLs remotas o varios archivos, el overlay puede permanecer unos segundos; no indica fallo por sí solo.
La vista previa de imagen/PDF funciona en local pero no en producción
Revisa que la extensión esté instalada/invocada en el build de producción y que main.css de la extensión esté en la config generada.
Varios archivos: no aparece navegación
Pasa un arreglo a show([...]). La barra anterior/siguiente solo se muestra cuando hay más de un ítem y showGalleryNav no es false.
MIT © Benjamín Olvera R.