Herramientas de usuario

Herramientas del sitio


clase:daw:diw:angular-material

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

  • Instala Angular CLI v20

npm install  @angular/cli@20 -g

  • Crea una aplicación de Angular

ng new prueba

Las preguntas que hacen se responden de la siguiente forma:

  • Which stylesheet format would you like to use? : Sass (SCSS)
  • Do you want to enable Server-Side Rendering (SSR) and Static Site Generation (SSG/Prerendering)? : N
  • Do you want to create a 'zoneless' application without zone.js? : N
  • Which AI tools do you want to configure with Angular best practices? : None

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

  • Dentro de la carpeta del proyecto, ejecutar

ng serve

Modificar la página de inicio

  • Modifica el fichero app.html de forma que quede así:

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

Los dos ficheros importantes son:

  • app.ts: Es el fichero TypeScript que contiene la lógica del componente. Es la parte que hay que programar.
  • app.html: Es el fichero HTML que contiene como se muestra ese componente.
  • Vamos a dejar el componente de app de la siguiente forma

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:

  • Descargar Tailwind y PostCSS

npm install tailwindcss @tailwindcss/postcss

Si da error la instalación añadir --force al final de la línea
  • Añadir Tailwind a PostCSS creando el fichero .postcssrc.json en el raíz del proyecto con el siguiente contenido:

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

  • En la página de estilos SASS ./src/styles.scss añadir Tailwind

@use "tailwindcss";

Añadir Angular Material

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

  • Para añadirla al proyecto se usa:

ng add @angular/material

Las preguntas que hacen se responden de la siguiente forma:

  • Select a pair of starter prebuilt color palettes for your Angular Material theme : Azure/Blue

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.

  • Navega a Button y pincha en la pestaña de API, copia lo siguiente:

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

  • Ve al fichero app.ts y pega lo que acabas de copiar.
  • En el array de imports añade lo que has importado; que es MatButtonModule:

  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');



}

  • Ahora ya puedes transformar un botón "normal" en un botón de Angular Material añadiendo el atributo matButton

<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.

  • Cambia para que sea matButton="filled" y verás como cambia el estilo del botón.

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

Los estilos que hay son:

  • matButton: Botón de solo texto.
  • matButton="filled": Botón relleno con el color principal.
  • matButton="tonal": Botón relleno con un color más suave.
  • matButton="outlined": Botón con borde y sin relleno.
  • matButton="elevated": Botón con sombra.

<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.

  • Importa el módulo y añádelo al array de imports de app.ts, igual que MatButtonModule:

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

  • Y úsalo en el HTML:

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

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

  • matIconButton: Botón que solo tiene un icono.

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…

  • Importa el módulo y añádelo al array de imports de app.ts, igual que MatButtonModule:

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

  • Y úsalo en el HTML:

<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:

  • mat-card-header: La cabecera con mat-card-title y mat-card-subtitle.
  • mat-card-image: Atributo para una imagen que ocupa todo el ancho de la card.
  • mat-card-content: El contenido.
  • mat-card-actions: Los botones de la card.

Más información: Card

Tabs

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

  • Importa el módulo y añádelo al array de imports de app.ts, igual que MatButtonModule:

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

  • Y úsalo en el HTML:

<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>

  • mat-tab-group: El conjunto de pestañas.
  • mat-tab: Cada pestaña. El texto de la pestaña va en label y su contenido dentro de la etiqueta.

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.

  • Importa el módulo y define los datos y las columnas en el .ts:

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},
  ];

}

  • En el HTML se define cada columna y luego las filas:

<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:

  • [dataSource]: El array con los datos. Cada elemento es una fila.
  • matColumnDef: Define una columna con un nombre. Dentro van su cabecera (mat-header-cell) y su celda (mat-cell).
  • *matCellDef="let producto": producto es el elemento del array de esa fila.
  • *matHeaderRowDef y *matRowDef: Las columnas que se muestran y en qué orden. Es el array columnas del .ts.
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:

  • Una tabla con al menos 5 productos y las columnas nombre, precio y stock.
  • Debajo, una card por cada uno de 3 productos destacados con imagen, nombre, precio y los botones "Comprar" (relleno) y "Ver detalles" (solo texto).
  • Unas tabs con "Descripción", "Especificaciones" y "Opiniones".
clase/daw/diw/angular-material.txt · Última modificación: por claude