Angular CDK | Overlays
Tags: angular, cdk
Published: 2023-03-09 19:43:46

[Angular Material](https://material.angular.io/cdk/overlay/overview)

Overlays son esas cosas que flotan dentro de la aplicación:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vkyp5prymzsvsg879vd0.png)

Es común ver abrir overlays en acción al click en un botón que despliega un menú flotante.

Si bien, esto se puede lograr con Angular Material, el CDK provee la interacción y el diseño va por nuestra cuenta. Sin tanto lío como modificar estilos de los componentes de Angular Material.

> *El `overlay` package proporciona una forma de abrir paneles flotantes en la pantalla.*
> _**Descripción Oficial**_

De acuerdo a la documentación del CDK, lo primero que se debe realizar es importar los estilos. Son un conjunto de estilos mínimos estructurales que necesita el paquete para funcionar correctamente. 

Estos deberán colocarse en el archivo de estilos del proyecto:

```tsx
// CDK
@import '@angular/cdk/overlay-prebuilt.css';
```

Ahora hay que importar el módulo `OverlayModule` dentro del módulo donde estará ese componente, o si será utilizado en toda la aplicación; en el `app.module.ts`

```tsx
import { OverlayModule } from "@angular/cdk/overlay";

@NgModule({
  declarations: [ ],
  imports: [ OverlayModule ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

Ahora, se tiene un botón que despliega información para configuración. A este se le debe agregar una directiva que proporciona el paquete `Overlay`.

directiva: `cdk-overlay-origin` || `overlay-origin` || `cdkOverlayOrigin`

Como se quiere que el panel esté asociado al botón, éste deberá asignarse a la directiva que se ha declarado. Esto es justo para linkear el panel al botón.

```tsx
#menuOverlay="cdkOverlayOrigin"
```

![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/96472a6b-7721-4220-aca6-62f99eb03139/Untitled.png)

> ***Directiva aplicada a un elemento para que se pueda utilizar como origen de una Superposición mediante una `ConnectedPositionStrategy`.***
> 

El Overlay, necesita saber cuándo desplegar el panel y cuando ocultarlo. Para esto, se ha de utilizar el evento `(click)` del botón. Y En el TS también se debe meter esa prop.

```tsx
// HTML
(click)="isOpen = !isOpen" // => a cada click cambia el estado de isOpen

// TS
isOpen = false; // => Estado inicial
```

```tsx
<button 
	type="button" 
	class="flex rounded-full" 
	aria-expanded="false" 
	type="button" 
	(click)="isOpen = !isOpen"
  cdkOverlayOrigin 
	#menuOverlay="cdkOverlayOrigin"
>
	<img class="w-8 h-8 rounded-full" src="https://api.lorem.space/image/face?w=400&h=400" alt="user photo" />
</button>
```

Hasta este punto, ya se tiene un origen dónde debe aparecer el panel flotante. Ahora, es necesario indicar qué es lo que se debe mostrar dentro de ese overlay.

En algún lugar del template, hay que colocar un `<ng-template> </ng-template>` Este contendrá el contenido a mostrar.

Deberá tener otra directiva del paquete: 

`cdk-connected-overlay` || `connected-overlay` || `cdkConnectedOverlay`

Con las siguientes props de la directiva, se indica cuál es el overlay con cuál conecta y que dispara la acción de mostrar el panel flotante.

```tsx
//"menuOverlay" es la var de referencia creada en el botón => #menuOverlay
[cdkConnectedOverlayOrigin]="menuOverlay"
```

También, se debe indicar cuál es la prop condicionante o boolean que dice si se debe o no mostrar el panel. En este caso es el `boolen` que se ha definido en el TS

```tsx
[cdkConnectedOverlayOpen]="isOpen"
```

```tsx
<ng-template cdkConnectedOverlay [cdkConnectedOverlayOrigin]="menuOverlay" [cdkConnectedOverlayOpen]="isOpen">

  <div class="z-50 my-4 w-60 text-base list-none bg-white rounded divide-y divide-gray-100 shadow">
    <div class="py-3 px-4 flex justify-between">
      <span class="block text-sm text-center text-gray-900">Account</span>
      <button (click)="isOpen = !isOpen" class="block text-sm text-gray-900">
        <fa-icon [icon]="faClose"></fa-icon>
      </button>
    </div>
    <div class="py-3 px-4 flex items-center space-x-4">
      <img class="w-10 h-10 rounded-full" src="https://api.lorem.space/image/face?w=400&h=400" alt="" />
      <div class="space-y-1">
        <div>Jese Leos</div>
        <div class="text-sm text-gray-500">nico@gmail.com</div>
      </div>
    </div>
    <ul class="py-1">
      <li>
        <a href="#" class="block py-2 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600">Profile</a>
      </li>
      <li>
        <a href="#" class="block py-2 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600">Activity</a>
      </li>
      <li>
        <a href="#" class="block py-2 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600">Cards</a>
      </li>
      <li>
        <a href="#" class="block py-2 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600">Settings</a>
      </li>
      <li>
        <a href="#" class="block py-2 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600">Sign out</a>
      </li>
    </ul>
    <ul class="py-1">
      <li>
        <a href="#" class="block py-2 px-4 text-sm text-gray-700">Log out</a>
      </li>
    </ul>
  </div>

</ng-template>
```


Esto lo aprendí en platzi. Curso de Maquetación con Angular CDK y Tailwind CSS
https://platzi.com/cursos/angular-tailwind/