Search code examples
angulartypescriptpopover

Is there an issue with my usage of the method hidePopover?


Rapid background

According to MDN, popover is an attribute to display a popup in the screen:

The popover global attribute is used to designate an element as a popover element.

Popover elements are hidden via display: none until opened via an invoking/control element (i.e. a <button> or <input type="button"> with a popovertarget attribute) or a HTMLElement.showPopover() call.

When open, popover elements will appear above all other elements in the top layer, and won't be influenced by parent elements' position or overflow styling.

Still according to MDN, hidePopover() is a method that hide our popover:

The hidePopover() method of the HTMLElement interface hides a popover element (i.e. one that has a valid popover attribute) by removing it from the top layer and styling it with display: none.

My implementation

I have a component modal-options that when pressing on a button will call the second component modal-change-password who is defined with the popover attribute to display the pop-up.

<div class="popover">
  <!-- skipping not relevant part -->

  <div id="pwdDocker" class="rounded">
    <button id="updatePwdBtn" popovertarget="updatePwd"><h3>Update password</h3></button>
    <app-modal-change-password id="updatePwd" popover [currentUser]="currentUser" (closeModalEvent)="closeChangePasswordModal()"></app-modal-change-password>
  </div>
</div>
@Component({
  selector: 'app-modal-options',
  templateUrl: './modal-options.component.html',
  styleUrls: ['./modal-options.component.scss'],
})
export class ModalOptionsComponent implements OnInit {

// skipping not relevant part

  closeChangePasswordModal(): void {
    const popoverElement = document.getElementById("updatePwd");
    if(popoverElement){
      popoverElement.hidePopover();
    }
  }
}

modal-change-password is my popover component, in it we have a button that will close the pop-up by emitting an EventEmitter to the parent.

<div class="alert-box">
  <!-- skipping not relevant part -->

  <div class="alert-box-action">
    <button (click)="save()">Change password</button>
    <button (click)="onClose()">Close</button>
  </div>
</div>
@Component({
  selector: 'app-modal-change-password',
  templateUrl: './modal-change-password.component.html',
  styleUrls: ['./modal-change-password.component.scss'],
})
export class ModalChangePasswordComponent implements OnInit {
  @Output() closeModalEvent = new EventEmitter<void>();
  
//skipping not relevant part
  
  onClose(): void {
    this.closeModalEvent.emit();
  }
}

My issue

The typescript compiler will raise me an error stating error TS2339: Property 'hidePopover' does not exist on type 'HTMLElement'. which totally lose me because:

  1. hidePopover() is a method and not a property
  2. The method exists and according to MDN, does exist in HTMLElement

I am still learning a lot everyday about Typescript and so I might be looking in the wrong direction, but I have been researching for a good amount of time now and because of the very recent nature of this attribute, I haven't found any answers related to my issue.

Why is it raising me an error at the compilation ? How should I update my code to make it work ?

(note: I tried two differents approaches, first with @ViewChild() instead of getElementById() and then with togglePopover() instead just to see if I got an other result, but ended up with the same error for both tries)


Solution

  • hidePopover() is a method and not a property

    Method is just a special name for "A property whose value is a function". They are still properties.

    The method exists and according to MDN, does exist in HTMLElement

    If you look at the browser compatibility section of the documentation you will note that:

    • No browser supported it before May this year
    • Firefox still doesn't support it in production (it is locked behind a feature flag).

    hidePopover is bleeding edge technology.

    TypeScript 5.1 does not support it. TypeScript 5.2 does support it.

    Upgrade your version of TypeScript (or consider avoiding it until it has matured a bit more).