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.
npm install @angular/cli@20 -g
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)? : NDo you want to create a 'zoneless' application without zone.js? : NWhich AI tools do you want to configure with Angular best practices? : None
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' }
]
};
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.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 />
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
Por ejemplo para usar Bootstrap junto a su JavaScript se haría de la siguiente forma:
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"
]
}
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
--force al final de la línea
.postcssrc.json en el raíz del proyecto con el siguiente contenido:
{
"plugins": {
"@tailwindcss/postcss": {}
}
}
./src/styles.scss añadir Tailwind
@use "tailwindcss";
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:
Select a pair of starter prebuilt color palettes for your Angular Material theme : Azure/BluePara 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.
API, copia lo siguiente:
import {MatButtonModule} from '@angular/material/button';
app.ts y pega lo que acabas de copiar.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');
}
matButton
<style> </style> <h1 >Hola mundo</h1> <button matButton> Aceptar </button> <router-outlet />
El atributo matButton admite un valor para elegir el estilo del botón.
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
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.
imports de app.ts, igual que MatButtonModule:
import {MatIconModule} from '@angular/material/icon';
<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.
Una card agrupa la información de una cosa: un producto, una noticia, un usuario…
imports de app.ts, igual que MatButtonModule:
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:
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
Las pestañas (tabs) muestran distinto contenido en el mismo sitio, una pestaña cada vez.
imports de app.ts, igual que MatButtonModule:
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>
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
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.
.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},
];
}
<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.ng-container, solo el array columnas.
Más información: Table
Crea una página de una tienda que tenga: