====== 8. Angular: Material ======
En este tema vamos a crear un proyecto de Angular y usar en sus páginas los componentes de [[https://material.angular.dev/|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
* Navegar a [[http://localhost:4200]]
===== Modificar la página de inicio =====
* Modifica el fichero ''app.html'' de forma que quede así:
Hola mundo
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');
}
Hola mundo
===== 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:
* Descarga bootstrap. Para ello ver la última versión en ''https://www.npmjs.com/package/bootstrap?activeTab=versions''
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 [[https://tailwindcss.com/|Tailwind CSS]] en Angular hay que seguir la guía [[https://tailwindcss.com/docs/installation/framework-guides/angular|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 [[https://postcss.org/|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 [[https://material.angular.dev/|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 [[https://material.angular.dev/components/button/overview|Button]].
* Navega a [[https://material.angular.dev/components/button/overview|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''
Hola mundo
===== 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.
Hola mundo
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.
Vuelve a los ejemplos que hay en [[https://material.angular.dev/components/button/overview|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:
shopping_cart
* ''matIconButton'': Botón que solo tiene un icono.
El nombre del icono es el que aparece en [[https://fonts.google.com/icons|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:
Monitor Acer Nitro 23.8"89,99 €
Monitor FHD de 200Hz con FreeSync Premium y HDR10.
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: [[https://material.angular.dev/components/card/overview|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:
Monitor FHD de 200Hz con FreeSync Premium y HDR10.
23.8 pulgadas, panel VA, 1920x1080.
4,6 de 5 en 1472 opiniones.
* ''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: [[https://material.angular.dev/components/tabs/overview|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:
Nombre
{{producto.nombre}}
Precio
{{producto.precio}}
Stock
{{producto.stock}}
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: [[https://material.angular.dev/components/table/overview|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".