Skip to content

FilePreview Component

A modal-based file preview component for displaying images, PDFs, and other file types. Supports both single and multiple file previews with navigation controls, keyboard shortcuts, and automatic file type detection.


Props

PropTypeDefaultDescription
showbooleanfalseControls the visibility of the preview modal
filesFileInput | FileInput[][]File(s) to preview - can be File objects, URLs, or image objects
initialIndexnumber0Index of the file to display initially (for multiple files)

FileInput Types

The files prop accepts multiple input formats:

typescript
// Image object format
type imageObject = {
  name: string; // Display name for the file
  url: string; // URL to the file
  type?: "image" | "pdf" | "other"; // Optional explicit type
  isBlob?: boolean; // If true, URL will be revoked on unmount
};

// Accepted types
type FileInput = imageObject | File | string;

Emits

EventParametersDescription
update:showbooleanEmitted when modal visibility changes
close-Emitted when the preview is closed

Features

Multi-Format Support

  • Images: Displays JPG, JPEG, PNG, GIF, WebP, SVG, and BMP files with proper scaling
  • PDFs: Renders PDF files in an embedded iframe viewer
  • Other Files: Shows file information with a "Preview in Browser" option

File Navigation

  • Arrow Buttons: Previous/Next navigation for multiple files
  • Keyboard Shortcuts: Use Left/Right arrow keys to navigate, Escape to close
  • Progress Indicator: Shows current position (e.g., "1 / 5")

Flexible Input Handling

  • File Objects: Direct JavaScript File objects from input elements
  • URL Strings: Direct URLs to files
  • Image Objects: Objects with name, URL, and optional type information
  • Mixed Arrays: Arrays containing any combination of the above

Memory Management

  • Automatically creates and revokes blob URLs for File objects
  • Properly cleans up resources on component unmount
  • Tracks blob URLs to prevent memory leaks

Usage Examples

Basic Usage with URL

vue
<script setup>
import { ref } from "vue";
import { FilePreview } from "dolphin-components";

const showPreview = ref(false);
const imageUrl = "https://example.com/image.jpg";
</script>

<template>
  <button @click="showPreview = true">Preview Image</button>

  <FilePreview v-model:show="showPreview" :files="imageUrl" />
</template>

Preview File Object from Input

vue
<script setup>
import { ref } from 'vue';
import { FilePreview } from 'dolphin-components';

const showPreview = ref(false);
const selectedFile = ref<File | null>(null);

const handleFileSelect = (event: Event) => {
  const target = event.target as HTMLInputElement;
  if (target.files?.[0]) {
    selectedFile.value = target.files[0];
    showPreview.value = true;
  }
};
</script>

<template>
  <input type="file" @change="handleFileSelect" accept="image/*,.pdf" />

  <FilePreview
    v-if="selectedFile"
    v-model:show="showPreview"
    :files="selectedFile"
  />
</template>

Multiple Files with Navigation

vue
<script setup>
import { ref } from 'vue';
import { FilePreview } from 'dolphin-components';

const showPreview = ref(false);
const previewIndex = ref(0);
const files = ref([
  { name: 'Document 1.pdf', url: '/files/doc1.pdf' },
  { name: 'Photo.jpg', url: '/images/photo.jpg' },
  { name: 'Report.pdf', url: '/files/report.pdf', type: 'pdf' }
]);

const openPreview = (index: number) => {
  previewIndex.value = index;
  showPreview.value = true;
};
</script>

<template>
  <div class="grid grid-cols-3 gap-4">
    <div
      v-for="(file, index) in files"
      :key="index"
      @click="openPreview(index)"
      class="cursor-pointer p-4 border rounded hover:bg-gray-50"
    >
      {{ file.name }}
    </div>
  </div>

  <FilePreview
    v-model:show="showPreview"
    :files="files"
    :initial-index="previewIndex"
  />
</template>

Preview with Close Handler

vue
<script setup>
import { ref } from "vue";
import { FilePreview } from "dolphin-components";

const showPreview = ref(false);
const currentImage = ref({
  name: "Profile Picture",
  url: "/images/avatar.png",
});

const handleClose = () => {
  console.log("Preview closed");
  // Perform cleanup or analytics
};
</script>

<template>
  <FilePreview
    v-model:show="showPreview"
    :files="currentImage"
    @close="handleClose"
  />
</template>

Integration with FileUpload Component

vue
<script setup>
import { ref } from 'vue';
import { FilePreview, FileUpload } from 'dolphin-components';

const uploadedFiles = ref<File[]>([]);
const showPreview = ref(false);
const previewIndex = ref(0);

const openPreview = (index: number) => {
  previewIndex.value = index;
  showPreview.value = true;
};
</script>

<template>
  <FileUpload v-model="uploadedFiles" :multiple="true" accept="image/*,.pdf" />

  <FilePreview
    v-model:show="showPreview"
    :files="uploadedFiles"
    :initial-index="previewIndex"
  />
</template>

Keyboard Shortcuts

KeyAction
(Left)Go to previous file
(Right)Go to next file
EscapeClose the preview modal

File Type Detection

The component automatically detects file types based on:

  1. MIME Type: When using File objects, the MIME type is checked first
  2. File Extension: Falls back to extension-based detection
  3. Explicit Type: Can be overridden using the type property in imageObject

Supported Extensions

CategoryExtensions
Imagejpg, jpeg, png, gif, webp, svg, bmp
PDFpdf
OtherAll other file types (with download/open option)

Internal Implementation Notes

Preview File Structure

typescript
interface PreviewFile {
  url: string; // URL for displaying the file
  name: string; // Display name
  type: "image" | "pdf" | "other"; // Detected file type
  isBlob: boolean; // Whether URL is a blob that needs cleanup
}

Blob URL Management

  • File objects are converted to blob URLs using URL.createObjectURL()
  • Blob URLs are automatically revoked when:
    • The component unmounts
    • The show prop changes to false
    • New files are provided (old blob URLs are cleaned up)

Best Practices

Usage Recommendations

  • Always use v-model:show for proper two-way binding
  • Provide meaningful name properties for image objects for better UX
  • Use initialIndex when opening specific files from a list
  • Handle the close event for any cleanup operations

Performance Considerations

  • Avoid passing very large arrays of files simultaneously
  • For large images, consider using optimized/compressed versions
  • PDFs are loaded in iframes - large PDFs may take time to render

Memory Management

  • The component handles blob URL cleanup automatically
  • For custom implementations, remember to revoke blob URLs manually

Common Use Cases

  • Document Viewers: Preview uploaded documents before submission
  • Image Galleries: Browse through multiple images with navigation
  • File Managers: Quick preview of files in a file management system
  • Form Attachments: Preview attached files in forms before saving
  • Media Libraries: Browse and preview media assets