Saltar al contenido principal

TdnInputImage

Paquete: @tiendana/ngx-core/forms

Componente de carga de imágenes con previsualización, optimización automática, drag & drop y personalización completa.

Características​

✅ Preview en vivo - Muestra la imagen seleccionada antes de subirla
✅ Optimización automática - Comprime y redimensiona imágenes con ImageCompressor
✅ Drag & drop - Arrastra imágenes directamente sobre el componente
✅ Restricción de tipos - Acepta solo formatos de imagen
✅ Imágenes existentes - Muestra imágenes ya guardadas con URLs
✅ Object-fit configurable - Controla cómo se ajusta la imagen (cover/contain)
✅ Eventos detallados - Controla selección, eliminación y procesamiento
✅ Integración total - Compatible con Reactive Forms y validadores

Selector​

<tdn-input-image />

API​

Inputs​

PropiedadTipoDescripciónPor Defecto
settingsTdnInputImageSettingsConfiguración del componente (optimización, textos, iconos, object-fit)Configuración predeterminada
preventBodyDropbooleanPreviene que imágenes arrastradas fuera del componente se abran en el navegadortrue
labelstringTexto de etiqueta para el input''
uploadTextstringTexto del tooltip de carga'Seleccionar imagen'
objectFit'contain' | 'cover'Modo de ajuste de la imagen en preview'cover'

Outputs​

EventoTipoDescripción
focusvoidDeclarado, pero nunca se emite: la plantilla no lo enlaza
blurvoidDeclarado, pero nunca se emite: la plantilla no lo enlaza
onSelectFileEmite cuando se selecciona una imagen (después de optimización si está habilitada)
onClearFileEmite cuando se elimina una imagen nueva (objeto File)
onClearInstancestringEmite cuando se elimina una imagen existente (URL)

Clases del host​

tdn-input-image, tdn-input-image--has-value, tdn-input-image--disabled y tdn-input-image--processing, más las de settings.classes.

Atributos HTML​

AtributoTipoDescripción
no-optimizebooleanDesactiva la optimización automática de imágenes
acceptstringLista separada por comas de tipos de imágenes aceptadas (ej: .png,.jpg)

Configuración​

Interfaz TdnInputImageSettings
interface TdnInputImageSettings {
// Textos
removeText?: string; // Texto del tooltip de eliminar
uploadText?: string; // Texto del tooltip de carga
procesingText?: string; // Texto mostrado durante optimización
label?: string; // Etiqueta del input

// Visualización
objectFit?: 'contain' | 'cover'; // Modo de ajuste de imagen
classes?: string; // Clases CSS adicionales

// Tipos aceptados
accept?: string[]; // Array de extensiones aceptadas

// Optimización (basada en ImageCompressor de @tiendana/utils)
optimize?: {
enable?: boolean; // Habilita/deshabilita optimización
maxWidth?: number | null; // Ancho máximo (px)
maxHeight?: number | null; // Alto máximo (px)
quality?: number; // Calidad (0-1)
strict?: boolean; // Modo estricto
checkOrientation?: boolean; // Sin efecto: el componente no lo pasa a ImageCompressor
resize?: 'contain' | 'cover' | 'none'; // Sin efecto: el componente no lo pasa a ImageCompressor
mimeType?: string; // Sin efecto: el componente no lo pasa a ImageCompressor
convertTypes?: string | string[]; // Sin efecto: el componente no lo pasa a ImageCompressor
convertSize?: number; // Sin efecto: el componente no lo pasa a ImageCompressor
};

// Iconos (SVG como string o SafeHtml)
icons?: {
toolbarIcon?: string | SafeHtml; // Icono de la barra de herramientas
upload?: string | SafeHtml; // Icono del botón de carga
clear?: string | SafeHtml; // Icono del botón de eliminar
};
}

Valores Predeterminados​

{
removeText: 'Remover imagen',
uploadText: 'Seleccionar imagen',
procesingText: 'Procesando...',
label: '',
objectFit: 'cover',
classes: '',
accept: ['.png', '.jpg', '.jpeg', '.webp'],
optimize: {
enable: true,
strict: true,
maxWidth: 1920,
maxHeight: Infinity,
quality: 1.0
},
icons: {
toolbarIcon: TDN_ICON_TOOLBAR_IMAGE,
upload: TDN_ICON_UPLOAD_IMAGE,
clear: TDN_ICON_CLEAR
}
}

Comportamiento de la optimización​

  • Con optimize.enable activo (por defecto) todas las imágenes, incluidas las image/webp, pasan por ImageCompressor. Para dejar pasar el archivo tal cual, usa no-optimize u optimize: { enable: false }.
  • El archivo emitido se renombra con el nombre en minúsculas.
  • Si la compresión falla, se emite el archivo original (también con el nombre en minúsculas).

