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 apopovertarget
attribute) or aHTMLElement.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
oroverflow
styling.
Still according to MDN, hidePopover()
is a method that hide our popover:
The
hidePopover()
method of theHTMLElement
interface hides a popover element (i.e. one that has a valid popover attribute) by removing it from the top layer and styling it withdisplay: 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:
- hidePopover() is a method and not a property
- 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).