Taiga UI 5.0 is out!

InputFiles KIT

Examples API GitHub

On this page

An input for uploading one or several files using native input file capabilities

Single

Selecting one file at a time
    
      @if (!control.value) {
    <label tuiInputFiles>
        <input
            accept="image/*"
            tuiInputFiles
            [formControl]="control"
        />
    </label>
}

<tui-files class="tui-space_top-1">
    @if (control.value | tuiFileRejected: {accept: 'image/*'} | async; as file) {
        <tui-file
            state="error"
            [file]="file"
            (remove)="removeFile()"
        />
    }

    @if (loadedFiles$ | async; as file) {
        <tui-file
            size="l"
            [file]="file"
            (remove)="removeFile()"
        />
    }

    @if (failedFiles$ | async; as file) {
        <tui-file
            state="error"
            [file]="file"
            (remove)="removeFile()"
        />
    }

    @if (loadingFiles$ | async; as file) {
        <tui-file
            state="loading"
            [file]="file"
            (remove)="removeFile()"
        />
    }
</tui-files>

    

Multiple

Selecting and processing multiple files at once
    
      <label tuiInputFiles>
    <input
        #validator="tuiInputFilesValidator"
        accept="image/*"
        tuiInputFiles
        [formControl]="control"
        [multiple]="true"
        (reject)="onReject($event)"
    />
</label>

<tui-files class="tui-space_top-1">
    @for (file of accepted$ | async; track file) {
        <tui-file
            [file]="file"
            (remove)="onRemove(file)"
        />
    }

    @for (file of rejected; track file) {
        <tui-file
            state="error"
            [file]="(file | tuiFileRejected: validator | async) || file"
            (remove)="onRemove(file)"
        />
    }
</tui-files>

<tui-error
    [formControl]="control"
    [order]="['maxLength']"
/>

    

Standalone

Displaying file-like items without the input
Loaded
.txt
A file with a very very long title to check that it can be cut correctly
.txt
File with an error
.txt
Something went wrong this time
Loading file
.txt

With link

with link
.txt

With deleted state

Loading file
.txt
    
      
    
    
      <tui-files>
    @for (file of files; track file) {
        <tui-file
            state="normal"
            [file]="file"
            [showDelete]="control.enabled"
        />
    }

    @for (file of rejectedFiles; track file) {
        <tui-file
            state="error"
            [file]="file"
            [showDelete]="control.enabled"
        />
    }

    @if (loadingFile && !isE2E) {
        <tui-file
            state="loading"
            [file]="loadingFile"
            [showDelete]="control.enabled"
            (remove)="removeLoading()"
        />
    }
</tui-files>

<h4>With link</h4>
<tui-files>
    <a
        *tuiItem
        rel="noreferrer"
        state="normal"
        target="_blank"
        tuiFile
        [file]="fileWithLink"
        [href]="fileWithLink.src"
        [showDelete]="control.enabled"
    ></a>
</tui-files>

<h4>With deleted state</h4>
<tui-files>
    @for (file of removedFiles; track file) {
        <tui-file
            size="l"
            state="deleted"
            [file]="file"
            [showDelete]="control.enabled"
        >
            <button
                tuiLink
                type="button"
                (click)="restore(file)"
            >
                Restore
            </button>
        </tui-file>
    }
    @for (file of restoredFiles; track file) {
        <tui-file
            size="l"
            state="normal"
            [file]="file"
            [leftContent]="icon"
            [showDelete]="control.enabled"
            (remove)="remove(file)"
        />
    }
</tui-files>

<ng-template #icon>
    <tui-icon src="@tui.file" />
</ng-template>

    

With button

Collapsing files list when it's too long
Loaded
.txt
one_more_file
.txt
one_more_file
.txt
one_more_file
.txt
one_more_file
.txt
one_more_file
.txt
last_file
.txt
File with an error
.txt
Upload failed
    
      
    
    
      <tui-files [max]="3">
    @for (file of files; track file) {
        <tui-file
            *tuiItem
            state="normal"
            [file]="file"
        />
    }

    @for (file of rejectedFiles; track file) {
        <a
            *tuiItem
            rel="noreferrer"
            state="error"
            target="_blank"
            tuiFile
            [file]="file"
        ></a>
    }
</tui-files>

    

Custom content

Customizing drop area
custom
.txt
file is on checking
    
      
    
    
      <label tuiInputFiles>
    <input
        tuiInputFiles
        [formControl]="control"
    />
    <ng-template let-dragged>
        @if (dragged) {
            <div
                appearance="secondary"
                size="l"
                tuiAvatar="@tui.droplet"
            ></div>
            <div>
                Drop it like it's hot!
                <br />
                <br />
            </div>
        } @else {
            <div
                appearance="secondary"
                size="l"
                tuiAvatar="@tui.cloud-upload"
            ></div>
            <div>
                Drag and drop file here or
                <a tuiLink>click to upload</a>
            </div>
            <div class="types">PNG, JPG, JPEG, PNG, etc</div>
        }
    </ng-template>
</label>

<tui-files class="tui-space_top-4">
    <tui-file
        [file]="file"
        [leftContent]="content"
    >
        <span class="tui-text_body-s-2">file is on checking</span>
    </tui-file>
</tui-files>

<ng-template #content>
    <tui-icon icon="@tui.clock" />
</ng-template>

    
    
      :host {
    display: block;
    min-inline-size: 25rem;
}

.types {
    color: var(--tui-text-secondary);
    font-size: 0.6875rem;
}

    

Camera capture

The capture attribute works only on mobile browsers
    
      @if (!control.value) {
    <label tuiInputFiles>
        <input
            accept="image/*"
            capture="user"
            title="Choose files (no limits)"
            tuiInputFiles
            [formControl]="control"
        />
    </label>
}

<tui-files class="tui-space_top-1">
    @if (control.valueChanges | async; as file) {
        <tui-file
            [file]="file"
            (remove)="removeFile()"
        />
    }
</tui-files>

    

Model

Using template driven forms
    
      <label tuiInputFiles>
    <input
        #validator="tuiInputFilesValidator"
        accept="image/*"
        tuiInputFiles
        [multiple]="true"
        [ngModel]="files"
        (ngModelChange)="onChange($event)"
        (reject)="onReject($event)"
    />
</label>

<tui-files class="tui-space_top-1">
    @for (file of rejected; track file) {
        <tui-file
            state="error"
            [file]="(file | tuiFileRejected: validator | async) || file"
            (remove)="onRemove(file)"
        />
    }
    @for (file of files; track file) {
        <tui-file
            state="normal"
            [file]="file"
            (remove)="onRemove(file)"
        />
    }
</tui-files>

    

Accept

Uploading files with accept attribute containing multiple extensions separated by spaces
valid
.zip
16 B
    
      
    
    
      <label tuiInputFiles>
    <input
        #validator="tuiInputFilesValidator"
        tuiInputFiles
        [formControl]="control"
        [multiple]="true"
        (reject)="onReject($event)"
    />
</label>

<tui-files class="tui-space_top-1">
    @for (file of accepted$ | async; track file) {
        <tui-file
            [file]="file"
            (remove)="onRemove(file)"
        />
    }

    @for (file of rejected; track file) {
        <tui-file
            state="error"
            [file]="(file | tuiFileRejected: validator | async) || file"
            (remove)="onRemove(file)"
        />
    }
</tui-files>