From ba14a43e6449ddc12366bad1ee52e9e900fede1e Mon Sep 17 00:00:00 2001 From: "BugMaker.Huang" Date: Mon, 21 Oct 2024 10:09:53 +0800 Subject: [PATCH] feat(overlay): make the closing behavior of the overlay controllable --- .changeset/odd-lizards-search.md | 6 +++++ .../Overlay/demos/OverlayWithContent.tsx | 2 +- docs/example/Overlay/index.md | 10 +++++---- packages/banana/src/overlay/index.test.ts | 22 ++++++++++++++++--- packages/banana/src/overlay/index.ts | 20 ++++++++++++++--- 5 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 .changeset/odd-lizards-search.md diff --git a/.changeset/odd-lizards-search.md b/.changeset/odd-lizards-search.md new file mode 100644 index 00000000..f49b66a8 --- /dev/null +++ b/.changeset/odd-lizards-search.md @@ -0,0 +1,6 @@ +--- +'@banana-ui/banana': patch +'@banana-ui/react': patch +--- + +Make the closing behavior of the overlay controllable. diff --git a/docs/example/Overlay/demos/OverlayWithContent.tsx b/docs/example/Overlay/demos/OverlayWithContent.tsx index 684fc89e..d26dbc3c 100644 --- a/docs/example/Overlay/demos/OverlayWithContent.tsx +++ b/docs/example/Overlay/demos/OverlayWithContent.tsx @@ -3,7 +3,7 @@ */ import { Button, Overlay } from '@banana-ui/react'; -import React, { useState } from 'react'; +import { useState } from 'react'; export default function OverlayWithContent() { const [visiable, setVisiable] = useState(false); diff --git a/docs/example/Overlay/index.md b/docs/example/Overlay/index.md index 1a5176a8..beb3fed1 100644 --- a/docs/example/Overlay/index.md +++ b/docs/example/Overlay/index.md @@ -19,10 +19,12 @@ group: 组件 ## 属性 - Attributes & Properties -| 属性 | 说明 | 类型 | 默认值 | -| ------ | --------------------- | --------- | ------ | -| open | 遮罩层是否可见 | `boolean` | false | -| zIndex | 设置遮罩层的`z-index` | `number` | 999 | +| 属性 | 说明 | 类型 | 默认值 | +| --------------------------------------------------------- | ------------------------- | --------- | ------ | +| open | 遮罩层是否可见 | `boolean` | false | +| zIndex | 设置遮罩层的`z-index` | `number` | 999 | +| noCloseWhenMaskClicked
(no-close-when-mask-clicked) | 点击遮罩层不触发关闭事件 | `boolean` | false | +| noCloseWhenEscPressed
(no-close-when-esc-pressed) | 按下`Esc`键不触发关闭事件 | `boolean` | false | ## 方法 - Methods diff --git a/packages/banana/src/overlay/index.test.ts b/packages/banana/src/overlay/index.test.ts index 1634d6c2..c86c00dd 100644 --- a/packages/banana/src/overlay/index.test.ts +++ b/packages/banana/src/overlay/index.test.ts @@ -1,7 +1,7 @@ -import { fixture, html, expect } from '@open-wc/testing'; -import BOverlay from '.'; -import sinon from 'sinon'; +import { expect, fixture, html } from '@open-wc/testing'; import { sendKeys } from '@web/test-runner-commands'; +import sinon from 'sinon'; +import BOverlay from '.'; describe('b-overlay', () => { it('when provided no parameters', async () => { @@ -105,4 +105,20 @@ describe('b-overlay', () => { element.shadowRoot?.querySelector('div')?.dispatchEvent(new Event('click')); expect(spy.called).to.equal(false); }); + + it('should not emit the close event when click on mask and noCloseWhenMaskClicked is true', async () => { + const element = await fixture(html` `); + const spy = sinon.spy(); + element.addEventListener('close', spy); + element.shadowRoot?.querySelector('.overlay__mask')?.dispatchEvent(new Event('click')); + expect(spy.called).to.equal(false); + }); + + it('should not emit the close event when press escape and noCloseWhenEscKeyPressed is true', async () => { + const element = await fixture(html` `); + const spy = sinon.spy(); + element.addEventListener('close', spy); + await sendKeys({ down: 'Escape' }); + expect(spy.called).to.equal(false); + }); }); diff --git a/packages/banana/src/overlay/index.ts b/packages/banana/src/overlay/index.ts index 4cebeaed..93b1a241 100644 --- a/packages/banana/src/overlay/index.ts +++ b/packages/banana/src/overlay/index.ts @@ -11,6 +11,14 @@ export default class BOverlay extends LitElement { @property({ type: Number }) zIndex = 999; + // If no-close-when-mask-clicked is true, the overlay will not dispatch a close event when the mask is clicked. + @property({ type: Boolean, attribute: 'no-close-when-mask-clicked' }) + noCloseWhenMaskClicked = false; + + // If no-close-when-esc-key-pressed is true, the overlay will not dispatch a close event when the esc key is pressed. + @property({ type: Boolean, attribute: 'no-close-when-esc-key-pressed' }) + noCloseWhenEscKeyPressed = false; + static styles: CSSResultGroup = styles; // A style element to set the overflow of body to hidden. @@ -56,11 +64,17 @@ export default class BOverlay extends LitElement { // Use arrow function to bind 'this' on BOverlay class. private _handleEscape = (e: KeyboardEvent) => { - if (e.key === 'Escape') { - void this._handleMaskClose(); + if (e.key === 'Escape' && !this.noCloseWhenEscKeyPressed) { + this._handleMaskClose(); } }; + private _handleMaskClick() { + if (!this.noCloseWhenMaskClicked) { + this._handleMaskClose(); + } + } + private _handleMaskClose() { this.dispatchEvent(new CustomEvent('close')); } @@ -78,7 +92,7 @@ export default class BOverlay extends LitElement {
-
+
`; } }