add source to dialog/drawer event

pull/669/head
Cory LaViska 2022-02-10 10:34:22 -05:00
rodzic f555a3323e
commit 3e35b0f7c6
5 zmienionych plików z 69 dodań i 29 usunięć

Wyświetl plik

@ -159,10 +159,12 @@ By default, dialogs will close when the user clicks the close button, clicks the
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. 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.
You can use `event.detail.source` to determine what triggered the request to close. This example prevents the dialog from closing when the overlay is clicked, but allows the close button or <kbd>Escape</kbd> to dismiss it.
```html preview ```html preview
<sl-dialog label="Dialog" class="dialog-deny-close"> <sl-dialog label="Dialog" class="dialog-deny-close">
This dialog will not close unless you use the button below. This dialog will not close when you click on the overlay.
<sl-button slot="footer" variant="primary">Save &amp; Close</sl-button> <sl-button slot="footer" variant="primary">Close</sl-button>
</sl-dialog> </sl-dialog>
<sl-button>Open Dialog</sl-button> <sl-button>Open Dialog</sl-button>
@ -170,12 +172,17 @@ To keep the dialog open in such cases, you can cancel the `sl-request-close` eve
<script> <script>
const dialog = document.querySelector('.dialog-deny-close'); const dialog = document.querySelector('.dialog-deny-close');
const openButton = dialog.nextElementSibling; const openButton = dialog.nextElementSibling;
const saveButton = dialog.querySelector('sl-button[slot="footer"]'); const closeButton = dialog.querySelector('sl-button[slot="footer"]');
openButton.addEventListener('click', () => dialog.show()); openButton.addEventListener('click', () => dialog.show());
saveButton.addEventListener('click', () => dialog.hide()); closeButton.addEventListener('click', () => dialog.hide());
dialog.addEventListener('sl-request-close', event => event.preventDefault()); // Prevent the dialog from closing when the user clicks on the overlay
dialog.addEventListener('sl-request-close', event => {
if (event.detail.source === 'overlay') {
event.preventDefault();
}
});
</script> </script>
``` ```
@ -186,17 +193,24 @@ import { SlButton, SlDialog } from '@shoelace-style/shoelace/dist/react';
const App = () => { const App = () => {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
// Prevent the dialog from closing when the user clicks on the overlay
function handleRequestClose(event) {
if (event.detail.source === 'overlay') {
event.preventDefault();
}
}
return ( return (
<> <>
<SlDialog <SlDialog
label="Dialog" label="Dialog"
open={open} open={open}
onSlRequestClose={event => event.preventDefault()} onSlRequestClose={handleRequestClose}
onSlAfterHide={() => setOpen(false)} onSlAfterHide={() => setOpen(false)}
> >
This dialog will not close unless you use the button below. This dialog will not close when you click on the overlay.
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}> <SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
Save &amp; Close Close
</SlButton> </SlButton>
</SlDialog> </SlDialog>

Wyświetl plik

@ -346,10 +346,12 @@ By default, drawers will close when the user clicks the close button, clicks the
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. 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.
You can use `event.detail.source` to determine what triggered the request to close. This example prevents the drawer from closing when the overlay is clicked, but allows the close button or <kbd>Escape</kbd> to dismiss it.
```html preview ```html preview
<sl-drawer label="Drawer" class="drawer-deny-close"> <sl-drawer label="Drawer" class="drawer-deny-close">
This drawer will not close unless you use the button below. This drawer will not close when you click on the overlay.
<sl-button slot="footer" variant="primary">Save &amp; Close</sl-button> <sl-button slot="footer" variant="primary">Close</sl-button>
</sl-drawer> </sl-drawer>
<sl-button>Open Drawer</sl-button> <sl-button>Open Drawer</sl-button>
@ -362,7 +364,13 @@ To keep the drawer open in such cases, you can cancel the `sl-request-close` eve
openButton.addEventListener('click', () => drawer.show()); openButton.addEventListener('click', () => drawer.show());
closeButton.addEventListener('click', () => drawer.hide()); closeButton.addEventListener('click', () => drawer.hide());
drawer.addEventListener('sl-request-close', event => event.preventDefault()); // Prevent the drawer from closing when the user clicks on the overlay
drawer.addEventListener('sl-request-close', event => {
if (event.detail.source === 'overlay') {
event.preventDefault();
}
});
</script> </script>
``` ```
@ -373,15 +381,22 @@ import { SlButton, SlDrawer } from '@shoelace-style/shoelace/dist/react';
const App = () => { const App = () => {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
// Prevent the drawer from closing when the user clicks on the overlay
function handleRequestClose(event) {
if (event.detail.source === 'overlay') {
event.preventDefault();
}
}
return ( return (
<> <>
<SlDrawer <SlDrawer
label="Drawer" label="Drawer"
open={open} open={open}
onSlRequestClose={event => event.preventDefault()} onSlRequestClose={handleRequestClose}
onSlAfterHide={() => setOpen(false)} onSlAfterHide={() => setOpen(false)}
> >
This drawer will not close unless you use the button below. This drawer will not close when you click on the overlay.
<SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}> <SlButton slot="footer" variant="primary" onClick={() => setOpen(false)}>
Save &amp; Close Save &amp; Close
</SlButton> </SlButton>

Wyświetl plik

@ -11,6 +11,7 @@ _During the beta period, these restrictions may be relaxed in the event of a mis
- 🚨 BREAKING: the `unit` property of `<sl-format-bytes>` has changed to `byte | bit` instead of `bytes | bits` - 🚨 BREAKING: the `unit` property of `<sl-format-bytes>` has changed to `byte | bit` instead of `bytes | bits`
- Added `display-label` part to `<sl-select>` [#650](https://github.com/shoelace-style/shoelace/issues/650) - Added `display-label` part to `<sl-select>` [#650](https://github.com/shoelace-style/shoelace/issues/650)
- Added `--spacing` CSS custom property to `<sl-divider>` [#664](https://github.com/shoelace-style/shoelace/pull/664) - Added `--spacing` CSS custom property to `<sl-divider>` [#664](https://github.com/shoelace-style/shoelace/pull/664)
- Added `event.detail.source` to the `sl-request-close` event in `<sl-dialog>` and `<sl-drawer>`
- Fixed a bug that caused `<sl-progress-ring>` to render the wrong size when `--track-width` was increased [#656](https://github.com/shoelace-style/shoelace/issues/656) - Fixed a bug that caused `<sl-progress-ring>` to render the wrong size when `--track-width` was increased [#656](https://github.com/shoelace-style/shoelace/issues/656)
- Fixed a bug that allowed `<sl-details>` to open and close when disabled using a screen reader [#658](https://github.com/shoelace-style/shoelace/issues/658) - Fixed a bug that allowed `<sl-details>` to open and close when disabled using a screen reader [#658](https://github.com/shoelace-style/shoelace/issues/658)
- Fixed a bug in the FormData event polyfill that threw an error in some environments [#666](https://github.com/shoelace-style/shoelace/issues/666) - Fixed a bug in the FormData event polyfill that threw an error in some environments [#666](https://github.com/shoelace-style/shoelace/issues/666)

Wyświetl plik

@ -32,9 +32,10 @@ const hasPreventScroll = isPreventScrollSupported();
* @event sl-after-hide - Emitted after the dialog closes and all animations are complete. * @event sl-after-hide - Emitted after the dialog closes and all animations are complete.
* @event sl-initial-focus - Emitted when the dialog opens and the panel gains focus. Calling `event.preventDefault()` * @event sl-initial-focus - Emitted when the dialog opens and the panel gains focus. Calling `event.preventDefault()`
* will prevent focus and allow you to set it on a different element in the dialog, such as an input or button. * will prevent focus and allow you to set it on a different element in the dialog, such as an input or button.
* @event sl-request-close - Emitted when the user attempts to close the dialog by clicking the close button, clicking the * @event {{ source: 'close-button' | 'keyboard' | 'overlay' }} sl-request-close - Emitted when the user attempts to
* overlay, or pressing the escape key. Calling `event.preventDefault()` will prevent the dialog from closing. Avoid * close the dialog by clicking the close button, clicking the overlay, or pressing escape. Calling
* using this unless closing the dialog will result in destructive behavior such as data loss. * `event.preventDefault()` will keep the dialog open. Avoid using this unless closing the dialog will result in
* destructive behavior such as data loss.
* *
* @csspart base - The component's base wrapper. * @csspart base - The component's base wrapper.
* @csspart overlay - The overlay. * @csspart overlay - The overlay.
@ -123,8 +124,12 @@ export default class SlDialog extends LitElement {
return waitForEvent(this, 'sl-after-hide'); return waitForEvent(this, 'sl-after-hide');
} }
private requestClose() { private requestClose(source: 'close-button' | 'keyboard' | 'overlay') {
const slRequestClose = emit(this, 'sl-request-close', { cancelable: true }); const slRequestClose = emit(this, 'sl-request-close', {
cancelable: true,
detail: { source }
});
if (slRequestClose.defaultPrevented) { if (slRequestClose.defaultPrevented) {
const animation = getAnimation(this, 'dialog.denyClose'); const animation = getAnimation(this, 'dialog.denyClose');
animateTo(this.panel, animation.keyframes, animation.options); animateTo(this.panel, animation.keyframes, animation.options);
@ -137,7 +142,7 @@ export default class SlDialog extends LitElement {
handleKeyDown(event: KeyboardEvent) { handleKeyDown(event: KeyboardEvent) {
if (event.key === 'Escape') { if (event.key === 'Escape') {
event.stopPropagation(); event.stopPropagation();
this.requestClose(); this.requestClose('keyboard');
} }
} }
@ -217,7 +222,7 @@ export default class SlDialog extends LitElement {
})} })}
@keydown=${this.handleKeyDown} @keydown=${this.handleKeyDown}
> >
<div part="overlay" class="dialog__overlay" @click=${this.requestClose} tabindex="-1"></div> <div part="overlay" class="dialog__overlay" @click=${() => this.requestClose('overlay')} tabindex="-1"></div>
<div <div
part="panel" part="panel"
@ -241,7 +246,7 @@ export default class SlDialog extends LitElement {
name="x" name="x"
label=${this.localize.term('close')} label=${this.localize.term('close')}
library="system" library="system"
@click="${this.requestClose}" @click="${() => this.requestClose('close-button')}"
></sl-icon-button> ></sl-icon-button>
</header> </header>
` `

Wyświetl plik

@ -33,9 +33,10 @@ const hasPreventScroll = isPreventScrollSupported();
* @event sl-after-hide - Emitted after the drawer closes and all animations are complete. * @event sl-after-hide - Emitted after the drawer closes and all animations are complete.
* @event sl-initial-focus - Emitted when the drawer opens and the panel gains focus. Calling `event.preventDefault()` will * @event sl-initial-focus - 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. * prevent focus and allow you to set it on a different element in the drawer, such as an input or button.
* @event sl-request-close - Emitted when the user attempts to close the drawer by clicking the close button, clicking the * @event {{ source: 'close-button' | 'keyboard' | 'overlay' }} sl-request-close - Emitted when the user attempts to
* overlay, or pressing the escape key. Calling `event.preventDefault()` will prevent the drawer from closing. Avoid * close the drawer by clicking the close button, clicking the overlay, or pressing escape. Calling
* using this unless closing the drawer will result in destructive behavior such as data loss. * `event.preventDefault()` will keep the drawer open. Avoid using this unless closing the drawer will result in
* destructive behavior such as data loss.
* *
* @csspart base - The component's base wrapper. * @csspart base - The component's base wrapper.
* @csspart overlay - The overlay. * @csspart overlay - The overlay.
@ -140,8 +141,12 @@ export default class SlDrawer extends LitElement {
return waitForEvent(this, 'sl-after-hide'); return waitForEvent(this, 'sl-after-hide');
} }
private requestClose() { private requestClose(source: 'close-button' | 'keyboard' | 'overlay') {
const slRequestClose = emit(this, 'sl-request-close', { cancelable: true }); const slRequestClose = emit(this, 'sl-request-close', {
cancelable: true,
detail: { source }
});
if (slRequestClose.defaultPrevented) { if (slRequestClose.defaultPrevented) {
const animation = getAnimation(this, 'drawer.denyClose'); const animation = getAnimation(this, 'drawer.denyClose');
animateTo(this.panel, animation.keyframes, animation.options); animateTo(this.panel, animation.keyframes, animation.options);
@ -154,7 +159,7 @@ export default class SlDrawer extends LitElement {
handleKeyDown(event: KeyboardEvent) { handleKeyDown(event: KeyboardEvent) {
if (event.key === 'Escape') { if (event.key === 'Escape') {
event.stopPropagation(); event.stopPropagation();
this.requestClose(); this.requestClose('keyboard');
} }
} }
@ -243,7 +248,7 @@ export default class SlDrawer extends LitElement {
})} })}
@keydown=${this.handleKeyDown} @keydown=${this.handleKeyDown}
> >
<div part="overlay" class="drawer__overlay" @click=${this.requestClose} tabindex="-1"></div> <div part="overlay" class="drawer__overlay" @click=${() => this.requestClose('overlay')} tabindex="-1"></div>
<div <div
part="panel" part="panel"
@ -268,7 +273,7 @@ export default class SlDrawer extends LitElement {
name="x" name="x"
label=${this.localize.term('close')} label=${this.localize.term('close')}
library="system" library="system"
@click=${this.requestClose} @click=${() => this.requestClose('close-button')}
></sl-icon-button> ></sl-icon-button>
</header> </header>
` `