add sl-request-close event

pull/479/head
Cory LaViska 2021-06-21 09:40:11 -04:00
rodzic 95ba1b5849
commit 1c010ffe5a
5 zmienionych plików z 71 dodań i 42 usunięć

Wyświetl plik

@ -76,27 +76,29 @@ By design, a dialog's height will never exceed that of the viewport. As such, di
</script>
```
### Ignoring Clicks on the Overlay
### Preventing the Dialog from Closing
By default, dialogs are closed when the user clicks or taps on the overlay. To prevent this behavior, cancel the `sl-overlay-dismiss` event.
By default, dialogs will close when the user clicks the close button, clicks the overlay, or presses the <kbd>Escape</kbd> key. In most cases, the default behavior is the best behavior in terms of UX. However, there are situations where this may be undesirable, such as when data loss will occur.
To keep the dialog open in such cases, you can cancel the `sl-request-close` event. When canceled, the dialog will remain open and pulse briefly to draw the user's attention to it.
```html preview
<sl-dialog label="Dialog" class="dialog-no-overlay-dismiss">
This dialog will not be closed when you click outside of it.
<sl-button slot="footer" type="primary">Close</sl-button>
<sl-dialog label="Dialog" class="dialog-deny-close">
This dialog will not close unless you use the button below.
<sl-button slot="footer" type="primary">Save &amp; Close</sl-button>
</sl-dialog>
<sl-button>Open Dialog</sl-button>
<script>
const dialog = document.querySelector('.dialog-no-overlay-dismiss');
const dialog = document.querySelector('.dialog-deny-close');
const openButton = dialog.nextElementSibling;
const closeButton = dialog.querySelector('sl-button[slot="footer"]');
const saveButton = dialog.querySelector('sl-button[slot="footer"]');
openButton.addEventListener('click', () => dialog.show());
closeButton.addEventListener('click', () => dialog.hide());
saveButton.addEventListener('click', () => dialog.hide());
dialog.addEventListener('sl-overlay-dismiss', event => event.preventDefault());
dialog.addEventListener('sl-request-close', event => event.preventDefault());
</script>
```

Wyświetl plik

@ -164,27 +164,30 @@ By design, a drawer's height will never exceed 100% of its container. As such, d
</script>
```
### Ignoring Clicks on the Overlay
### Preventing the Drawer from Closing
By default, drawers will close when the user clicks the close button, clicks the overlay, or presses the <kbd>Escape</kbd> key. In most cases, the default behavior is the best behavior in terms of UX. However, there are situations where this may be undesirable, such as when data loss will occur.
To keep the drawer open in such cases, you can cancel the `sl-request-close` event. When canceled, the drawer will remain open and pulse briefly to draw the user's attention to it.
By default, drawers are closed when the user clicks or taps on the overlay. To prevent this behavior, cancel the `sl-overlay-dismiss` event.
```html preview
<sl-drawer label="Drawer" class="drawer-no-overlay-dismiss">
This drawer will not be closed when you click outside of it.
<sl-button slot="footer" type="primary">Close</sl-button>
<sl-drawer label="Drawer" class="drawer-deny-close">
This dialog will not close unless you use the button below.
<sl-button slot="footer" type="primary">Save &amp; Close</sl-button>
</sl-drawer>
<sl-button>Open Drawer</sl-button>
<script>
const drawer = document.querySelector('.drawer-no-overlay-dismiss');
const drawer = document.querySelector('.drawer-deny-close');
const openButton = drawer.nextElementSibling;
const closeButton = drawer.querySelector('sl-button[type="primary"]');
openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide());
drawer.addEventListener('sl-overlay-dismiss', event => event.preventDefault());
drawer.addEventListener('sl-request-close', event => event.preventDefault());
</script>
```

Wyświetl plik

