Fix concurrent active modals bug

pull/261/head
Cory LaViska 2020-10-15 13:55:42 -04:00
rodzic df0101cad2
commit cf2cf8edb0
3 zmienionych plików z 17 dodań i 24 usunięć

Wyświetl plik

@ -11,6 +11,7 @@ _During the beta period, these restrictions may be relaxed in the event of a mis
- Added `label` slot to `sl-input`, `sl-select`, and `sl-textarea` [#248](https://github.com/shoelace-style/shoelace/issues/248)
- Fixed a bug where initial transitions didn't show in `sl-dialog` and `sl-drawer` [#247](https://github.com/shoelace-style/shoelace/issues/247)
- Fixed a bug where indeterminate checkboxes would maintain the indeterminate state when toggled
- Fixed a bug where concurrent active modals (i.e. dialog, drawer) would try to steal focus from each other
- Improved `sl-color-picker` grid and slider handles [#246](https://github.com/shoelace-style/shoelace/issues/246)
- Reworked show/hide logic in `sl-alert`, `sl-dialog`, and `sl-drawer` to not use reflow hacks and the `hidden` attribute
- Updated to Popper 2.5.3 to address a fixed position bug in Firefox

Wyświetl plik

@ -1,6 +1,7 @@
import { Component, Element, Event, EventEmitter, Method, Prop, State, Watch, h } from '@stencil/core';
import { lockBodyScrolling, unlockBodyScrolling } from '../../utilities/scroll';
import { hasSlot } from '../../utilities/slot';
import Modal from '../../utilities/modal';
let id = 0;
@ -29,6 +30,7 @@ let id = 0;
export class Dialog {
componentId = `dialog-${++id}`;
dialog: HTMLElement;
modal: Modal;
panel: HTMLElement;
@Element() host: HTMLSlDialogElement;
@ -72,12 +74,15 @@ export class Dialog {
@Event({ eventName: 'sl-overlay-dismiss' }) slOverlayDismiss: EventEmitter;
connectedCallback() {
this.handleDocumentFocusIn = this.handleDocumentFocusIn.bind(this);
this.handleCloseClick = this.handleCloseClick.bind(this);
this.handleTransitionEnd = this.handleTransitionEnd.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.handleOverlayClick = this.handleOverlayClick.bind(this);
this.updateSlots = this.updateSlots.bind(this);
this.modal = new Modal(this.host, {
onFocusOut: () => this.panel.focus()
});
}
componentWillLoad() {
@ -114,9 +119,9 @@ export class Dialog {
this.isVisible = true;
this.open = true;
this.modal.activate();
lockBodyScrolling(this.host);
document.addEventListener('focusin', this.handleDocumentFocusIn);
}
/** Hides the dialog */
@ -134,23 +139,15 @@ export class Dialog {
}
this.open = false;
this.modal.deactivate();
unlockBodyScrolling(this.host);
document.removeEventListener('focusin', this.handleDocumentFocusIn);
}
handleCloseClick() {
this.hide();
}
handleDocumentFocusIn(event: Event) {
const target = event.target as HTMLElement;
if (target.closest('sl-dialog') !== this.host) {
this.panel.focus();
}
}
handleKeyDown(event: KeyboardEvent) {
if (event.key === 'Escape') {
this.hide();

Wyświetl plik

@ -1,6 +1,7 @@
import { Component, Element, Event, EventEmitter, Method, Prop, State, Watch, h } from '@stencil/core';
import { lockBodyScrolling, unlockBodyScrolling } from '../../utilities/scroll';
import { hasSlot } from '../../utilities/slot';
import Modal from '../../utilities/modal';
let id = 0;
@ -28,6 +29,7 @@ let id = 0;
export class Drawer {
componentId = `drawer-${++id}`;
drawer: HTMLElement;
modal: Modal;
panel: HTMLElement;
@Element() host: HTMLSlDrawerElement;
@ -82,10 +84,13 @@ export class Drawer {
connectedCallback() {
this.handleCloseClick = this.handleCloseClick.bind(this);
this.handleTransitionEnd = this.handleTransitionEnd.bind(this);
this.handleDocumentFocusIn = this.handleDocumentFocusIn.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.handleOverlayClick = this.handleOverlayClick.bind(this);
this.updateSlots = this.updateSlots.bind(this);
this.modal = new Modal(this.host, {
onFocusOut: () => (this.contained ? null : this.panel.focus())
});
}
componentWillLoad() {
@ -125,10 +130,9 @@ export class Drawer {
// Lock body scrolling only if the drawer isn't contained
if (!this.contained) {
this.modal.activate();
lockBodyScrolling(this.host);
}
document.addEventListener('focusin', this.handleDocumentFocusIn);
}
/** Hides the drawer */
@ -146,24 +150,15 @@ export class Drawer {
}
this.open = false;
this.modal.deactivate();
unlockBodyScrolling(this.host);
document.removeEventListener('focusin', this.handleDocumentFocusIn);
}
handleCloseClick() {
this.hide();
}
handleDocumentFocusIn(event: Event) {
const target = event.target as HTMLElement;
// Trap focus only if the drawer is NOT contained
if (!this.contained && target.closest('sl-drawer') !== this.host) {
this.panel.focus();
}
}
handleKeyDown(event: KeyboardEvent) {
if (event.key === 'Escape') {
this.hide();