Skip to content

Commit

Permalink
fix: stop touchstart event propagation if coming from cancel button i…
Browse files Browse the repository at this point in the history
…n detached mode (#924)


Co-authored-by: Sarah Dayan <[email protected]>
  • Loading branch information
dhayab and sarahdayan authored Mar 31, 2022
1 parent 9e8f9e6 commit 24cf9d6
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 10 deletions.
29 changes: 21 additions & 8 deletions packages/autocomplete-js/src/__tests__/detached.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,30 @@ describe('detached', () => {
'.aa-DetachedCancelButton'
);

const bodyClickListener = jest.fn();
document.querySelector('body').addEventListener('click', bodyClickListener);
// Prevent `onTouchStart` event from closing detached overlay
const windowTouchStartListener = jest.fn();
window.addEventListener('touchstart', windowTouchStartListener);

fireEvent(
cancelButton,
new TouchEvent('touchstart', {
bubbles: true,
cancelable: true,
composed: true,
})
);

// Close detached overlay
cancelButton.click();
expect(windowTouchStartListener).toHaveBeenCalledTimes(0);

expect(bodyClickListener).toHaveBeenCalledTimes(0);
window.removeEventListener('touchstart', windowTouchStartListener);

await waitFor(() => {
expect(document.querySelector('.aa-DetachedOverlay')).toBeInTheDocument();
expect(document.body).toHaveClass('aa-Detached');
});

document
.querySelector('body')
.removeEventListener('click', bodyClickListener);
// Close detached overlay
cancelButton.click();

// The detached overlay should close
await waitFor(() => {
Expand Down
6 changes: 5 additions & 1 deletion packages/autocomplete-js/src/createAutocompleteDom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,12 @@ export function createAutocompleteDom<TItem extends BaseItem>({
type: 'button',
class: classNames.detachedCancelButton,
textContent: translations.detachedCancelButtonText,
onClick(event: MouseEvent) {
// Prevent `onTouchStart` from closing the panel
// since it should be initiated by `onClick` only
onTouchStart(event: TouchEvent) {
event.stopPropagation();
},
onClick() {
autocomplete.setIsOpen(false);
setIsModalOpen(false);
},
Expand Down
15 changes: 14 additions & 1 deletion packages/autocomplete-js/src/utils/setProperties.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
/* eslint-disable */

/**
* Touch-specific event aliases
*
* See https://w3c.github.io/touch-events/#extensions-to-the-globaleventhandlers-mixin
*/
const TOUCH_EVENTS_ALIASES = [
'ontouchstart',
'ontouchend',
'ontouchmove',
'ontouchcancel',
];

/*
* Taken from Preact
*
Expand Down Expand Up @@ -50,7 +62,8 @@ export function setProperty(dom: HTMLElement, name: string, value: any) {
else if (name[0] === 'o' && name[1] === 'n') {
useCapture = name !== (name = name.replace(/Capture$/, ''));
nameLower = name.toLowerCase();
if (nameLower in dom) name = nameLower;
if (nameLower in dom || TOUCH_EVENTS_ALIASES.includes(nameLower))
name = nameLower;
name = name.slice(2);

if (!(dom as any)._listeners) (dom as any)._listeners = {};
Expand Down

0 comments on commit 24cf9d6

Please sign in to comment.