DEV Community

Cover image for Creating a Snackbar using Signals and Tailwind CSS generated with V0
Diogo Machado
Diogo Machado

Posted on

Creating a Snackbar using Signals and Tailwind CSS generated with V0

Recently I discovered how easy it is to create a component that serves the whole application using signals to manage the state, without needing to include a complex library like NgRx.

For this experiment, I also use the power of V0.dev, which provides an artificial intelligence to create components React or pure HTML with Tailwind CSS.

Creating the UI using V0

Enter in the v0.dev and put a prompt with the idea of the UI you want, in this case, I put:

A clean snackbar com title, description and a button in the right side

Step 1

Image description

Step 2

Image description

Step 3

Image description

That's it, thanks v0 and Tailwind CSS 🥰

Structure used to organize

You are free to organize your own idea, but in my experience, I use:

/components

Seems obvious, but this is where I store my components.

/components/models

The file snackbar.ts is used to export the interface used on the component.

export interface SnackbarOptions {
  visible: boolean;
  title?: string;
  description?: string;
}
Enter fullscreen mode Exit fullscreen mode

Often when we create a new component with the Angular CLI, we have these files:

  • snackbar.component.html
  • snackbar.component.ts
  • snackbar.component.spec.ts
  • snackbar.component.scss

To create the state of the component, I included a new file called snackbar.state.ts, which contains the initialization of the signal.

import { signal } from '@angular/core';
import { SnackbarOptions } from './models/snackbar';

export const InitialState: SnackbarOptions = {
  visible: false,
};

export const SnackbarState = signal(InitialState);
Enter fullscreen mode Exit fullscreen mode

Now we need to put the template of the component in the place of the application (generally where we have the <ng-outlet> if you work with routes), this strategy with Signals is possibly due to the nature of Signal, we can easily listen to the changes of a signal using effect() inside the constructor().

In this example, I used the main.ts file:

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [SnackbarComponent],
  template: `
    <main>
      @if(snackbar) {
        <snackbar
          [title]="snackbar.title"
          [description]="snackbar.description"
          [visible]="snackbar.visible"
        ></snackbar>
      }
    </main>
  `
})
Enter fullscreen mode Exit fullscreen mode

This is where the magic happens, using the special method effect, Angular can identify and update the value of a signal:

export class App {
  snackbar: SnackbarOptions | undefined;

  constructor() {
    effect(() => {
      this.snackbar = SnackbarState();
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

To test the Snackbar, we are going to include a method to update the signal, the interest is you are free to update the Snackbar in any place of the application, you should only import the snackbar.state.ts, and the Snackbar effect() placed in the app will happen, nice isn't it?

handleOpen() {
    SnackbarState.update((currentSnackbar) => {
      return {
        ...currentSnackbar,
        visible: true,
        title: 'LinkedIn',
        description: 'Amazing, it works fine!',
      };
    });
}
Enter fullscreen mode Exit fullscreen mode

Demo

References:
https://angular.dev/guide/signals

Top comments (1)

Collapse
 
quedicesebas profile image
Sebastián Rojas Ricaurte

No need to use effect(), just use the signal in the templates.