Resumen: mostrar cómo crear un menú de navegación con Angular Material; es decir, implementar un navigation drawer con el menú a la izquierda (que se puede ocultar y mostrar con un botón) y el contenido a la derecha.
Para implementar un navigation drawer o cajón de navegación en Angular Material vamos a usar combinar algunos componentes. Entre ellos:
- Mat Toolbar: la barra que estará en la parte superior y tendrá el título de la app de Angular así como un botón para mostrar/ocultar el cajón de navegación
- Mat Sidenav Container: el contenedor de lo que veremos a continuación
- Mat Sidenav: el menú con los enlaces, es decir, el cajón de navegación
- Mat Sidenav Content: el contenido que se irá mostrando e inyectando dependiendo de la sección
Nota: recuerda que para esto debes tener un proyecto de Angular y haberle agregado Angular Material.
Si quieres ver el ejemplo terminado haz click aquí.
Menú de navegación con Angular Material
Para usar este diseño de Material Design importa los siguientes componentes:
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatListModule } from '@angular/material/list';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { MatExpansionModule } from '@angular/material/expansion';
El MatIconModule
es para mostrar algunos iconos, el de MatButtonModule
para los botones y finalmente el MatExpansionModule
para mostrar elementos que se expanden.
Después en @NgModule
indica los imports
.
@NgModule({
// ...
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MatSidenavModule,
MatToolbarModule,
MatListModule,
MatIconModule,
MatButtonModule,
MatExpansionModule,
],
// ...
})
El contenedor para el menú de navegación con Angular Material
Como lo dije, esto se divide en una barra; el contenido y el menú. A grandes rasgos se ve así (he encerrado todo en un div
para darle estilo más tarde):
<div class="contenedor-padre">
<mat-toolbar class="barra" color="warn">
<mat-toolbar-row>
<!--Aquí el contenido de la barra-->
</mat-toolbar-row>
</mat-toolbar>
<mat-sidenav-container class="contenido">
<mat-sidenav>
<!--Aquí van todos los mat-nav-list -->
</mat-sidenav>
<mat-sidenav-content>
<!--El contenido de la sección-->
</mat-sidenav-content>
</mat-sidenav-container>
</div>
Lo he colocado en ese contenedor para estilizar y asignar los espacios usando flexbox:
.contenedor-padre {
display: flex;
flex-flow: column;
height: 100%;
}
Toolbar
Comenzamos con la barra, como este es un ejemplo para otro post que haré más tarde que tratará sobre MySQL y PHP con Angular el título es sobre eso. Se ve así:
<mat-toolbar class="barra" color="warn">
<mat-toolbar-row>
<button (click)="cajon.toggle()" mat-icon-button>
<mat-icon>menu</mat-icon>
</button>
<span>
CRUD Angular con PHP y MySQL
</span>
<span>
<a mat-stroked-button href="https://parzibyte.me/blog">By Parzibyte</a>
</span>
</mat-toolbar-row>
</mat-toolbar>
He colocado el botón que oculta y muestra el menú; después el título y más tarde mi nombre. Se ve así:
El estilo de la barra es:
.barra {
flex: 0 1 auto;
}
El contenedor del menú y el contenido
Como vamos a ir por partes, primero quiero mostrar los estilos del contenedor que será hermano de la barra:
.contenido {
flex: 1 1 auto;
}
La barra lateral
Después veamos la barra lateral que será ahora sí el menú:
<mat-sidenav style="min-width: 300px;" #cajon mode="side" opened>
<mat-nav-list>
<a mat-list-item href='#'>
<mat-icon color="accent">add</mat-icon>
Agregar mascota
</a>
<a mat-list-item href='#'>
<mat-icon color="primary">pets</mat-icon>
Ver mascotas
</a>
</mat-nav-list>
<mat-accordion>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
Más
</mat-panel-title>
</mat-expansion-panel-header>
<mat-nav-list>
<a mat-list-item href='#'>
Acerca de
</a>
<a mat-list-item href='#'>
Ayuda
</a>
</mat-nav-list>
</mat-expansion-panel>
</mat-accordion>
</mat-sidenav>
Como ves tengo una referencia con #cajon
(y en la barra invoco a toggle
cuando se hace click en el botón).
Tengo mis elementos y en la parte inferior un panel de expansión que si bien no es obligatorio ejemplifica bien cómo podríamos tener elementos colapsables.
El único estilo que tiene es que su ancho mínimo es de 300px
.
El contenido
Finalmente el contenido es así:
<mat-sidenav-content class="padding-10">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Iste quam vero
tempore architecto laborum. Et labore consequatur necessitatibus, dicta
vitae perferendis itaque veritatis explicabo! Id sapiente perferendis
iusto omnis provident?</p>
<p>Cumque assumenda error vitae consequatur numquam tenetur molestias
impedit est quaerat molestiae! Officia, expedita laborum unde quasi eius
nemo nulla molestiae enim accusantium minima error soluta eaque numquam
nihil quibusdam?</p>
<p>Dolores deleniti rerum illo optio, voluptatibus pariatur molestiae, at
earum amet, maxime porro totam! Numquam magni eius, autem voluptatum
optio consectetur quisquam magnam saepe officia ipsa consequuntur, quis
quam cum.</p>
<p>Suscipit animi fugit in cumque ipsum nesciunt ullam vitae aliquid
recusandae omnis quam unde consequuntur, maiores totam. Quas, molestiae
consequuntur, suscipit nisi atque doloribus, eligendi ipsam explicabo
eius culpa totam?</p>
<p>Vitae amet dolores consequatur eligendi blanditiis molestias delectus
fugiat eum ipsa vel distinctio, perspiciatis illo dolorum, maiores non
ratione? Quos soluta sed laboriosam corporis ab ducimus inventore,
libero dignissimos fuga.</p>
<p>Facere fugiat dolore, numquam optio fuga hic, accusantium sapiente
porro dolor laboriosam maiores aut fugit velit ab vel dolorum esse
libero. Consequatur libero suscipit sunt placeat. Consequuntur, hic.
Hic, mollitia.</p>
<p>Quod et fugit voluptates voluptas dolores nobis cum ipsam temporibus
non, dolorem quidem voluptatibus, ut pariatur, totam officiis incidunt
deleniti repellendus debitis sit velit! Voluptates, vitae perferendis.
Dolor, amet ipsam.</p>
<p>Necessitatibus quaerat quas aliquam maxime quos enim ad perspiciatis
eaque incidunt unde. Deleniti voluptatum quidem neque quos consequatur
veniam, alias sit voluptatem, libero nulla, debitis minima rem qui?
Vitae, adipisci.</p>
<p>Vitae doloribus aperiam perferendis corrupti sit, recusandae enim
veniam consequatur voluptas dolorum porro ducimus mollitia provident,
illum inventore asperiores aspernatur voluptatum tempore, dolor magni
consequuntur assumenda beatae error! Nulla, repellendus.</p>
<p>Omnis, quod maxime! Beatae dignissimos ea tempora repellat vel, aliquam
minima error enim non in? Soluta quo, labore veritatis mollitia
exercitationem laboriosam doloribus corrupti. Totam, voluptatum. Et
corrupti suscipit dignissimos.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Atque nobis
delectus officia fugit porro consectetur odit vitae corrupti incidunt
iste pariatur, quo, error aspernatur repellat tenetur? Fugiat expedita
non a!</p>
<p>Dicta nostrum laudantium quo aliquid commodi! Facilis vero quis error
et tempora nobis dicta maxime aspernatur, ipsam quam doloremque
voluptatem officia quia beatae culpa ducimus aperiam atque sapiente
consectetur praesentium!</p>
<p>Nisi possimus quis quae fuga, quos obcaecati suscipit est nemo sapiente
exercitationem dolores accusamus unde magni quod, veritatis iste totam
provident quaerat ad, voluptatum placeat qui adipisci libero rerum.
Quis.</p>
<p>Similique veritatis ipsa laboriosam officiis rem ab illo temporibus
ipsum ipsam explicabo, quaerat vero eius laudantium blanditiis ea porro
sequi eaque aspernatur recusandae, commodi facere. Dolorem quaerat
recusandae quo voluptatem.</p>
<p>Id eos ea explicabo facere ex qui quibusdam ipsam tempora
reprehenderit. Quos, animi? Beatae consectetur nam amet voluptatibus
culpa harum nisi ut nulla quisquam, facilis veritatis rem optio quam
voluptate.</p>
</mat-sidenav-content>
Con un padding de 10 px cuyo estilo es:
.padding-10 {
padding: 10px;
}
Poniendo todo junto
Así que para no hacer las cosas más largas primero tenemos la vista:
<div class="contenedor-padre">
<mat-toolbar class="barra" color="warn">
<mat-toolbar-row>
<button (click)="cajon.toggle()" mat-icon-button>
<mat-icon>menu</mat-icon>
</button>
<span>
CRUD Angular con PHP y MySQL
</span>
<span>
<a mat-stroked-button href="https://parzibyte.me/blog">By Parzibyte</a>
</span>
</mat-toolbar-row>
</mat-toolbar>
<mat-sidenav-container class="contenido">
<mat-sidenav style="min-width: 300px;" #cajon mode="side" opened>
<mat-nav-list>
<a mat-list-item href='#'>
<mat-icon color="accent">add</mat-icon>
Agregar mascota
</a>
<a mat-list-item href='#'>
<mat-icon color="primary">pets</mat-icon>
Ver mascotas
</a>
</mat-nav-list>
<mat-accordion>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
Más
</mat-panel-title>
</mat-expansion-panel-header>
<mat-nav-list>
<a mat-list-item href='#'>
Acerca de
</a>
<a mat-list-item href='#'>
Ayuda
</a>
</mat-nav-list>
</mat-expansion-panel>
</mat-accordion>
</mat-sidenav>
<mat-sidenav-content class="padding-10">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Iste quam vero
tempore architecto laborum. Et labore consequatur necessitatibus, dicta
vitae perferendis itaque veritatis explicabo! Id sapiente perferendis
iusto omnis provident?</p>
<p>Cumque assumenda error vitae consequatur numquam tenetur molestias
impedit est quaerat molestiae! Officia, expedita laborum unde quasi eius
nemo nulla molestiae enim accusantium minima error soluta eaque numquam
nihil quibusdam?</p>
<p>Dolores deleniti rerum illo optio, voluptatibus pariatur molestiae, at
earum amet, maxime porro totam! Numquam magni eius, autem voluptatum
optio consectetur quisquam magnam saepe officia ipsa consequuntur, quis
quam cum.</p>
<p>Suscipit animi fugit in cumque ipsum nesciunt ullam vitae aliquid
recusandae omnis quam unde consequuntur, maiores totam. Quas, molestiae
consequuntur, suscipit nisi atque doloribus, eligendi ipsam explicabo
eius culpa totam?</p>
<p>Vitae amet dolores consequatur eligendi blanditiis molestias delectus
fugiat eum ipsa vel distinctio, perspiciatis illo dolorum, maiores non
ratione? Quos soluta sed laboriosam corporis ab ducimus inventore,
libero dignissimos fuga.</p>
<p>Facere fugiat dolore, numquam optio fuga hic, accusantium sapiente
porro dolor laboriosam maiores aut fugit velit ab vel dolorum esse
libero. Consequatur libero suscipit sunt placeat. Consequuntur, hic.
Hic, mollitia.</p>
<p>Quod et fugit voluptates voluptas dolores nobis cum ipsam temporibus
non, dolorem quidem voluptatibus, ut pariatur, totam officiis incidunt
deleniti repellendus debitis sit velit! Voluptates, vitae perferendis.
Dolor, amet ipsam.</p>
<p>Necessitatibus quaerat quas aliquam maxime quos enim ad perspiciatis
eaque incidunt unde. Deleniti voluptatum quidem neque quos consequatur
veniam, alias sit voluptatem, libero nulla, debitis minima rem qui?
Vitae, adipisci.</p>
<p>Vitae doloribus aperiam perferendis corrupti sit, recusandae enim
veniam consequatur voluptas dolorum porro ducimus mollitia provident,
illum inventore asperiores aspernatur voluptatum tempore, dolor magni
consequuntur assumenda beatae error! Nulla, repellendus.</p>
<p>Omnis, quod maxime! Beatae dignissimos ea tempora repellat vel, aliquam
minima error enim non in? Soluta quo, labore veritatis mollitia
exercitationem laboriosam doloribus corrupti. Totam, voluptatum. Et
corrupti suscipit dignissimos.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Atque nobis
delectus officia fugit porro consectetur odit vitae corrupti incidunt
iste pariatur, quo, error aspernatur repellat tenetur? Fugiat expedita
non a!</p>
<p>Dicta nostrum laudantium quo aliquid commodi! Facilis vero quis error
et tempora nobis dicta maxime aspernatur, ipsam quam doloremque
voluptatem officia quia beatae culpa ducimus aperiam atque sapiente
consectetur praesentium!</p>
<p>Nisi possimus quis quae fuga, quos obcaecati suscipit est nemo sapiente
exercitationem dolores accusamus unde magni quod, veritatis iste totam
provident quaerat ad, voluptatum placeat qui adipisci libero rerum.
Quis.</p>
<p>Similique veritatis ipsa laboriosam officiis rem ab illo temporibus
ipsum ipsam explicabo, quaerat vero eius laudantium blanditiis ea porro
sequi eaque aspernatur recusandae, commodi facere. Dolorem quaerat
recusandae quo voluptatem.</p>
<p>Id eos ea explicabo facere ex qui quibusdam ipsam tempora
reprehenderit. Quos, animi? Beatae consectetur nam amet voluptatibus
culpa harum nisi ut nulla quisquam, facilis veritatis rem optio quam
voluptate.</p>
</mat-sidenav-content>
</mat-sidenav-container>
</div>
Después los estilos:
.contenedor-padre {
display: flex;
flex-flow: column;
height: 100%;
}
.barra {
flex: 0 1 auto;
}
.contenido {
flex: 1 1 auto;
}
.padding-10 {
padding: 10px;
}
Al final tenemos lo siguiente:
Sobre el enrutador
Si estás usando el enrutador de Angular, coloca el router-outlet
dentro del mat-sidenav-content
. Algo así:
<mat-sidenav-content class="padding-10">
<router-outlet></router-outlet>
</mat-sidenav-content>