diff --git a/docs/resources/changelog.md b/docs/resources/changelog.md index 79eafc67..bb9e303b 100644 --- a/docs/resources/changelog.md +++ b/docs/resources/changelog.md @@ -14,6 +14,7 @@ _During the beta period, these restrictions may be relaxed in the event of a mis - Added tests for `` and `` [#935](https://github.com/shoelace-style/shoelace/pull/935) - Added translations for Turkish, English (United Kingdom) and German (Austria) [#989](https://github.com/shoelace-style/shoelace/pull/989) - Added `--indicator-transition-duration` custom property to `` [#986](https://github.com/shoelace-style/shoelace/issues/986) +- Added the ability to cancel `sl-show` and `sl-hide` events in `` [#993](https://github.com/shoelace-style/shoelace/issues/993) - Fixed a bug in `` that prevented the border radius to apply correctly to the header [#934](https://github.com/shoelace-style/shoelace/pull/934) - Fixed a bug in `` where the inner border disappeared on focus [#980](https://github.com/shoelace-style/shoelace/pull/980) - Improved `` to improve padding and render relative to the current font size diff --git a/src/components/details/details.test.ts b/src/components/details/details.test.ts index 9143b910..fd81b238 100644 --- a/src/components/details/details.test.ts +++ b/src/components/details/details.test.ts @@ -126,6 +126,44 @@ describe('', () => { expect(body.hidden).to.be.true; }); + it('should not open when preventing sl-show', async () => { + const el = await fixture(html` + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. + + `); + const showHandler = sinon.spy((event: CustomEvent) => event.preventDefault()); + + el.addEventListener('sl-show', showHandler); + el.open = true; + + await waitUntil(() => showHandler.calledOnce); + + expect(showHandler).to.have.been.calledOnce; + expect(el.open).to.be.false; + }); + + it('should not close when preventing sl-hide', async () => { + const el = await fixture(html` + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. + + `); + const hideHandler = sinon.spy((event: CustomEvent) => event.preventDefault()); + + el.addEventListener('sl-hide', hideHandler); + el.open = false; + + await waitUntil(() => hideHandler.calledOnce); + + expect(hideHandler).to.have.been.calledOnce; + expect(el.open).to.be.true; + }); + it('should be the correct size after opening more than one instance', async () => { const el = await fixture(html`
diff --git a/src/components/details/details.ts b/src/components/details/details.ts index 08d06370..fd416ff9 100644 --- a/src/components/details/details.ts +++ b/src/components/details/details.ts @@ -118,7 +118,11 @@ export default class SlDetails extends ShoelaceElement { async handleOpenChange() { if (this.open) { // Show - this.emit('sl-show'); + const slShow = this.emit('sl-show', { cancelable: true }); + if (slShow.defaultPrevented) { + this.open = false; + return; + } await stopAnimations(this.body); this.body.hidden = false; @@ -130,7 +134,11 @@ export default class SlDetails extends ShoelaceElement { this.emit('sl-after-show'); } else { // Hide - this.emit('sl-hide'); + const slHide = this.emit('sl-hide', { cancelable: true }); + if (slHide.defaultPrevented) { + this.open = true; + return; + } await stopAnimations(this.body);