Saltar al contenido principal

TdnInputFile

Paquete: @tiendana/ngx-core/forms

Componente de carga de archivos con soporte para arrastrar y soltar, múltiples archivos, previsualización de archivos existentes y personalización completa.

Características​

✅ Soporte drag & drop - Arrastra archivos directamente sobre el componente
✅ Modo múltiple - Sube uno o varios archivos según sea necesario
✅ Restricción de tipos - Filtra archivos por extensión o tipo MIME
✅ Archivos existentes - Muestra archivos ya guardados con URLs
✅ Template personalizado - Personaliza la visualización de cada archivo
✅ Eventos detallados - Controla selección y eliminación de archivos
✅ Integración total - Compatible con Reactive Forms y validadores

Selector​

<tdn-input-file />

API​

Inputs​

PropiedadTipoDescripciónPor Defecto
settingsTdnInputFileSettingsConfiguración del componente (textos, iconos, clases, tipos aceptados)Configuración predeterminada
preventBodyDropbooleanPreviene que archivos arrastrados fuera del componente se abran en el navegadortrue

Outputs​

EventoTipoDescripción
focusvoidDeclarado, pero nunca se emite: la plantilla no lo enlaza
blurvoidDeclarado, pero nunca se emite: la plantilla no lo enlaza
onSelectFile | File[]Emite cuando se selecciona(n) archivo(s). Devuelve File en modo simple o File[] en modo múltiple
onClearFileEmite cuando se elimina un archivo nuevo (objeto File)
onClearInstancestringEmite cuando se elimina un archivo existente (URL)

Atributos HTML​

