Angular Tutorial: Implementing Sidenav Toggling with Icons in Multiple Components

Currently, I am in the process of creating a homepage with a toggleable sidenav. I have successfully implemented the functionality, but I am facing an issue. When the sidenav is closed, I still want to display the icons on the left-hand side instead of icons with text (when opened). My setup involves three components: app, header, and side-nav.

The toggle button is located in the header component, and I have set up an event binding to make the text in the sideNav disappear when toggled. However, the problem is that the page does not adjust accordingly, leading to the sidenav remaining the same size but with less text.

I am unsure whether this issue stems from TypeScript or something related to CSS.

header.html

<button mat-icon-button (click)="toggleSideNav()"><mat-icon>menu</mat-icon></button>

header.ts

@Output() onToggleSideNav: EventEmitter<any> = new EventEmitter();

toggleSideNav() {
    this.onToggleSideNav.emit();
}

app.html

<mat-drawer-container>
    <mat-drawer mode="side" [opened]=true>
        <app-side-nav [isExpanded]='sideNavOpen'></app-side-nav>
    </mat-drawer>
    <mat-drawer-content>
        <app-header (onToggleSideNav)='sideNavToggler()'></app-header>
        <router-outlet></router-outlet>
    </mat-drawer-content>
</mat-drawer-container>

app.ts

sideNavOpen: boolean = true;
sideNavToggler() {
    this.sideNavOpen = !this.sideNavOpen;
}

sidenav.html

<mat-nav-list>
    <a mat-list-item routerLink="/home" routerLinkActive="list-item-active">
        <mat-icon>home</mat-icon>
        <h4 mat-line *ngIf="isExpanded">Home</h4>
    </a>
</mat-nav-list>

sidenav.ts

@Input() isExpanded: boolean = true;

https://i.sstatic.net/FeWQj.png

Answer №1

After analyzing your code...

  1. It seems that the sidenav.ts file has a hardcoded Input value, which means it will always be overwritten with a "true" value regardless of what it initially holds. To avoid this, leave it unset and let it receive its dynamic value during initialization using @Input() isExpanded: boolean;. If you need to handle an inputted value, you can do so in the ngOnChanges() method.
  2. The original <mat-drawer> component does not have a hardcoded width and can adjust to the size of its inner content (https://material.angular.io/components/sidenav/overview#sidenav-autosize). It seems like your app-side-nav component's template width is not changing as expected. Make sure that the width of the template changes according to the value of isExpanded. You can achieve this by using the following:
<div id="app-side-nav" [ngClass]="{'expandedWidth': isExpanded, 
  'autoWidth': !isExpanded}">
...
</div>

Ensure that your CSS matches the following:

.expandedWidth {
  width: 200px;
}
.autoWidth{
  width: auto;
}
  1. Consider enhancing the user experience by adding transitions to the width changes in your app. By adding transitions, your app will appear smoother during changes. For example, you can add a transition to the parent element of <app-side-nav> that lasts for 1 second and uses the 'ease-out' timing function: transition: all 1s ease-out;.

I hope this information proves helpful.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Enhance your Primeng split button with an added icon when selected

Is it possible to add a tick icon when the user selects the click option in a split button? Any advice on how to achieve this would be appreciated. Thank you. For example, similar to the image below: https://i.stack.imgur.com/owOgE.png ...

Issue with compatibility of Angular Elements across Chrome and IE11 at the same time

Experimenting with Angular Elements has led me to focus on achieving optimal browser compatibility. However, I have encountered a roadblock where adding an IE polyfill for Shadow DOM breaks the Element in Chrome. Initially, I faced the error 'Failed ...

Tips for creating a breadcrumb navigation component in Angular inspired by the design of Windows File Explorer

When there are too many items in the breadcrumbs, I want to hide the older ones and only display the most recent ones. Here's a visual example of how it's done on Windows: view here ...

What is the best way to output a JSX element using an inline switch statement?

