Skip to content

fix(dialog, modal, popover, sheet): restore deactivating focus traps on outside click #11058

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 10 additions & 16 deletions packages/calcite-components/src/components/dialog/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,8 @@ export class Dialog

private dragPosition: DialogDragPosition = { ...initialDragPosition };

private escapeDeactivates = (event: KeyboardEvent): boolean => {
if (event.defaultPrevented || this.escapeDisabled) {
return false;
}
event.preventDefault();
return true;
};

focusTrap: FocusTrap;

private focusTrapDeactivates = (): void => {
this.open = false;
};

private ignoreOpenChange = false;

private interaction: Interactable;
Expand Down Expand Up @@ -306,10 +294,16 @@ export class Dialog
this.mutationObserver?.observe(this.el, { childList: true, subtree: true });
connectFocusTrap(this, {
focusTrapOptions: {
// Scrim has it's own close handler, allow it to take over.
clickOutsideDeactivates: false,
escapeDeactivates: this.escapeDeactivates,
onDeactivate: this.focusTrapDeactivates,
// scrim closes on click, so we let it take over
clickOutsideDeactivates: () => !this.modal,
escapeDeactivates: (event) => {
if (!event.defaultPrevented && !this.escapeDisabled) {
this.open = false;
event.preventDefault();
}

return false;
},
},
});
this.setupInteractions();
Expand Down
24 changes: 9 additions & 15 deletions packages/calcite-components/src/components/modal/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,20 +80,8 @@ export class Modal
this.updateSizeCssVars();
});

private escapeDeactivates = (event: KeyboardEvent) => {
if (event.defaultPrevented || this.escapeDisabled) {
return false;
}
event.preventDefault();
return true;
};

focusTrap: FocusTrap;

private focusTrapDeactivates = () => {
this.open = false;
};

private ignoreOpenChange = false;

private modalContent = createRef<HTMLDivElement>();
Expand Down Expand Up @@ -276,10 +264,16 @@ export class Modal
this.updateSizeCssVars();
connectFocusTrap(this, {
focusTrapOptions: {
// Scrim has it's own close handler, allow it to take over.
// scrim closes on click, so we let it take over
clickOutsideDeactivates: false,
escapeDeactivates: this.escapeDeactivates,
onDeactivate: this.focusTrapDeactivates,
escapeDeactivates: (event) => {
if (!event.defaultPrevented && !this.escapeDisabled) {
this.open = false;
event.preventDefault();
}

return false;
},
},
});
}
Expand Down
28 changes: 8 additions & 20 deletions packages/calcite-components/src/components/popover/popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,6 @@ export class Popover

private arrowEl: SVGSVGElement;

private clickOutsideDeactivates = (event: MouseEvent): boolean => {
const path = event.composedPath();
const isReferenceElementInPath =
this.referenceEl instanceof EventTarget && path.includes(this.referenceEl);

const outsideClick = !path.includes(this.el);
const shouldCloseOnOutsideClick = this.autoClose && outsideClick;

return (
shouldCloseOnOutsideClick &&
(this.triggerDisabled || (isReferenceElementInPath && !this.autoClose))
);
};

private closeButtonEl = createRef<Action["el"]>();

private filteredFlipPlacements: FlipPlacement[];
Expand All @@ -100,10 +86,6 @@ export class Popover

focusTrap: FocusTrap;

private focusTrapDeactivates = (): void => {
this.open = false;
};

private guid = `calcite-popover-${guid()}`;

private hasLoaded = false;
Expand Down Expand Up @@ -298,9 +280,15 @@ export class Popover
focusTrapEl: this.el,
focusTrapOptions: {
allowOutsideClick: true,
clickOutsideDeactivates: this.clickOutsideDeactivates,
escapeDeactivates: (event) => {
if (!event.defaultPrevented) {
this.open = false;
event.preventDefault();
}

return false;
},
initialFocus: this.initialFocusTrapFocus,
onDeactivate: this.focusTrapDeactivates,
},
});

Expand Down
24 changes: 9 additions & 15 deletions packages/calcite-components/src/components/sheet/sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,8 @@ export class Sheet

private contentId: string;

private escapeDeactivates = (event: KeyboardEvent) => {
if (event.defaultPrevented || this.escapeDisabled) {
return false;
}
event.preventDefault();
return true;
};

focusTrap: FocusTrap;

private focusTrapDeactivates = (): void => {
this.open = false;
};

private ignoreOpenChange = false;

private initialOverflowCSS: string;
Expand Down Expand Up @@ -254,10 +242,16 @@ export class Sheet
this.mutationObserver?.observe(this.el, { childList: true, subtree: true });
connectFocusTrap(this, {
focusTrapOptions: {
// Scrim has it's own close handler, allow it to take over.
// scrim closes on click, so we let it take over
clickOutsideDeactivates: false,
escapeDeactivates: this.escapeDeactivates,
onDeactivate: this.focusTrapDeactivates,
escapeDeactivates: (event) => {
if (!event.defaultPrevented && !this.escapeDisabled) {
this.open = false;
event.preventDefault();
}

return false;
},
},
});
this.setupInteractions();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export function connectFocusTrap(component: FocusTrapComponent, options?: Connec
}

const focusTrapOptions: FocusTrapOptions = {
clickOutsideDeactivates: true,
fallbackFocus: focusTrapNode,
setReturnFocus: (el) => {
focusElement(el as FocusableElement);
Expand Down
Loading