@ -8,6 +8,9 @@ _During the beta period, these restrictions may be relaxed in the event of a mis
## Next
- 🚨 BREAKING: removed the `sl-overlay-click` event from `sl-dialog` and `sl-drawer` (use `sl-request-close` instead) [#471](https://github.com/shoelace-style/shoelace/discussions/471)
- Added `sl-request-close` event to `sl-dialog` and `sl-drawer`
- Added `dialog.denyClose` and `drawer.denyClose` animations
- Fixed a bug in `sl-color-picker` where setting `value` immediately wouldn't trigger an update
## 2.0.0-beta.44

Wyświetl plik

@ -42,6 +42,7 @@ let id = 0;
*
* @animation dialog.show - The animation to use when showing the dialog.
* @animation dialog.hide - The animation to use when hiding the dialog.
* @animation dialog.denyClose - The animation to use when a request to close the dialog is denied.
* @animation dialog.overlay.show - The animation to use when showing the dialog's overlay.
* @animation dialog.overlay.hide - The animation to use when hiding the dialog's overlay.
*/
@ -92,8 +93,12 @@ export default class SlDialog extends LitElement {
*/
@event('sl-initial-focus') slInitialFocus: EventEmitter<void>;
/** Emitted when the overlay is clicked. Calling `event.preventDefault()` will prevent the dialog from closing. */
@event('sl-overlay-dismiss') slOverlayDismiss: EventEmitter<void>;
/**
* Emitted when the user attempts to close the dialog by clicking the close button, clicking the overlay, or pressing
* the escape key. Calling `event.preventDefault()` will prevent the dialog from closing. Avoid using this unless
* closing the dialog will result in destructive behavior such as data loss.
*/
@event('sl-request-close') slRequestClose: EventEmitter<void>;
connectedCallback() {
super.connectedCallback();
@ -131,14 +136,21 @@ export default class SlDialog extends LitElement {
return waitForEvent(this, 'sl-after-hide');
}
handleCloseClick() {
private requestClose() {
const slRequestClose = this.slRequestClose.emit({ cancelable: true });
if (slRequestClose.defaultPrevented) {
const animation = getAnimation(this, 'dialog.denyClose');
animateTo(this.panel, animation.keyframes, animation.options);
return;
}
this.hide();
}
handleKeyDown(event: KeyboardEvent) {
if (event.key === 'Escape') {
event.stopPropagation();
this.hide();
this.requestClose();
}
}
@ -206,13 +218,6 @@ export default class SlDialog extends LitElement {
}
}
handleOverlayClick() {
const slOverlayDismiss = this.slOverlayDismiss.emit({ cancelable: true });
if (!slOverlayDismiss.defaultPrevented) {
this.hide();
}
}
handleSlotChange() {
this.hasFooter = hasSlot(this, 'footer');
}
@ -228,7 +233,7 @@ export default class SlDialog extends LitElement {
})}
@keydown=${this.handleKeyDown}
>
<div part="overlay" class="dialog__overlay" @click=${this.handleOverlayClick} tabindex="-1"></div>
<div part="overlay" class="dialog__overlay" @click=${this.requestClose} tabindex="-1"></div>
<div
part="panel"
@ -251,7 +256,7 @@ export default class SlDialog extends LitElement {
class="dialog__close"
name="x"
library="system"
@click="${this.handleCloseClick}"
@click="${this.requestClose}"
></sl-icon-button>
</header>
`
@ -286,6 +291,11 @@ setDefaultAnimation('dialog.hide', {
options: { duration: 250, easing: 'ease' }
});
setDefaultAnimation('dialog.denyClose', {
keyframes: [{ transform: 'scale(1)' }, { transform: 'scale(1.02)' }, { transform: 'scale(1)' }],
options: { duration: 250 }
});
setDefaultAnimation('dialog.overlay.show', {
keyframes: [{ opacity: 0 }, { opacity: 1 }],
options: { duration: 250 }

Wyświetl plik

@ -50,6 +50,7 @@ let id = 0;
* @animation drawer.hideEnd - The animation to use when hiding a drawer with `end` placement.
* @animation drawer.hideBottom - The animation to use when hiding a drawer with `bottom` placement.
* @animation drawer.hideStart - The animation to use when hiding a drawer with `start` placement.
* @animation drawer.denyClose - The animation to use when a request to close the drawer is denied.
* @animation drawer.overlay.show - The animation to use when showing the drawer's overlay.
* @animation drawer.overlay.hide - The animation to use when hiding the drawer's overlay.
*/
@ -106,8 +107,12 @@ export default class SlDrawer extends LitElement {
/** Emitted when the drawer opens and the panel gains focus. Calling `event.preventDefault()` will prevent focus and allow you to set it on a different element in the drawer, such as an input or button. */
@event('sl-initial-focus') slInitialFocus: EventEmitter<void>;
/** Emitted when the overlay is clicked. Calling `event.preventDefault()` will prevent the drawer from closing. */
@event('sl-overlay-dismiss') slOverlayDismiss: EventEmitter<void>;
/**
* Emitted when the user attempts to close the drawer by clicking the close button, clicking the overlay, or pressing
* the escape key. Calling `event.preventDefault()` will prevent the drawer from closing. Avoid using this unless
* closing the drawer will result in destructive behavior such as data loss.
*/
@event('sl-request-close') slRequestClose: EventEmitter<void>;
connectedCallback() {
super.connectedCallback();
@ -145,14 +150,21 @@ export default class SlDrawer extends LitElement {
return waitForEvent(this, 'sl-after-hide');
}
handleCloseClick() {
private requestClose() {
const slRequestClose = this.slRequestClose.emit({ cancelable: true });
if (slRequestClose.defaultPrevented) {
const animation = getAnimation(this, 'drawer.denyClose');
animateTo(this.panel, animation.keyframes, animation.options);
return;
}
this.hide();
}
handleKeyDown(event: KeyboardEvent) {
if (event.key === 'Escape') {
event.stopPropagation();
this.hide();
this.requestClose();
}
}
@ -223,13 +235,6 @@ export default class SlDrawer extends LitElement {
}
}
handleOverlayClick() {
const slOverlayDismiss = this.slOverlayDismiss.emit({ cancelable: true });
if (!slOverlayDismiss.defaultPrevented) {
this.hide();
}
}
handleSlotChange() {
this.hasFooter = hasSlot(this, 'footer');
}
@ -251,7 +256,7 @@ export default class SlDrawer extends LitElement {
})}
@keydown=${this.handleKeyDown}
>
<div part="overlay" class="drawer__overlay" @click=${this.handleOverlayClick} tabindex="-1"></div>
<div part="overlay" class="drawer__overlay" @click=${this.requestClose} tabindex="-1"></div>
<div
part="panel"
@ -275,7 +280,7 @@ export default class SlDrawer extends LitElement {
class="drawer__close"
name="x"
library="system"
@click=${this.handleCloseClick}
@click=${this.requestClose}
></sl-icon-button>
</header>
`
@ -362,6 +367,12 @@ setDefaultAnimation('drawer.hideStart', {
options: { duration: 250, easing: 'ease' }
});
// Deny close
setDefaultAnimation('drawer.denyClose', {
keyframes: [{ transform: 'scale(1)' }, { transform: 'scale(1.01)' }, { transform: 'scale(1)' }],
options: { duration: 250 }
});
// Overlay
setDefaultAnimation('drawer.overlay.show', {
keyframes: [{ opacity: 0 }, { opacity: 1 }],