@avoraui/av-file-picker
Version:
A customizable Angular file picker component for images and PDFs with preview support.
208 lines (156 loc) • 6.06 kB
Markdown
# AvFilePicker Component (AvoraUI)
A customizable Angular file picker component that supports both images and PDF files with preview functionality. This component implements Angular's `ControlValueAccessor` interface, making it fully compatible with reactive forms.
## Features
- ✅ **Multi-format Support**: Handles both image files and PDF documents
- ✅ **File Size Validation**: Enforces a 10MB maximum file size limit
- ✅ **Preview Functionality**:
- Image preview with thumbnail display
- PDF preview with view link that opens in a new tab
- ✅ **Reactive Forms Integration**: Full support for Angular reactive forms
- ✅ **Material Design**: Built with Angular Material components
- ✅ **Memory Management**: Automatic cleanup of object URLs to prevent memory leaks
- ✅ **Error Handling**: Graceful error handling with user-friendly alerts
## Dependencies
This component requires the following Angular Material modules:
```typescript
import { MatCard } from "@angular/material/card";
import { MatButton } from "@angular/material/button";
import { MatIcon } from '@angular/material/icon';
```
## Installation
1. Ensure you have Angular Material installed in your project
2. Import the component in your module or use it directly (standalone component)
## Usage
### Basic Usage
```html
<av-file-picker
[defaultImage]="'/assets/default-placeholder.png'"
[showPdfDetails]="true">
</av-file-picker>
```
### With Reactive Forms
```typescript
// Component
export class MyComponent {
fileForm = this.fb.group({
selectedFile: ['']
});
constructor(private fb: FormBuilder) {}
}
```
```html
<!-- Template -->
<form [formGroup]="fileForm">
<av-file-picker
formControlName="selectedFile"
[defaultImage]="'/assets/placeholder.png'"
[showPdfDetails]="true">
</av-file-picker>
</form>
```
## Input Properties
| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| `defaultImage` | `any` | No | `undefined` | Default image to display when no file is selected |
| `showPdfDetails` | `boolean` | No | `false` | Whether to show PDF file details and view link |
## Component Behavior
### File Selection
- Click the "Select" button to open the file picker dialog
- Accepts image files (`image/*`) and PDF files (`.pdf`)
- Validates file size (maximum 10MB)
- Automatically detects file type and displays appropriate preview
### File Preview
- **Images**: Displays thumbnail preview of the selected image
- **PDFs**: Shows PDF icon with document indicator and optional view link
### File Management
- **Clear**: Removes the selected file and resets to default state
- **Replace**: Select a new file to replace the current selection
### Form Integration
The component outputs a Base64-encoded string of the selected file, making it easy to:
- Store in databases
- Send via API calls
- Integrate with form validation
## Data Format
The component handles data conversion automatically:
**Output**: Base64-encoded string representation of the file
**Input**: Base64-encoded string (automatically decoded and displayed)
### File Type Detection
The component uses binary signatures to detect file types:
- **PDF**: Checks for PDF signature (`%PDF`) in the first 4 bytes
- **Images**: Treats all non-PDF files as images
## Error Handling
The component includes comprehensive error handling for:
- File size validation (shows alert for files > 10MB)
- File reading errors (console logging + user alerts)
- Base64 decoding errors (graceful fallback to default image)
## Memory Management
The component automatically:
- Creates object URLs for PDF preview
- Cleans up object URLs in `ngOnDestroy()` to prevent memory leaks
- Revokes previous URLs when new files are selected
## Styling
The component uses CSS classes that can be customized:
- `.img-upload-panel` - Main container
- `.img-preview-container` - Preview area container
- `.img-placeholder` - Placeholder/preview area
- `.preview-image` - Selected image display
- `.pdf-placeholder` - PDF icon container
- `.pdf-overlay` - PDF view link overlay
- `.file-info` - File information display
- `.action-buttons` - Button container
## Browser Compatibility
This component uses modern browser APIs:
- `FileReader` API for file reading
- `URL.createObjectURL()` for PDF preview
- `atob()`/`btoa()` for Base64 encoding/decoding
Ensure your target browsers support these features or include appropriate polyfills.
## Example Implementation
```typescript
// app.component.ts
import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'app-root',
template: `
<form [formGroup]="uploadForm">
<av-file-picker
formControlName="document"
[defaultImage]="defaultPlaceholder"
[showPdfDetails]="true">
</av-file-picker>
<button (click)="onSubmit()" [disabled]="!uploadForm.valid">
Submit
</button>
</form>
`
})
export class AppComponent {
defaultPlaceholder = '/assets/upload-placeholder.png';
uploadForm: FormGroup = this.fb.group({
document: ['']
});
constructor(private fb: FormBuilder) {}
onSubmit() {
const fileData = this.uploadForm.get('document')?.value;
// fileData contains the Base64-encoded file
console.log('Selected file (Base64):', fileData);
}
}
```
## Requirements
- Angular 17+
- Angular Material (for pagination component)
- Modern browser with CSS Grid support
## Browser Support
- Chrome/Edge 57+
- Firefox 52+
- Safari 10.1+
## License
This project is licensed under the MIT License - see the LICENSE file for details.
## Changelog
### v0.0.2
- Initial release
- Basic table functionality with pagination
- CRUD operations support
- Reactive forms integration
- Nested object property access