Animated Toggles In Angular 17
Published: 2024-01-18 03:43:15

by [Ugo Chukwuebuka](https://blog.openreplay.com/authors/ugo-chukwuebuka)


<blockquote><em>
A switcher or toggler is a user interface element that can be included in a website to enable users to choose from options. For example, in an application, a user can toggle between a dark or light theme or enable or disable a feature. In this article, you'll learn how to create an animated switcher using Angular, how it works, and how to use it in your application.
</em></blockquote>

<div style="background-color:#efefef; border-radius:8px; padding:10px; display:block;">
<hr/>
<h3><em>Session Replay for Developers</em></h3> 
<p><em>Uncover frustrations, understand bugs and fix slowdowns like never before with <strong><a href="https://github.com/openreplay/openreplay" target="_blank">OpenReplay</a></strong> — an open-source session replay suite for developers. It can be <strong>self-hosted</strong> in minutes, giving you complete control over your customer data.</em></p>
<img alt="OpenReplay" style="margin-top:5px; margin-bottom:5px;" width="768" height="400" src="https://raw.githubusercontent.com/openreplay/openreplay/main/static/openreplay-git-hero.svg" class="astro-UXNKDZ4E" loading="lazy" decoding="async">
<p><em>Happy debugging! <a href="https://openreplay.com" target="_blank">Try using OpenReplay today.</a></em><p>
<hr/>
</div>

Let's look briefly at the importance of having a switcher or toggler in your application.

* Modifications: With switchers, we can customize how we want certain features in our application to play out. For example, with switchers, we can select or toggle between languages, change background or color schemes like dark or light themes, and so much more.
* Live Updates: Like the word live updates, switchers allow users to see the changes they make when using switchers or togglers in real time. For example, in an application that implements dark and light mode features, users can see in real time what happens to the application when they toggle between the dark and light mode features.
* Accessibility: Using switchers in an application can give users with diverse needs smooth interactions with some features. For example, a user with high sensitivity to bright colors can use a switcher to select a darker color instead. Another example will be a user switching to their preferred language instead of the default application's language. This makes a diverse range of options accessible to users.

## Getting Started
We'll go through a practical example of using a switcher in an application. This will be how you can use a switcher to customize an element's colors or display in an application.

But before we start with the project, let's start with setting up our project, which is very important as it helps us install all the necessary packages we need for the project and build a good project structure.

If you don't already have Angular CLI installed on your system, use the code below:

```bash
# do this
npm install -g @angular/cli

# then this
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
```

This installs the latest version of Angular, which we currently use for this project.

Next, we create a new Angular app using the code below in your terminal:

```typescript
ng new switcher
```
Then, we create a switcher component in a switcher folder with the code below: 

```typescript
ng g c switcher/switcher 
``` 

Now that we have set up our project structure let's go ahead and create our color-themed animated switcher.

## Creating our Switcher Structure
In this section, we'll go through practical steps in creating our color-themed animated switcher. 

In your `switcher.component.html` file, enter the following code:

```html
<div class="">
  <section class="p-4 switcher-container" (click)="toggleSwitcherState()">
    <article
      class="switcher-circle-Container"
      [style.border]="switcherState ? '1px solid red' : '1px solid black'"
    >
      <div
        class="switcher-circle"
        [style.left]="switcherState ? 'calc(100px / 1.3)' : '1px'"
        [style.backgroundColor]="switcherState ? 'red' : 'black'"
      ></div>
    </article>

    <section class="text-center text-capitalise mt-2">
      <p>Switch Status: {{ switcherState }}</p>
    </section>
  </section>
</div>
```

The code above contains the structure of our switcher, has conditional styling, and shows the status of our switcher.

In your `switcher.component.ts` file, add the following code:

```typescript
import { Component } from "@angular/core";
import { CommonModule } from "@angular/common";

@Component({
  selector: "app-switcher",
  standalone: true,
  imports: [CommonModule],
  templateUrl: "./switcher.component.html",
  styleUrl: "./switcher.component.css",
})
export class SwitcherComponent {
  switcherState: boolean = false;

  toggleSwitcherState() {
    this.switcherState = !this.switcherState;
    console.log(this.switcherState);
  }
}
```

Code breakdown: 
* We initialized `switcherState`, which represents the state of our switcher, giving it a boolean data type and assigning a false value to it as its default value.
* We defined a `toggleSwitcherState` function that changes the state of `switcherState` whenever it's called. 
* When the `toggleSwitcherState` is called, the switcher component's background color, position, and border styles are changed based on the state of the `SwitcherState` variable. 

In your `switcher.component.css`, add the following code:

```css
*,
::after,
::before {
  box-sizing: border-box;
}
.switcher-container {
  background-color: whitesmoke;
  margin: 50px auto;
  width: fit-content;
  height: 100px;
  text-align: center;
  box-shadow:
    inset 0 0 -2em 2em rgba(0, 0, 0, 0.2),
    0 0 0 1px rgb(255, 258, 260),
    0.4em 0.4em 2em rgba(0, 0, 0.1, 0.4);
}
.switcher-circle-Container {
  border: 1px solid black;
  position: relative;
  border-radius: 12px;
  color: black;
  left: 12px;
  height: calc(100px / 4);
  width: 100px;
  cursor: pointer;
}

.switcher-circle-Container .switcher-circle {
  background-color: black;
  border-radius: 50%;
  position: absolute;
  --size: calc(100px / 4 - 4px);
  width: var(--size);
  height: var(--size);
  top: 1px;
  left: 1px;
}
```

This is what our output looks like on the browser:

<video autoplay loop muted playsinline src="https://res.cloudinary.com/dvofaxqpf/video/upload/c_crop,h_600,w_730/v1702989190/ezgif.com-crop-video_3_qppqjt.mp4" type="video/mp4"></video>


### Animating our Switcher
To add a smooth experience to our switcher when it's toggled, let's animate it. We'll use CSS transition animation to add animation to the switcher.

Update your `switcher.component.css` file with the code below.

```css
.switcher-circle-Container .switcher-circle {
  /* add this code */
  transition: all 700ms cubic-bezier(0.175, 0.89, 0.35, 1.27);
}
```

Here is what our animated switcher looks like on the browser:

<video autoplay loop muted playsinline src="https://res.cloudinary.com/dvofaxqpf/video/upload/c_crop,h_600,w_730/v1702989575/ezgif.com-crop-video_4_vlrhky.mp4" type="video/mp4"></video>


<CTA_Middle_Design />


## Using our Animated Switcher in an Application
In this section, we'll look at how we will use the animated switcher we created in an existing application.

Here is what the existing application looks like without a switcher:

![Screenshot (576)](https://blog.openreplay.com/images/animated-toggles-in-angular-17/images/image.png)

You'll notice how the background color is just white. We'll add our animated switcher component to this home page so that when users toggle, it affects the display of the image and background color.

Update your `switcher.component.ts` with the following code:

```typescript
import { Component, Output, EventEmitter } from "@angular/core"; // imported Output and EventEmitter decorators
import { CommonModule } from "@angular/common";

@Component({
  selector: "app-switcher",
  standalone: true,
  imports: [CommonModule],
  templateUrl: "./switcher.component.html",
  styleUrl: "./switcher.component.css",
})
export class SwitcherComponent {
  switcherState: boolean = false;
  @Output() sendSwitcherState = new EventEmitter<boolean>(); // added this

  toggleSwitcherState() {
    this.switcherState = !this.switcherState;
    console.log(this.switcherState);
    this.sendSwitcherState.emit(this.switcherState); // added this
  }
}
```

We made use of the `Output()` decorator to send or emit the value contained in `sendSwitcherState` to `AppComponent`, which is the parent component of `SwitcherComponent`.

In your `app.component.html`, add this code below:

```html
<section class="p-5 border border-danger fs-5">
  <header class="d-flex justify-content-between">
    <div>
      <h4>LOGO</h4>
    </div>
    <div class="d-flex nav justify-content-between g-4">
      <p>Home</p>
      <p>Contact</p>

      <p>About</p>
      <div class="switcher">
        <app-switcher
          (sendSwitcherState)="handleSwitcherChange($event)"
        ></app-switcher>
      </div>
    </div>
  </header>
  <main class="mt-4 d-flex justify-content-between">
    <div class="mt-3">
      <h2>
        Sometimes, we all need an undeserved break to cool off what seems to be
        an undying ache that flushes through the deepest canal contained with
        knowledge.
      </h2>
      <p>
        It's with a sad face the nerdy had when the scores of the undefeated was
        announced. So, what seems to be undefeated was only a fiasco that
        covered the thoughts of thinkers. Surely what seems to be undefeated can
        actually in reality and not in thoughts, be defeated totally.
      </p>
    </div>
    <div class="illustration">
      <img class="w-100" src="../assets/undraw1.svg" alt="" />
    </div>
  </main>
</section>
```

The above code represents the structure of our home page. When `sendSwitcherState` gets emitted by the `app-switcher` selector, it calls the `handleSwitcherChange` method in `AppComponent` and emits `switcherState` from `SwitcherComponent` to `$event`.

Now, in your `app.component.ts`, add this code below:

```typescript
import { Component } from "@angular/core";
import { CommonModule } from "@angular/common";
import { RouterOutlet } from "@angular/router";
import { SwitcherComponent } from "./switcher/switcher/switcher.component";

@Component({
  selector: "app-root",
  standalone: true,
  imports: [CommonModule, RouterOutlet, SwitcherComponent],
  templateUrl: "./app.component.html",
  styleUrl: "./app.component.css",
})
export class AppComponent {
  receivedSwitcherState: boolean = false;

  handleSwitcherChange(state: boolean) {
    this.receivedSwitcherState = state;
  }
}
```

We declared the `receivedSwitcherState` variable as a boolean and defined the `handleSwitcherChange` method, in which we assigned the value in the `state` parameter to `receivedSwitcherState`. 

So, this now means that the value contained in the `receivedSwitcherState` variable equals the value contained in the `switcherState` variable from `SwitcherComponent`.

Now that we have succeeded in getting the `SwitcherComponent` and the value of `switcherState` from `SwitcherComponent` in `AppComponent`, we'll go ahead and use the switcher to change the background color, text color, and image on the home page depending on the state of `receivedSwitcherState`.

Update your `app.component.html` with the following code:

```html
<section
  class="p-5 border border-danger fs-5"
  [style.backgroundColor]="receivedSwitcherState ? 'rgb(63, 61, 86)' : 'white'"
  [style.color]="receivedSwitcherState ? 'white' : 'black'"
>
  <header class="d-flex justify-content-between">
    <div>
      <h4>LOGO</h4>
    </div>
    <div class="d-flex nav justify-content-between g-4">
      <p>Home</p>
      <p>Contact</p>

      <p>About</p>
      <div class="switcher">
        <app-switcher
          (sendSwitcherState)="handleSwitcherChange($event)"
        ></app-switcher>
      </div>
    </div>
  </header>
  <main class="mt-4 d-flex justify-content-between">
    <div class="mt-3">
      <h2>
        Sometimes we all need an undeserved break to cool off what seems to be
        an undying ache that flushes through the deepest canal contained with
        knowledge.
      </h2>
      <p>
        It's with a sad face the nerdy had when the scores of the undefeated was
        announced. So, what seems to be undefeated was only a fiasco that
        covered the thoughts of thinkers. Surely what seems to be undefeated can
        actually in reality and not in thoughts, be defeated totally.
      </p>
    </div>
    <div class="illustration">
      @if (receivedSwitcherState) {
      <img class="w-100" src="../assets/undraw.svg" alt="" />
      } @if (!receivedSwitcherState) {
      <img class="w-100" src="../assets/undraw1.svg" alt="" />
      }
    </div>
  </main>
</section>
```

In the code above, we use conditional styling to display a particular background color, text color, or image depending on the value of `receivedSwitcherState`.

The illustration below shows how our home page now looks and works:

<video autoplay loop muted playsinline src="https://res.cloudinary.com/dvofaxqpf/video/upload/c_fit,h_600,w_730/v1703113607/ezgif.com-crop-video_6_bxzu2c.mp4" type="video/mp4"></video>


## Conclusion
We've been able to successfully show how a switcher or toggler can be created, make it more visually appealing by adding CSS transitions to make it animated, and then show how we can use it in an application to change its text color, background color, and image depending on its state.

I'll implore you to explore other ways a switcher can be used in an application, as its uses are endless.