Skip to content

Commit

Permalink
Use close watcher when supported in place of escape key handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
lukewarlow committed Dec 13, 2023
1 parent fd65254 commit 8158b15
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 4 deletions.
19 changes: 19 additions & 0 deletions packages/web-components/fast-foundation/src/close-watcher.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
interface CloseWatcher extends EventTarget {
new (options?: CloseWatcherOptions): CloseWatcher;
requestClose(): void;
close(): void;
destroy(): void;

oncancel: (event: Event) => any | null;
onclose: (event: Event) => any | null;
}

declare const CloseWatcher: CloseWatcher;

interface CloseWatcherOptions {
signal: AbortSignal;
}

declare interface Window {
CloseWatcher?: CloseWatcher;
}
18 changes: 16 additions & 2 deletions packages/web-components/fast-foundation/src/dialog/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ export class FASTDialog extends FASTElement {
*/
private notifier: Notifier;

/**
* @internal
*/
private closeWatcher: CloseWatcher | null = null;

/**
* @internal
*/
Expand All @@ -119,6 +124,11 @@ export class FASTDialog extends FASTElement {
*/
public show(): void {
this.hidden = false;
if ("CloseWatcher" in window) {
this.closeWatcher?.destroy();
this.closeWatcher = new CloseWatcher();
this.closeWatcher.onclose = () => this.hide();
}
}

/**
Expand All @@ -128,6 +138,7 @@ export class FASTDialog extends FASTElement {
*/
public hide(): void {
this.hidden = true;
this.closeWatcher?.destroy();
// implement `<dialog>` interface
this.$emit("close");
}
Expand All @@ -152,6 +163,7 @@ export class FASTDialog extends FASTElement {

// remove keydown event listener
document.removeEventListener("keydown", this.handleDocumentKeydown);
this.closeWatcher?.destroy();

// if we are trapping focus remove the focusin listener
this.updateTrapFocus(false);
Expand All @@ -176,8 +188,10 @@ export class FASTDialog extends FASTElement {
if (!e.defaultPrevented && !this.hidden) {
switch (e.key) {
case keyEscape:
this.dismiss();
e.preventDefault();
if (!this.closeWatcher) {
this.dismiss();
e.preventDefault();
}
break;

case keyTab:
Expand Down
9 changes: 9 additions & 0 deletions packages/web-components/fast-foundation/src/picker/picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,8 @@ export class FASTPicker extends FormAssociatedPicker {
private inputElementView: HTMLView | null = null;
private behaviorOrchestrator: ViewBehaviorOrchestrator | null = null;

private closeWatcher: CloseWatcher | null = null;

/**
* @internal
*/
Expand Down Expand Up @@ -558,6 +560,9 @@ export class FASTPicker extends FormAssociatedPicker {

if (open && this.getRootActiveElement() === this.inputElement) {
this.flyoutOpen = open;
this.closeWatcher?.destroy();
this.closeWatcher = new CloseWatcher();
this.closeWatcher.onclose = () => this.toggleFlyout(false);
Updates.enqueue(() => {
if (this.menuElement !== undefined) {
this.setFocusedOption(0);
Expand All @@ -570,6 +575,7 @@ export class FASTPicker extends FormAssociatedPicker {

this.flyoutOpen = false;
this.disableMenu();
this.closeWatcher?.destroy();
return;
}

Expand Down Expand Up @@ -660,6 +666,9 @@ export class FASTPicker extends FormAssociatedPicker {
}

case keyEscape: {
if (this.closeWatcher) {
return true;
}
this.toggleFlyout(false);
return false;
}
Expand Down
10 changes: 9 additions & 1 deletion packages/web-components/fast-foundation/src/select/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export class FASTSelect extends FormAssociatedSelect {
@attr({ attribute: "open", mode: "boolean" })
public open: boolean = false;

private closeWatcher: CloseWatcher | null = null;

/**
* Sets focus and synchronizes ARIA attributes when the open property changes.
*
Expand All @@ -78,10 +80,16 @@ export class FASTSelect extends FormAssociatedSelect {
this.focusAndScrollOptionIntoView();
this.indexWhenOpened = this.selectedIndex;

this.closeWatcher?.destroy();
this.closeWatcher = new CloseWatcher();
this.closeWatcher.onclose = () => (this.open = false);

// focus is directed to the element when `open` is changed programmatically
Updates.enqueue(() => this.focus());

return;
} else {
this.closeWatcher?.destroy();
}

this.cleanup?.();
Expand Down Expand Up @@ -523,7 +531,7 @@ export class FASTSelect extends FormAssociatedSelect {
}

case keyEscape: {
if (this.collapsible && this.open) {
if (this.collapsible && this.open && !this.closeWatcher) {
e.preventDefault();
this.open = false;
}
Expand Down
13 changes: 12 additions & 1 deletion packages/web-components/fast-foundation/src/tooltip/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ export class FASTTooltip extends FASTElement {
@observable
private controlledVisibility: boolean = false;

/**
* @internal
*/
private closeWatcher: CloseWatcher | null = null;

/**
* Switches between controlled and uncontrolled visibility.
*
Expand Down Expand Up @@ -311,7 +316,9 @@ export class FASTTooltip extends FASTElement {
this.addEventListener("mouseout", this.mouseoutAnchorHandler);
this.addEventListener("mouseover", this.mouseoverAnchorHandler);

document.addEventListener("keydown", this.keydownDocumentHandler);
if (!("CloseWatcher" in window)) {
document.addEventListener("keydown", this.keydownDocumentHandler);
}
}

public connectedCallback(): void {
Expand All @@ -337,6 +344,7 @@ export class FASTTooltip extends FASTElement {
public hideTooltip(): void {
this._visible = false;
this.cleanup?.();
this.closeWatcher?.destroy();
}

/**
Expand Down Expand Up @@ -446,5 +454,8 @@ export class FASTTooltip extends FASTElement {
private showTooltip(): void {
this._visible = true;
Updates.enqueue(() => this.setPositioning());
this.closeWatcher?.destroy();
this.closeWatcher = new CloseWatcher();
this.closeWatcher.onclose = () => this.dismiss();
}
}

0 comments on commit 8158b15

Please sign in to comment.