Tabla de Contenidos

8. Angular: Material

En este tema vamos a crear un proyecto de Angular y usar en sus páginas los componentes de Angular Material: botones, cards, tabs y tablas.

Crear una aplicación de Angular

npm install  @angular/cli@20 -g

ng new prueba

Las preguntas que hacen se responden de la siguiente forma:

Establecer el idioma y moneda

Una cosa importante que siempre hay que hacer en un proyecto de Angular es definir que el idioma y la moneda es 'es-ES' y 'EUR' para ello modificaremos el fichero app.config.ts

import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';

import localeEs from '@angular/common/locales/es';
import { registerLocaleData } from '@angular/common';
import { LOCALE_ID,DEFAULT_CURRENCY_CODE } from '@angular/core';

registerLocaleData(localeEs);

export const appConfig: ApplicationConfig = {
  providers: [
    provideBrowserGlobalErrorListeners(),
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    {provide: LOCALE_ID, useValue: 'es-ES' },
    {provide: DEFAULT_CURRENCY_CODE, useValue: 'EUR' }
  ]
};

Ejecutar la App

ng serve

Modificar la página de inicio

<style>
</style>
 
<h1 >Hola mundo</h1>
 
<button >
  Aceptar
</button>
 
<router-outlet />

Los dos ficheros importantes son:

import { Component, signal } from '@angular/core';
import { RouterOutlet } from '@angular/router';


@Component({
  selector: 'app-root',
  imports: [RouterOutlet],
  templateUrl: './app.html',
  styleUrl: './app.scss'
})
export class App {
  protected readonly title = signal('prueba');


}

<style>
</style>
 
<h1 >Hola mundo</h1>
 
<button >
  Aceptar
</button>
 
<router-outlet />

Añadir CSS en Angular

Para añadir estilos CSS en Angular se usa el fichero de SASS que está en src/styles.scss donde se indican los estilos globales de la App. Aunque también cada componente tiene sus propios estilos.

Por otro lado si queremos añadir otros ficheros CSS o SASS deberemos añadirlos en el JSON de angular.json del raíz. En el nodo /projects/EjemploComponentesAngular/architect/build/options/styles Siendo EjemploComponentesAngular el nombre del proyecto.

Lo mismo se aplica a JavaScript que se añade en /projects/EjemploComponentesAngular/architect/build/options/scripts

Usar Bootstrap en Angular

Por ejemplo para usar Bootstrap junto a su JavaScript se haría de la siguiente forma:

npm install bootstrap@v5.3.8

Eso descargará bootstrap en node_modules/bootstrap/

Y ahora añadir el CSS y JavaScript en angular.json:

"build": {
    "styles": [
        "node_modules/bootstrap/dist/css/bootstrap.min.css",
        "src/styles.scss"
     ],
     "scripts": [
         "node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
     ]
}

Usar Tailwind CSS en Angular

Para usar Tailwind CSS en Angular hay que seguir la guía Install Tailwind CSS with Angular - Tailwind CSS

Los pasos son:

npm install tailwindcss @tailwindcss/postcss

Si da error la instalación añadir --force al final de la línea

{
  "plugins": {
    "@tailwindcss/postcss": {}
  }
}

@use "tailwindcss";

Añadir Angular Material

La librería que vamos a usar en este módulo es Angular Material

ng add @angular/material

Las preguntas que hacen se responden de la siguiente forma:

Usar Angular Material

Para usar un componente,primero debes importarlo en TypeScript.

Lo primero es buscar el componente en https://material.angular.dev/components/categories y una vez en el componente copiar el import que hay en la pestaña API.

Veamos el ejemplo con el componente Button.

import {MatButtonModule} from '@angular/material/button';

  imports: [RouterOutlet,MatButtonModule],

El fichero app.ts debe quedar así:

import { Component, signal } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import {MatButtonModule} from '@angular/material/button';

@Component({
  selector: 'app-root',
  imports: [RouterOutlet, MatButtonModule],
  templateUrl: './app.html',
  styleUrl: './app.scss'
})
export class App {
  protected readonly title = signal('EjemploComponentesAngular');



}

<style>
</style>
 
<h1 >Hola mundo</h1>
 
<button matButton>
  Aceptar
</button>
 
<router-outlet />

