fix(overlays): assign incremental id to overlay host (#27278)

Issue number: Internal

---------

<!-- Please refer to our contributing documentation for any questions on
submitting a pull request, or let us know here if you need any help:
https://ionicframework.com/docs/building/contributing -->

<!-- Some docs updates need to be made in the `ionic-docs` repo, in a
separate PR. See
https://github.com/ionic-team/ionic-framework/blob/main/.github/CONTRIBUTING.md#modifying-documentation
for details. -->

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

The counter for incrementing the `id` and `z-index` of an overlay is
incremented whenever the `connectedCallback` is fired for an overlay.

When an overlay is presented and/or conditionally rendered, the overlay
`id` can increment by `n+2` instead of `n+1`.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- Increments all overlay ids consistently
- Removes legacy `ion-modal-{id}` and `ion-popover-{id}` logic
- Adds unit tests for the id behavior
- Tests are split up into separate files so that the counter is always
starting from `0`
- Adds an integration test with the Angular test app to verify
conditional rendering behavior

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
This commit is contained in:
Sean Perkins
2023-05-03 13:24:19 -04:00
committed by GitHub
parent 27a9aaaedc
commit 9313a914b7
19 changed files with 365 additions and 38 deletions

View File

@ -22,6 +22,7 @@ import { OVERLAY_BACK_BUTTON_PRIORITY } from './hardware-back-button';
import { addEventListener, componentOnReady, focusElement, getElementRoot, removeEventListener } from './helpers';
import { printIonWarning } from './logging';
let lastOverlayIndex = 0;
let lastId = 0;
export const activeAnimations = new WeakMap<OverlayInterface, Animation[]>();
@ -50,15 +51,42 @@ export const pickerController = /*@__PURE__*/ createController<PickerOptions, HT
export const popoverController = /*@__PURE__*/ createController<PopoverOptions, HTMLIonPopoverElement>('ion-popover');
export const toastController = /*@__PURE__*/ createController<ToastOptions, HTMLIonToastElement>('ion-toast');
/**
* Prepares the overlay element to be presented.
*/
export const prepareOverlay = <T extends HTMLIonOverlayElement>(el: T) => {
if (typeof document !== 'undefined') {
/**
* Adds a single instance of event listeners for application behaviors:
*
* - Escape Key behavior to dismiss an overlay
* - Trapping focus within an overlay
* - Back button behavior to dismiss an overlay
*
* This only occurs when the first overlay is created.
*/
connectListeners(document);
}
const overlayIndex = lastId++;
const overlayIndex = lastOverlayIndex++;
/**
* overlayIndex is used in the overlay components to set a zIndex.
* This ensures that the most recently presented overlay will be
* on top.
*/
el.overlayIndex = overlayIndex;
};
/**
* Assigns an incrementing id to an overlay element, that does not
* already have an id assigned to it.
*
* Used to track unique instances of an overlay element.
*/
export const setOverlayId = <T extends HTMLIonOverlayElement>(el: T) => {
if (!el.hasAttribute('id')) {
el.id = `ion-overlay-${overlayIndex}`;
el.id = `ion-overlay-${++lastId}`;
}
return el.id;
};
export const createOverlay = <T extends HTMLIonOverlayElement>(
@ -301,8 +329,8 @@ const trapKeyboardFocus = (ev: Event, doc: Document) => {
};
const connectListeners = (doc: Document) => {
if (lastId === 0) {
lastId = 1;
if (lastOverlayIndex === 0) {
lastOverlayIndex = 1;
doc.addEventListener(
'focus',
(ev: FocusEvent) => {