Ejemplos y Demos​

Uso Básico​

Cargando demo...
Ver código

Configuración de Optimización​

Cargando demo...
Ver código

Sin Optimización​

Cargando demo...
Ver código

Object-fit: Contain​

Cargando demo...
Ver código

Imagen Existente (URL)​

Cargando demo...
Ver código

Restricción de Tipos​

Cargando demo...
Ver código

Configuración Personalizada​

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

Ejemplo Completo​

Cargando demo...
Ver código

Buenas Prácticas​

Hacer​

  • Usa optimización automática para reducir tamaño de archivos
  • Configura maxWidth y maxHeight según el uso (perfil: 500px, portada: 1920px)
  • Implementa validación de tamaño en el cliente antes de subir
  • Usa object-fit: contain para logos y elementos que no deben recortarse
  • Proporciona feedback visual durante la optimización
  • Restringe tipos de archivo con accept

Evitar​

  • No desactives optimización sin razón justificada
  • No permitas imágenes muy grandes sin validación
  • No olvides validar dimensiones mínimas cuando sea relevante
  • No uses quality muy baja (menor que 0.7) para imágenes importantes
  • No omitas manejo de errores de optimización

Integración con Backend​

Envío con FormData​

async uploadImage() {
const formData = new FormData();
const image = this.form.value.avatar;

if (image instanceof File) {
formData.append('avatar', image);

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

Con Información Adicional​

async uploadWithMetadata() {
const formData = new FormData();
const image = this.form.value.profilePicture;

if (image instanceof File) {
formData.append('image', image);
formData.append('type', 'profile');
formData.append('userId', this.userId);

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

Accesibilidad​

  • El componente usa un <input type="file"> nativo con el accept de la configuración
  • Los botones tienen atributos title para tooltips descriptivos
  • El estado disabled previene interacciones cuando está deshabilitado
  • La imagen de preview tiene alt text apropiado

Personalización Avanzada​

Token de Angular​

TDN_INPUT_IMAGE_DEFAULT_SETTINGS_TOKEN​

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

import {
TDN_INPUT_IMAGE_DEFAULT_SETTINGS,
TDN_INPUT_IMAGE_DEFAULT_SETTINGS_TOKEN,
TdnInputImageSettings
} from '@tiendana/ngx-core/forms';
import { bootstrapApplication } from '@angular/platform-browser';

const customImageSettings: TdnInputImageSettings = {
...TDN_INPUT_IMAGE_DEFAULT_SETTINGS,
objectFit: 'contain',
optimize: {
...TDN_INPUT_IMAGE_DEFAULT_SETTINGS.optimize,
enable: true,
maxWidth: 1200,
maxHeight: 1200,
quality: 0.85
},
accept: ['.png', '.jpg', '.jpeg', '.webp']
};

bootstrapApplication(AppComponent, {
providers: [
{
provide: TDN_INPUT_IMAGE_DEFAULT_SETTINGS_TOKEN,
useValue: customImageSettings
}
]
});

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_IMAGE_DEFAULT_SETTINGS,
TDN_INPUT_IMAGE_DEFAULT_SETTINGS_TOKEN
} from '@tiendana/ngx-core/forms';

@Component({
selector: 'app-products-section',
providers: [
{
provide: TDN_INPUT_IMAGE_DEFAULT_SETTINGS_TOKEN,
useValue: {
...TDN_INPUT_IMAGE_DEFAULT_SETTINGS,
optimize: {
...TDN_INPUT_IMAGE_DEFAULT_SETTINGS.optimize,
enable: true,
maxWidth: 800,
maxHeight: 800,
quality: 0.9
}
}
}
],
template: `
<!-- Todos los TdnInputImage aquí heredarán esta configuración -->
`
})
export class ProductsSectionComponent {}

Valores Predeterminados del Token​

Si no se proporciona configuración, el componente usa estos valores (exportados también como TDN_INPUT_IMAGE_DEFAULT_SETTINGS; la fábrica del token clona icons, optimize y accept):

{
removeText: 'Remover imagen',
uploadText: 'Seleccionar imagen',
procesingText: 'Procesando...',
label: '',
objectFit: 'cover',
classes: '',
accept: ['.png', '.jpg', '.jpeg', '.webp'],
optimize: {
enable: true,
strict: true,
maxWidth: 1920,
maxHeight: Infinity,
quality: 1.0
},
icons: {
toolbarIcon: TDN_ICON_TOOLBAR_IMAGE,
upload: TDN_ICON_UPLOAD_IMAGE,
clear: TDN_ICON_CLEAR
}
}

Componentes Relacionados​