Skip to content

Commit

Permalink
fix(picker): stop the click events from reaching the elements below p…
Browse files Browse the repository at this point in the history
…icker-tray (#5060)

* fix(picker): stop the click events to reach the element below tray

* chore(picker): add story to test the background click
  • Loading branch information
TarunAdobe authored Feb 4, 2025
1 parent 9dcf7fe commit 7e4fdbf
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
34 changes: 34 additions & 0 deletions packages/overlay/src/AbstractOverlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,4 +338,38 @@ export class AbstractOverlay extends SpectrumElement {
overlay.placement = options.placement;
overlay.willPreventClose = !!options.notImmediatelyClosable;
}

private iosEventPropagationController?: AbortController;

protected setupIOSEventManagement(): void {
// This is a workaround for a bug in iOS <17 where the event leaks out of the dialog to the element below it.
// Issue - https://github.com/adobe/spectrum-web-components/issues/5042
this.iosEventPropagationController = new AbortController();
this.dialogEl.addEventListener(
'pointerup',
(event) => event.stopPropagation(),
{
capture: true,
signal: this.iosEventPropagationController.signal,
}
);
this.dialogEl.addEventListener(
'touchend',
(event) => event.stopPropagation(),
{
capture: true,
signal: this.iosEventPropagationController.signal,
}
);
}

protected cleanupIOSEventManagement(): void {
this.iosEventPropagationController?.abort();
this.iosEventPropagationController = undefined;
}

override disconnectedCallback(): void {
this.cleanupIOSEventManagement();
super.disconnectedCallback();
}
}
2 changes: 2 additions & 0 deletions packages/overlay/src/OverlayDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export function OverlayDialog<T extends Constructor<AbstractOverlay>>(
if (!targetOpenState) {
const close = (): void => {
el.removeEventListener('close', close);
this.cleanupIOSEventManagement();
finish(el, index);
};
el.addEventListener('close', close);
Expand Down Expand Up @@ -88,6 +89,7 @@ export function OverlayDialog<T extends Constructor<AbstractOverlay>>(
return;
}
this.dialogEl.showModal();
this.setupIOSEventManagement();
};
const finish = (el: OpenableElement, index: number) => (): void => {
if (this.open !== targetOpenState) {
Expand Down
26 changes: 26 additions & 0 deletions packages/picker/stories/picker.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -694,3 +694,29 @@ custom.args = {
open: true,
};
custom.decorators = [isOverlayOpen];

export const BackgroundClickTest = (): TemplateResult => {
return html`
<div style="display: flex; flex-direction: column;">
<sp-picker size="l">
<sp-menu-item value="option-1">Deselect</sp-menu-item>
<sp-menu-item value="option-2">Select Inverse</sp-menu-item>
</sp-picker>
<div style="position: absolute; bottom: 50px;">
<sp-button
@click=${() => {
console.log(
'this button should not have been clicked...'
);
}}
size="l"
>
I shall not be clicked
</sp-button>
</div>
</div>
`;
};
BackgroundClickTest.swc_vrt = {
skip: true,
};

0 comments on commit 7e4fdbf

Please # to comment.