API reference
tngFileUpload is a standalone directive that makes its host a drop zone, validates dropped files, and reports accepted and rejected results back to the owner.
Directive selector
The primitive attaches through [tngFileUpload] and exports itself as tngFileUpload. It works on any section-like host element.
Directive attachment
html
<div
tngFileUpload
[accept]="'image/*,.pdf'"
[maxSize]="5 * 1024 * 1024"
(filesSelected)="onFilesSelected($event)"
></div>
Inputs and outputs
| Name | Type | Notes |
|---|---|---|
accept | string | string[] | null | Comma-separated or array of tokens: extensions (.pdf), exact MIME types (application/pdf), or wildcard groups (image/*). Empty means no restriction. |
multiple | boolean | When false, the first valid file is accepted and the rest are rejected as multiple. |
maxSize | number | null | Maximum size in bytes. Zero, negative, and null values disable size validation. |
disabled | boolean | Disabled drop zones are fully passive: no preventDefault, no emits. |
filesSelected | TngFileUploadSelectedEvent | Emits { files, source } when one or more valid files are selected. |
filesRejected | TngFileUploadRejectedEvent | Emits { rejected, accepted, source } when files fail validation. |
dragStateChange | 'idle' | 'dragging' | 'rejected' | Emits whenever the drag interaction state changes. |
Drag and drop behavior
- The host remains the drop target even when the pointer releases over nested markup such as labels, icons, or hint text inside the zone.
- Drag state is not reset when the pointer moves between the host and its descendants; only a true exit from the zone clears
data-dragging. - Accepted and rejected file outputs are scheduled inside Angular's zone so owner templates update as soon as the drop completes.
Validation model
Each file is checked for type first, then size. Only files that pass both are considered for acceptance, and the multiple rule is applied last. Input order is preserved within both the accepted and rejected lists.
Reading rejected files
ts
// filesSelected → { files: File[]; source: "drop" | "input" }
// filesRejected → { rejected: TngFileUploadRejectedFile[]; accepted: File[]; source }
protected onFilesRejected(event: TngFileUploadRejectedEvent): void {
for (const item of event.rejected) {
// item.reason: "type" | "size" | "multiple" | "disabled" | "empty"
console.warn(item.reason, item.message, item.file.name);
}
}