Display Templates
Paquetes: @tiendana/ngx-core/ui @tiendana/api-types
Componentes especializados para mostrar entidades de Tiendana con formato consistente y resaltado de búsqueda. Se usan como plantilla de ítem dentro de tdn-select o de forma independiente en listados.
Estos componentes usan tipos de @tiendana/api-types (Brand, Customer, Store, TerminalPOS, etc.), interfaces TypeScript basadas en los modelos reales de las bases de datos de Tiendana.
Características
✅ Un componente standalone por entidad, todos con OnPush y signal inputs
✅ Resaltado de coincidencias con highlightedText, con normalización de acentos
✅ Imágenes resueltas con cfSrc y fallback cuando la entidad no tiene imagen
✅ Tres tamaños (small, normal, large) en los templates con foto circular
Componentes Disponibles
Todos se importan desde @tiendana/ngx-core/ui.
| Selector | Clase | data | searchTerm | Otros inputs |
|---|---|---|---|---|
brand-display | BrandDisplayComponent | Brand | null | string | null (requerido) | - |
category-display | CategoryDisplayComponent | Category | undefined | null | string (requerido) | - |
country-display | CountryDisplayComponent | Country | string (opcional) | - |
country-phone-code-display | CountryPhoneCodeDisplayComponent | Country | string (opcional) | - |
customer-display | CustomerDisplayComponent | Customer | undefined | null | string (opcional) | size |
device-display | DeviceDisplayComponent | TerminalPOS | undefined | null | - | full |
employee-display | EmployeeDisplayComponent | ApplicationUser | undefined | null | string (opcional) | size |
payment-method-display | PaymentMethodDisplayComponent | PaymentMethod | undefined | null | string (opcional) | - |
store-display | StoreDisplayComponent | Store | undefined | null | string (opcional) | - |
supplier-display | SupplierDisplayComponent | Supplier | undefined | null | string (opcional) | size |
data es siempre requerido. country-display y country-phone-code-display construyen la URL de la bandera con getCloudfrontUrl a partir de code_1; el segundo muestra +{phone_code} y el nombre en español (name_es).
terminal-pos-displayEl template de dispositivos se llamaba terminal-pos-display (TerminalPosDisplayComponent). Desde ngx-core 0.8.0 es device-display (DeviceDisplayComponent): cambia el selector y el nombre de la clase. Ya no existe terminal-pos-display.
Tamaños
customer-display, employee-display y supplier-display aceptan size con los valores 'small' | 'normal' | 'large' (default 'normal'). El valor se aplica como clase del host y define el tamaño de la foto y de la fuente:
size | Foto | Fuente del nombre |
|---|---|---|
small | 24px | 12px |
normal | 40px | 14px |
large | 100px | 12px |
<customer-display [data]="customer" [searchTerm]="search()" size="small" />
<employee-display [data]="employee" size="large" />
La foto es circular, con un borde de 2px (--border-color) y, si la entidad no tiene imagen, usa assets/images/account_circle.svg.
supplier-display comparte los nombres de variable de customer-display (--customer-photo-size y --customer-font-size), no define unas propias.
Variables CSS
| Componente | Variable | Default |
|---|---|---|
brand-display, category-display | --brand-logo-size (en el img) | 30px |
country-display, country-phone-code-display | --img-size (en el img) | 20px |
customer-display, supplier-display | --customer-photo-size, --customer-font-size | según size |
employee-display | --employee-photo-size, --employee-font-size | según size |
payment-method-display | --pm-logo-size (en el img) | 20px |
Patrón Común
La mayoría comparte esta estructura: imagen a la izquierda y nombre con resaltado.
@Component({
selector: 'brand-display',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [HighlightedTextPipe, CfSrcDirective],
template: `
<img [cfSrc]="data()?.attachment" alt="Logo marca">
<div [innerHtml]="data()?.name | highlightedText : searchTerm() : true"></div>
`,
styleUrl: './brand-display.component.scss'
})
export class BrandDisplayComponent {
data = input.required<Brand | null>();
readonly searchTerm = input.required<string | null>();
}
store-display no lleva imagen: muestra el nombre (con resaltado) y debajo la dirección con la ciudad.
Uso
En Listados
@for (brand of brands(); track brand.id) {
<brand-display [data]="brand" [searchTerm]="searchTerm()" />
}
Dentro de tdn-select
<tdn-select formControlName="customer" [data]="customers()" simple labelKey="full_name">
<ng-template #listItem let-item="item" let-searchTerm="searchTerm">
<customer-display [data]="item" [searchTerm]="searchTerm" />
</ng-template>
</tdn-select>
Mira tdn-select para las plantillas disponibles (listItem, etc.).
Tablas
<table>
@for (customer of customers(); track customer.id) {
<tr>
<td>
<customer-display [data]="customer" [searchTerm]="tableSearch()" size="small" />
</td>
</tr>
}
</table>
Highlight de Búsqueda
Los templates llaman a highlightedText con el tercer parámetro en true (normalización de acentos):
data()?.name | highlightedText : searchTerm() : true
El pipe no escapa el término como expresión regular: ver la nota en highlightedText.
Personalización
Crea tus propios componentes display siguiendo el mismo patrón:
@Component({
selector: 'product-display',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [HighlightedTextPipe, CfSrcDirective],
template: `
<img [cfSrc]="data()?.image" alt="Producto">
<div [innerHtml]="data()?.name | highlightedText : searchTerm() : true"></div>
`
})
export class ProductDisplayComponent {
data = input.required<Product | null>();
searchTerm = input.required<string | null>();
}
Accesibilidad
- Los
altestán fijados en cada template (por ejemploLogo marca,Foto,Bandera del país). - Si necesitas un nombre accesible distinto, crea un template propio con el patrón anterior.