I have been attempting to use an inline switch in order to return an element, but all I am getting is an empty <span> </span>. What could be the issue here? getRowTdForHeader: (header: string, entry: response) => { return (< ...

What is the best way to mock a Typescript interface or type definition?

In my current project, I am working with Typescript on an AngularJS 1.X application. I make use of various Javascript libraries for different functionalities. While unit testing my code, I am interested in stubbing some dependencies using the Typings (inte ...

Angular click switch Component keeps track of its previous state

I recently developed an Angular component that consists of a button and an icon. One key requirement is for each instance of this component to retain its own status. For example, let's say we have three instances in the app.component.html: <app-v ...

Having trouble sending HTTP requests in Angular 6

I am currently facing an issue in my Angular application while trying to send an HTTP POST request to a Spring RESTful API. Despite my attempts, I have not been able to succeed and I do not see any error response in the browser console. Below is a snippet ...

Why won't angular ng update work? Is there a timeout issue with the proxy settings?

I am encountering a problem with my angular project. When I am at work, I use a proxy, but when I am at home, I do not. So I added the following: npm config set https-proxy http://xx.xx.xx.xx:9090 npm config set proxy http://xx.xx.xx.xx:9090 and it works ...

How to send an ngFor element to a pipe in Angular 2 as an argument?

When attempting to pass an ngFor item into a pipe as a parameter, I encountered an error: Error: Call to Node module failed with error: Error: Template parse errors: TypeError: Cannot read property 'toUpperCase' of undefined ("{{name}} ng-cont ...

Angular Material sidebar small version with dropdown menus

I am currently using Angular 5 in conjunction with Material design. My application features a side navigation menu with an angular material navigation drawer mini variant, where the items are hidden, leaving only the icons when collapsed (see image). My g ...

Automatically injecting dependencies in Aurelia using Typescript

Recently, I started working with Typescript and Aurelia framework. Currently, I am facing an issue while trying to implement the @autoinject decorator in a VS2015 ASP.NET MVC 6 project. Below is the code snippet I am using: import {autoinject} from "aure ...

An entire line of boxes has been checked off

Currently, I am working on adding an additional column with checkboxes to the Mat table example. However, I noticed that when I click on one checkbox in a column, the checkboxes in other columns also get selected. How can I implement this so that only th ...

Modifying Array Values in Angular 7

I am currently dealing with a complex array where questions and their corresponding answers are retrieved from a service. Upon receiving the array, I aim to set the 'IsChecked' attribute of the answers to false. The snippet of code I have written ...

Angular script error when running 'npm run' on select computers causing Unix command issues for some users but not all

Recently, I've encountered a puzzling issue at my workplace that has been difficult to diagnose. We utilize scripts in npm within the Angular framework to launch a local server instance. Strangely enough, some of my colleagues' computers are thro ...

Having difficulty subscribing to multiple observables simultaneously using withLatestFrom

I am facing an issue where I have three observables and need to pass their values to a service as parameters. I attempted to do this using WithLatestFrom(), but it works fine only when all values are observables. this.payment$.pipe( withLatestFrom(this.fir ...

Is it possible to enable autocomplete for JavaScript generated code in .proto files?

I recently created a basic .proto file with the following content: syntax = "proto3"; message Event { optional string name = 1; } After downloading and installing the protoc linux compiler (protoc-3.19.3-linux-x86_64.zip) on my local machine, ...

Understanding the behavior of the enter key in Angular and Material forms

When creating forms in my MEAN application, I include the following code: <form novalidate [formGroup]="thesisForm" enctype="multipart/form-data" (keydown.enter)="$event.preventDefault()" (keydown.shift.enter)="$ev ...

Having trouble getting webpack to transpile typescript to ES5?

Despite following official guides and various tutorials, I am still facing an issue with compiling my code to ES5 using TypeScript and webpack. The problem is that the final bundle.js file always contains arrow functions. Here is a snippet from my webpack ...

Authenticating passports without the need for a templating engine

Seeking assistance with integrating Passport authentication using the Google strategy. Authentication with Google works, but upon returning to the express server, I aim to redirect to a client-side page along with profile data without utilizing a templatin ...

I am attempting to update the URL of an iframe dynamically, but I am encountering an issue: the Error message stating that an Unsafe value is being

Currently, I am attempting to dynamically alter the src of an iframe using Angular 2. Here is what I have tried: HTML <iframe class="controls" width="580" height="780" src="{{controllerSrc}}" frameborder="0" allowfullscreen></iframe> COMPONE ...