AtributoTipoDescripción
multiplebooleanPermite seleccionar múltiples archivos. Se detecta automáticamente por la presencia del atributo
acceptstringLista separada por comas de tipos de archivos aceptados (ej: .pdf,.docx o image/*)

Content Children​

TemplateDescripción
#ifItemTemplate para renderizar cada archivo personalizado. Recibe el contexto { item }: un File para archivos nuevos y la URL (string) para archivos existentes. Úsalo con let-item="item"

Clases del host​

tdn-input-file, tdn-input-file--has-value, tdn-input-file--disabled y tdn-input-file--drag-over, más las de settings.classes. Con preventBodyDrop activo, los eventos dragover y drop sobre el body se previenen.

Comportamiento​

  • En modo multiple, los archivos seleccionados se añaden a la lista.
  • Al elegir un File nuevo se descartan los archivos existentes (URLs).
  • Un archivo existente se muestra como enlace a su URL; con processFilenameUrl solo se muestra el nombre del archivo.

Configuración​

Interfaz TdnInputFileSettings
interface TdnInputFileSettings {
// Estilos
classes?: string; // Clases CSS adicionales

// Comportamiento
processFilenameUrl?: boolean; // Extrae solo el nombre del archivo de URLs completas
accept?: string[]; // Array de tipos de archivos aceptados

// Iconos (SVG como string o SafeHtml)
icons?: Partial<TdnInputFileIcons>;

// Traducciones
translations?: Partial<TdnInputFileTranslations>;
}

interface TdnInputFileIcons {
upload: string | SafeHtml; // Icono del botón de carga
remove: string | SafeHtml; // Icono del botón de eliminar
file: string | SafeHtml; // Icono de archivo
}

interface TdnInputFileTranslations {
removeText: string; // Tooltip de eliminar (default: 'Remover archivo')
uploadText: string; // Tooltip para subir un archivo (default: 'Seleccionar archivo')
uploadMultipleText: string; // Tooltip para subir varios archivos (default: 'Seleccionar archivos')
fileInstanceTitle: string; // Tooltip de archivos existentes (default: 'Clic para ver el archivo guardado')
}

Valores Predeterminados​

{
classes: '',
processFilenameUrl: true,
accept: ['*'],
icons: {
upload: TDN_ICON_UPLOAD,
remove: TDN_ICON_CLEAR,
file: TDN_ICON_FILE
},
translations: {
removeText: 'Remover archivo',
uploadText: 'Seleccionar archivo',
uploadMultipleText: 'Seleccionar archivos',
fileInstanceTitle: 'Clic para ver el archivo guardado'
}
}

Ejemplos y Demos​

Uso Básico​

Cargando demo...
Ver código

Múltiples Archivos​

Cargando demo...
Ver código

Restricción de Tipos​

Cargando demo...
Ver código

Configuración Personalizada​

Cargando demo...
Ver código

Archivos Existentes (URLs)​

Cargando demo...
Ver código

Template Personalizado para Items​

Cargando demo...
Ver código

Eventos de Selección y Eliminación​

Cargando demo...
Ver código

Con Validación​

Cargando demo...
Ver código

Validación Personalizada de Tamaño​

Cargando demo...
Ver código

Ejemplo Completo​

Cargando demo...
Ver código

Buenas Prácticas​

Hacer​

  • Usa accept para restringir tipos de archivos y mejorar UX
  • Implementa validación de tamaño en el cliente antes de subir
  • Proporciona feedback visual claro cuando se seleccionan archivos
  • Usa modo multiple solo cuando realmente sea necesario
  • Maneja errores de selección con eventos onSelect
  • Personaliza textos según el contexto (CV, foto, documento, etc.)

Evitar​

  • No omitas validación de tipo de archivo por seguridad
  • No uses accept="*" sin validación adicional en el servidor
  • No permitas archivos muy grandes sin advertir al usuario
  • No olvides limpiar archivos temporales del formulario
  • No uses multiple si solo necesitas un archivo

Integración con Backend​

Envío con FormData​

async uploadFiles() {
const formData = new FormData();
const file = this.form.value.document;

if (file instanceof File) {
formData.append('document', file);

// Enviar al servidor
await fetch('/api/upload', {
method: 'POST',
body: formData
});
}
}

Múltiples Archivos​

async uploadMultipleFiles() {
const formData = new FormData();
const files = this.form.value.attachments || [];

files.forEach((file, index) => {
formData.append(`files[${index}]`, file);
});

await fetch('/api/upload-multiple', {
method: 'POST',
body: formData
});
}

Accesibilidad​

  • El componente usa un <input type="file"> nativo para máxima compatibilidad
  • Los botones tienen atributos title para tooltips descriptivos
  • El estado disabled previene interacciones cuando está deshabilitado
  • La zona de carga es un div sin tabindex: hoy no se alcanza con el teclado

Personalización Avanzada​

Token de Angular​

TDN_INPUT_FILE_DEFAULT_SETTINGS_TOKEN​

Token de inyección para configurar el comportamiento predeterminado de todos los componentes TdnInputFile en la aplicación. Un proveedor reemplaza el objeto completo: parte de TDN_INPUT_FILE_DEFAULT_SETTINGS.

import {
TDN_INPUT_FILE_DEFAULT_SETTINGS,
TDN_INPUT_FILE_DEFAULT_SETTINGS_TOKEN,
TdnInputFileSettings
} from '@tiendana/ngx-core/forms';
import { bootstrapApplication } from '@angular/platform-browser';

const customFileSettings: TdnInputFileSettings = {
...TDN_INPUT_FILE_DEFAULT_SETTINGS,
translations: {
...TDN_INPUT_FILE_DEFAULT_SETTINGS.translations,
uploadText: 'Subir Archivo',
uploadMultipleText: 'Subir Archivos',
removeText: 'Eliminar'
},
processFilenameUrl: false, // Mostrar URLs completas sin procesar
accept: ['.pdf', '.doc', '.docx', '.xls', '.xlsx'],
icons: {
upload: '<svg>...</svg>', // Iconos personalizados
remove: '<svg>...</svg>',
file: '<svg>...</svg>'
}
};

bootstrapApplication(AppComponent, {
providers: [
{
provide: TDN_INPUT_FILE_DEFAULT_SETTINGS_TOKEN,
useValue: customFileSettings
}
]
});

Configuración a Nivel de Módulo/Componente​

Puedes proporcionar configuraciones específicas para un contexto limitado:

import { Component } from '@angular/core';
import {
TDN_INPUT_FILE_DEFAULT_SETTINGS,
TDN_INPUT_FILE_DEFAULT_SETTINGS_TOKEN
} from '@tiendana/ngx-core/forms';

@Component({
selector: 'app-documents-section',
providers: [
{
provide: TDN_INPUT_FILE_DEFAULT_SETTINGS_TOKEN,
useValue: {
...TDN_INPUT_FILE_DEFAULT_SETTINGS,
accept: ['.pdf'], // Solo PDFs en esta sección
translations: {
...TDN_INPUT_FILE_DEFAULT_SETTINGS.translations,
uploadText: 'Cargar Documento PDF'
}
}
}
],
template: `
<!-- Todos los TdnInputFile aquí heredarán esta configuración -->
`
})
export class DocumentsSectionComponent {}

Valores Predeterminados del Token​

Si no se proporciona configuración, el componente usa estos valores:

{
classes: '',
processFilenameUrl: true,
accept: ['*'], // Acepta todos los tipos
icons: {
upload: TDN_ICON_UPLOAD,
remove: TDN_ICON_CLEAR,
file: TDN_ICON_FILE
},
translations: {
removeText: 'Remover archivo',
uploadText: 'Seleccionar archivo',
uploadMultipleText: 'Seleccionar archivos',
fileInstanceTitle: 'Clic para ver el archivo guardado'
}
}

La fábrica del token clona icons, translations y accept, de modo que el valor del token no comparte objetos con la constante exportada TDN_INPUT_FILE_DEFAULT_SETTINGS.

Componentes Relacionados​