Botones

El atributo matButton admite un valor para elegir el estilo del botón.

<style>
</style>
 
<h1 >Hola mundo</h1>
 
<button matButton="filled">
  Aceptar
</button>
 
<router-outlet />

Los estilos que hay son:

<button matButton="filled">Pagar carrito</button>
<button matButton="outlined">Seguir comprando</button>
<button matButton>Cancelar</button>

Vuelve a los ejemplos que hay en Button y prueba otros estilos de botones

Iconos

Prueba ahora a añadir un icono de Angular Material; para ello ve a https://material.angular.dev/components/icon/overview

Y fíjate que ahora ya no se añade un atributo a una etiqueta HTML sino que directamente es la etiqueta mat-icon.

import {MatIconModule} from '@angular/material/icon';

<mat-icon>shopping_cart</mat-icon>

<button matIconButton>
  <mat-icon>delete</mat-icon>
</button>

El nombre del icono es el que aparece en Material Symbols.

Cards

Una card agrupa la información de una cosa: un producto, una noticia, un usuario…

import {MatCardModule} from '@angular/material/card';

<mat-card appearance="outlined" style="max-width: 300px">
  <mat-card-header>
    <mat-card-title>Monitor Acer Nitro 23.8"</mat-card-title>
    <mat-card-subtitle>89,99 €</mat-card-subtitle>
  </mat-card-header>
  <img mat-card-image src="https://logongas.es/lib/exe/fetch.php?cache=&media=clase:daw:diw:monitor.webp">
  <mat-card-content>
    <p>Monitor FHD de 200Hz con FreeSync Premium y HDR10.</p>
  </mat-card-content>
  <mat-card-actions>
    <button matButton="filled">Comprar</button>
    <button matButton>Ver detalles</button>
  </mat-card-actions>
</mat-card>

Las partes de la card son:

Más información: Card

Tabs

Las pestañas (tabs) muestran distinto contenido en el mismo sitio, una pestaña cada vez.

import {MatTabsModule} from '@angular/material/tabs';

<mat-tab-group>
  <mat-tab label="Descripción">
    <p>Monitor FHD de 200Hz con FreeSync Premium y HDR10.</p>
  </mat-tab>
  <mat-tab label="Especificaciones">
    <p>23.8 pulgadas, panel VA, 1920x1080.</p>
  </mat-tab>
  <mat-tab label="Opiniones">
    <p>4,6 de 5 en 1472 opiniones.</p>
  </mat-tab>
</mat-tab-group>

Más información: Tabs

Tablas

La tabla de Material no se escribe fila a fila: se le pasa un array con los datos y se define cómo se muestra cada columna.

import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import {MatTableModule} from '@angular/material/table';

@Component({
  selector: 'app-root',
  imports: [RouterOutlet, MatTableModule],
  templateUrl: './app.html',
  styleUrl: './app.scss'
})
export class App {

  columnas: string[] = ['nombre', 'precio', 'stock'];

  productos = [
    {nombre: 'Monitor Acer Nitro 23.8"', precio: 89.99, stock: 12},
    {nombre: 'Teclado mecánico', precio: 49.90, stock: 0},
    {nombre: 'Ratón inalámbrico', precio: 19.95, stock: 34},
  ];

}

<table mat-table [dataSource]="productos">

  <ng-container matColumnDef="nombre">
    <th mat-header-cell *matHeaderCellDef>Nombre</th>
    <td mat-cell *matCellDef="let producto">{{producto.nombre}}</td>
  </ng-container>

  <ng-container matColumnDef="precio">
    <th mat-header-cell *matHeaderCellDef>Precio</th>
    <td mat-cell *matCellDef="let producto">{{producto.precio}}</td>
  </ng-container>

  <ng-container matColumnDef="stock">
    <th mat-header-cell *matHeaderCellDef>Stock</th>
    <td mat-cell *matCellDef="let producto">{{producto.stock}}</td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="columnas"></tr>
  <tr mat-row *matRowDef="let fila; columns: columnas;"></tr>
</table>

Las piezas son:

Para no mostrar una columna o cambiar el orden no hay que tocar las ng-container, solo el array columnas.

Más información: Table

Ejercicios

Ejercicio 1

Crea una página de una tienda que tenga: