Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified components/.DS_Store
Binary file not shown.
86 changes: 86 additions & 0 deletions components/global-file-viewer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
## Username

widlestudiollp

## Project Name

Smart File Viewer

## About

Smart File Viewer is an intelligent, auto-detecting file viewer component for Retool that supports multiple file formats and input sources. It automatically detects the file type and renders it using the appropriate viewer without requiring manual configuration.

The component supports files from uploads, URLs (including Google Drive/Docs), and Base64 strings. It provides a seamless experience for previewing documents, media, and structured data directly inside Retool apps.

## Preview

![Smart File Viewer Preview](cover.png)

## How it works

The component receives input via a text field (URL/Base64) or file upload. It then processes the input using a detection engine that determines the file type based on MIME type, file extension, or Base64 signature.

### File detection logic

* Base64 prefix → Determines MIME type (PDF, Image, etc.)
* File extension → Fallback detection (`.docx`, `.xlsx`, `.csv`, etc.)
* Google URLs → Converted into embeddable preview links
* Blob conversion → Ensures consistent rendering across formats

### Rendering logic

* PDF → Rendered using `react-pdf` with pagination
* Word → Converted to HTML using `mammoth`
* Excel → Parsed into table using `xlsx`
* CSV → Custom parser → table view
* JSON → Structured table
* Text → Code-style preview
* Image → Responsive image preview
* Video → Native HTML5 player
* Google Docs/Drive → Embedded iframe preview

### Example input

```json
[
{ "name": "Smith", "role": "Developer" },
{ "name": "John", "role": "Designer" }
]
```

Or Base64:

```
data:application/pdf;base64,JVBERi0xLjQKJ...
```

Or URL:

```
https://drive.google.com/file/d/FILE_ID/view
```

## Build process

The component is built using React and integrates with Retool through `@tryretool/custom-component-support`. It uses multiple libraries for handling different file types and rendering them efficiently.

### Key implementation details

* Uses `useMemo` for optimized file type detection
* Uses `useEffect` for async file loading and parsing
* Converts files to Blob URLs for consistent rendering
* Handles Google Drive/Docs links via URL transformation
* Implements custom parsers for CSV and JSON
* Supports dynamic container resizing using `ResizeObserver`
* Includes proper cleanup for Blob URLs to prevent memory leaks

### Extensibility

The component is designed to be flexible and extensible. Developers can:

* Add support for additional file types (e.g., audio, markdown)
* Replace Word rendering engine for better fidelity
* Add drag-and-drop upload support
* Extend parsing logic for large datasets
* Customize UI themes and controls
* Add caching or file size optimizations
Binary file added components/global-file-viewer/cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions components/global-file-viewer/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"id": "smart-file-viewer",
"title": "Smart File Viewer",
"author": "@widlestudiollp",
"shortDescription": "An intelligent auto-detect file viewer component that supports multiple file formats (PDF, Word, Excel, CSV, JSON, media) from uploads, URLs, and Base64, rendering them with the appropriate viewer automatically.",
"tags": ["File Viewer", "Document Viewer", "Auto Detection", "PDF", "Media", "Data Preview"]
}
53 changes: 53 additions & 0 deletions components/global-file-viewer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"name": "my-react-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@tryretool/custom-component-support": "latest",
"dompurify": "^3.3.3",
"mammoth": "^1.12.0",
"papaparse": "^5.5.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-pdf": "^10.4.1",
"xlsx": "^0.18.5"
},
"engines": {
"node": ">=20.0.0"
},
"scripts": {
"dev": "npx retool-ccl dev",
"deploy": "npx retool-ccl deploy",
"test": "vitest"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/papaparse": "^5.5.2",
"@types/react": "^18.2.55",
"@typescript-eslint/eslint-plugin": "^7.3.1",
"@typescript-eslint/parser": "^7.3.1",
"eslint": "^8.57.0",
"eslint-plugin-react": "^7.34.1",
"postcss-modules": "^6.0.0",
"prettier": "^3.0.3",
"vitest": "^4.0.17"
},
"retoolCustomComponentLibraryConfig": {
"name": "FileViewerComponent",
"label": "File viewer component",
"description": "A file viewer component.",
"entryPoint": "src/index.tsx",
"outputPath": "dist"
}
}
Loading
Loading