enri-file-management
v0.0.5
Published
Angular library for file management and visualization
Maintainers
Readme
enri-file-management
Angular library for file management and visualization
🎯 Features
- 📁 File Picker with drag & drop support
- 🖼️ Smart Preview for images, PDFs, documents, text files, and videos
- 🎥 Video Player with custom controls (play/pause, volume, speed, fullscreen)
- 📄 PDF Viewer with native rendering (zoom, download, fullscreen)
- 🎨 Fully Customizable via CSS Variables (50+ variables)
- 🏗️ Clean Architecture design with separation of concerns
- 🧩 Composable Components for maximum flexibility
- 📦 Tree-shakeable and lightweight
- ♿ Accessible (WCAG 2.1 AA compliant)
- 🌍 i18n ready
- 🔧 Extensible - add custom file renderers
📦 Installation
npm install enri-file-management🚀 Quick Start
1. Import the module
import { NgModule } from '@angular/core';
import { EnriFileManagementModule } from 'enri-file-management';
@NgModule({
imports: [EnriFileManagementModule],
})
export class AppModule { }2. Import styles (optional but recommended)
In your styles.scss:
@import 'enri-file-management/styles/enri-file-management';3. Use the components
import { Component } from '@angular/core';
import { FileData } from 'enri-file-management';
@Component({
selector: 'app-demo',
template: `
<enri-file-picker
[accept]="'image/*'"
[multiple]="true"
(filesSelected)="onFilesSelected($event)">
</enri-file-picker>
<enri-file-preview
[file]="selectedFile"
[state]="previewState">
</enri-file-preview>
`
})
export class DemoComponent {
selectedFile: FileData | null = null;
previewState: 'idle' | 'loading' | 'ready' | 'error' = 'idle';
onFilesSelected(files: FileData[]): void {
this.selectedFile = files[0];
this.previewState = 'ready';
}
}📖 Components
<enri-file-picker>
File selection component with drag & drop support.
Inputs:
accept: string- Accepted file types (MIME types or extensions)multiple: boolean- Allow multiple file selectiondisabled: boolean- Disable the pickermaxFileSize: number- Maximum file size in bytesallowedTypes: string[]- Allowed MIME typesallowedExtensions: string[]- Allowed file extensions
Outputs:
filesSelected: EventEmitter<FileData[]>- Emitted when files are selectedvalidationError: EventEmitter<ValidationError>- Emitted on validation errors
<enri-file-preview>
Container component for file preview with loading/error states.
Inputs:
file: FileData | null- File to previewstate: FileState- Current state (idle/loading/ready/error)previewConfig: PreviewConfig- Preview configurationerror: FileError- Error to display
Outputs:
loadSuccess: EventEmitter<void>- Emitted when preview loads successfullyloadError: EventEmitter<FileError>- Emitted on preview errors
<enri-file-viewer>
Renders files using appropriate strategies based on file type.
Inputs:
file: FileData- File to renderconfig: ViewerConfig- Viewer configuration
<enri-file-thumbnail>
Thumbnail component for file lists/grids.
Inputs:
file: FileData- File to displaysize: 'small' | 'medium' | 'large'- Thumbnail sizeshowName: boolean- Show file nameclickable: boolean- Make thumbnail clickable
<enri-file-metadata>
Displays file metadata (name, size, type, etc.).
Inputs:
file: FileData- File to display metadata forfields: MetadataField[]- Fields to displaylayout: 'horizontal' | 'vertical'- Layout direction
<enri-video-player>
Custom video player with full control support.
Inputs:
fileData: FileData | null- Video file to playautoplay: boolean- Auto-start playback (default: false)loop: boolean- Loop playback (default: false)muted: boolean- Start muted (default: false)poster: string- Poster image URLpreload: 'none' | 'metadata' | 'auto'- Preload strategy (default: 'metadata')showInfo: boolean- Show file info below video (default: true)
Features:
- ▶️ Play/Pause controls
- 📊 Interactive progress bar with seek
- 🔊 Volume control with draggable slider
- ⚡ Playback speed selector (0.5x - 2x)
- ⛶ Fullscreen mode with scaled controls
- ⏱️ Time display (current / total)
- 🎨 Fully customizable via CSS variables
- 🖱️ Click video to toggle play/pause
- 🎚️ Drag volume slider for precise control
Example:
<enri-video-player
[fileData]="videoFile"
[autoplay]="false"
[loop]="false"
[showInfo]="true">
</enri-video-player><enri-pdf-viewer>
Native PDF viewer with zoom and download controls.
Inputs:
fileData: FileData | null- PDF file to displayshowToolbar: boolean- Show toolbar with controls (default: true)showInfo: boolean- Show file info below PDF (default: true)initialZoom: number- Initial zoom level in percentage (default: 100)minZoom: number- Minimum zoom level (default: 50)maxZoom: number- Maximum zoom level (default: 200)zoomStep: number- Zoom step increment (default: 10)
Features:
- 🔍 Zoom in/out controls (50%-200%)
- 🔄 Reset zoom to 100%
- 💾 Download PDF button
- ⛶ Fullscreen mode
- 📄 Native PDF rendering (no external libraries)
- 🎨 Fully customizable via CSS variables
- 📱 Responsive design with scrollable content
Example:
<enri-pdf-viewer
[fileData]="pdfFile"
[showToolbar]="true"
[showInfo]="true"
[initialZoom]="100"
[minZoom]="50"
[maxZoom]="200">
</enri-pdf-viewer>CSS Variables (25+):
// Container
--enri-pdf-viewer-bg: #1a1a1a;
--enri-pdf-viewer-radius: 8px;
// Toolbar
--enri-pdf-viewer-toolbar-bg: #2d2d2d;
--enri-pdf-viewer-toolbar-padding: 12px;
--enri-pdf-viewer-btn-color: #fff;
--enri-pdf-viewer-btn-bg: #444;
--enri-pdf-viewer-btn-hover-bg: #555;
--enri-pdf-viewer-zoom-color: #fff;
// PDF Content
--enri-pdf-viewer-content-bg: #fff;
--enri-pdf-viewer-content-padding: 20px;
// File Info
--enri-pdf-viewer-info-bg: #2d2d2d;
--enri-pdf-viewer-filename-color: #fff;
--enri-pdf-viewer-size-color: #aaa;🎨 Customization
Using CSS Variables
The library provides 50+ CSS variables for complete customization:
:root {
// File Picker
--enri-file-picker-bg: #1a1a1a;
--enri-file-picker-border: 2px solid #00ff00;
--enri-file-picker-hover-bg: #2a2a2a;
--enri-file-picker-padding: 32px;
--enri-file-picker-radius: 8px;
// File Preview
--enri-file-preview-bg: #ffffff;
--enri-file-preview-radius: 8px;
--enri-file-loading-spinner-color: #1976d2;
// Video Player
--enri-video-player-bg: #000;
--enri-video-player-controls-bg: linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, transparent 100%);
--enri-video-player-progress-color: #1976d2;
--enri-video-player-btn-color: #fff;
--enri-video-player-btn-size: 20px;
--enri-video-player-volume-width: 80px;
--enri-video-player-volume-filled-color: #fff;
--enri-video-player-time-color: #fff;
// Fullscreen Video Controls
--enri-video-player-btn-fullscreen-size: 28px;
--enri-video-player-volume-fullscreen-width: 120px;
--enri-video-player-progress-fullscreen-height: 6px;
}Complete CSS Variable Reference
// Container
--enri-video-player-display
--enri-video-player-direction
--enri-video-player-bg
--enri-video-player-radius
--enri-video-player-container-bg
--enri-video-player-max-height
// Controls
--enri-video-player-controls-bg
--enri-video-player-controls-padding
--enri-video-player-controls-transition
--enri-video-player-control-gap
// Progress Bar
--enri-video-player-progress-height
--enri-video-player-progress-hover-height
--enri-video-player-progress-bg
--enri-video-player-progress-color
--enri-video-player-progress-radius
// Buttons
--enri-video-player-btn-color
--enri-video-player-btn-size
--enri-video-player-btn-padding
--enri-video-player-btn-focus
--enri-video-player-btn-transition
// Volume
--enri-video-player-volume-width
--enri-video-player-volume-height
--enri-video-player-volume-hover-height
--enri-video-player-volume-bg
--enri-video-player-volume-filled-color
--enri-video-player-volume-radius
--enri-video-player-volume-gap
// Time Display
--enri-video-player-time-color
--enri-video-player-time-size
--enri-video-player-time-weight
// Speed Control
--enri-video-player-speed-bg
--enri-video-player-speed-color
--enri-video-player-speed-border
--enri-video-player-speed-radius
--enri-video-player-speed-padding
--enri-video-player-speed-size
// File Info
--enri-video-player-info-padding
--enri-video-player-info-bg
--enri-video-player-filename-size
--enri-video-player-size-color// Container
--enri-pdf-viewer-display
--enri-pdf-viewer-direction
--enri-pdf-viewer-bg
--enri-pdf-viewer-radius
// Toolbar
--enri-pdf-viewer-toolbar-display
--enri-pdf-viewer-toolbar-justify
--enri-pdf-viewer-toolbar-align
--enri-pdf-viewer-toolbar-gap
--enri-pdf-viewer-toolbar-padding
--enri-pdf-viewer-toolbar-bg
--enri-pdf-viewer-toolbar-border-bottom
// Controls
--enri-pdf-viewer-controls-gap
// Buttons
--enri-pdf-viewer-btn-padding
--enri-pdf-viewer-btn-bg
--enri-pdf-viewer-btn-color
--enri-pdf-viewer-btn-border
--enri-pdf-viewer-btn-radius
--enri-pdf-viewer-btn-size
--enri-pdf-viewer-btn-cursor
--enri-pdf-viewer-btn-transition
--enri-pdf-viewer-btn-hover-bg
// Zoom Display
--enri-pdf-viewer-zoom-padding
--enri-pdf-viewer-zoom-color
--enri-pdf-viewer-zoom-size
--enri-pdf-viewer-zoom-weight
// Filename
--enri-pdf-viewer-filename-color
--enri-pdf-viewer-filename-size
--enri-pdf-viewer-filename-weight
// PDF Content
--enri-pdf-viewer-content-flex
--enri-pdf-viewer-content-overflow
--enri-pdf-viewer-content-bg
--enri-pdf-viewer-content-padding
--enri-pdf-viewer-pdf-width
--enri-pdf-viewer-pdf-height
// File Info
--enri-pdf-viewer-info-padding
--enri-pdf-viewer-info-bg
--enri-pdf-viewer-info-border-top
--enri-pdf-viewer-size-color
--enri-pdf-viewer-size-size--enri-file-picker-display
--enri-file-picker-direction
--enri-file-picker-padding
--enri-file-picker-border
--enri-file-picker-radius
--enri-file-picker-bg
--enri-file-picker-hover-bg
--enri-file-picker-dragging-bg
--enri-file-picker-text-color
--enri-file-picker-icon-size
--enri-file-picker-min-heightCustom Themes
Create a custom theme:
// dark-theme.scss
:root {
--enri-file-picker-bg: #2d2d2d;
--enri-file-picker-text-color: #ffffff;
--enri-file-preview-bg: #1a1a1a;
--enri-file-preview-border: 1px solid #444;
// ... more variables
}Extending with Custom Renderers
Add support for custom file types:
import { FileRendererRegistry, FileRenderer, FileData } from 'enri-file-management';
class CustomCadRenderer implements FileRenderer {
canRender(file: FileData): boolean {
return file.metadata.extension === '.dwg';
}
async render(file: FileData, container: HTMLElement): Promise<void> {
// Custom rendering logic
container.innerHTML = '<p>CAD file viewer</p>';
}
}
// In your module or component
constructor(private registry: FileRendererRegistry) {
registry.register(new CustomCadRenderer());
}🏗️ Architecture
The library follows Clean Architecture principles:
Core (Domain) → Application (Use Cases) → Infrastructure (Adapters) → UI (Components)- Core: Pure TypeScript models and interfaces
- Application: Business logic and use cases
- Infrastructure: Browser API adapters and rendering strategies
- UI: Angular components, pipes, and directives
📚 Advanced Usage
Programmatic File Reading
import { ReadFileUseCase } from 'enri-file-management';
constructor(private readFileUseCase: ReadFileUseCase) {}
async readFile(file: File): Promise<void> {
const dataUrl = await this.readFileUseCase.executeAsDataURL(file);
const text = await this.readFileUseCase.executeAsText(file);
const buffer = await this.readFileUseCase.executeAsArrayBuffer(file);
}File Validation
import { ValidateFileUseCase, FileValidationConfig } from 'enri-file-management';
const config: FileValidationConfig = {
maxSize: 5 * 1024 * 1024, // 5MB
allowedTypes: ['image/png', 'image/jpeg'],
allowedExtensions: ['.png', '.jpg']
};
const result = this.validateFileUseCase.execute(file, config);
if (!result.valid) {
console.error('Validation errors:', result.errors);
}🧪 Testing
The library is fully tested with Jasmine/Karma. Run tests:
npm run test:lib📄 License
MIT © Enrique Ruiz | Technical Lead
🤝 Contributing
Contributions are welcome! Please read our Contributing Guide for details.
📝 Changelog
See CHANGELOG.md for release history.
🐛 Issues
Found a bug? Please open an issue on GitHub.
