From 539bb116e6783559b5628209c499ca82345177bc Mon Sep 17 00:00:00 2001 From: i18u Date: Thu, 29 Aug 2024 15:42:59 +0800 Subject: [PATCH 1/9] fix: click on shadowDOM popup should not close it --- src/index.tsx | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index f59b038..df10f0c 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -272,19 +272,23 @@ export function generateTrigger( const originChildProps = child?.props || {}; const cloneProps: typeof originChildProps = {}; + const inContainer = (container: Element, target: Element) => { + return ( + target === container || + container.contains(target) || + getShadowRoot(container)?.host === target || + container.contains(getShadowRoot(target)?.host) + ); + }; + const inPopupOrChild = useEvent((ele: EventTarget) => { const childDOM = targetEle; return ( - childDOM?.contains(ele as HTMLElement) || - getShadowRoot(childDOM)?.host === ele || - ele === childDOM || - popupEle?.contains(ele as HTMLElement) || - getShadowRoot(popupEle)?.host === ele || - ele === popupEle || - Object.values(subPopupElements.current).some( - (subPopupEle) => - subPopupEle?.contains(ele as HTMLElement) || ele === subPopupEle, + inContainer(childDOM, ele as Element) || + inContainer(popupEle, ele as Element) || + Object.values(subPopupElements.current).some((subPopupEle) => + inContainer(subPopupEle, ele as Element), ) ); }); From 1a764b197023a09efff6a9a348f193a177a7aeb9 Mon Sep 17 00:00:00 2001 From: i18u Date: Fri, 30 Aug 2024 11:57:19 +0800 Subject: [PATCH 2/9] feat: test click action on shadowDOM popup --- tests/shadow.test.tsx | 119 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/tests/shadow.test.tsx b/tests/shadow.test.tsx index b7e0580..e2cebf4 100644 --- a/tests/shadow.test.tsx +++ b/tests/shadow.test.tsx @@ -198,3 +198,122 @@ describe('Trigger.Shadow', () => { errSpy.mockRestore(); }); }); + +describe('Popup.Shadow', () => { + beforeEach(() => { + resetWarned(); + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + class CustomElement extends HTMLElement { + disconnectedCallback() {} + connectedCallback() { + const shadowRoot = this.attachShadow({ + mode: 'open', + }); + const container = document.createElement('div'); + shadowRoot.appendChild(container); + container.classList.add('shadow-container'); + container.innerHTML = `
Hello World
`; + } + } + + customElements.define('custom-element', CustomElement); + + it('should not close the popup when click the shadow content in the popup element', async () => { + const container = document.createElement('div'); + document.body.appendChild(container); + + act(() => { + createRoot(container).render( + <> +
outer
+ } + > +

+ + , + ); + }); + + await awaitFakeTimer(); + + // Click to show + fireEvent.click(document.querySelector('.target')); + await awaitFakeTimer(); + expect(document.querySelector('.popup')).toBeTruthy(); + + // Click outside to hide + fireEvent.mouseDown(document.querySelector('.outer')); + await awaitFakeTimer(); + expect(document.querySelector('.popup')).toBeFalsy(); + + // Click to show again + fireEvent.click(document.querySelector('.target')); + await awaitFakeTimer(); + expect(document.querySelector('.popup')).toBeTruthy(); + + // Click on popup element should not hide + fireEvent.mouseDown(document.querySelector('.popup')); + await awaitFakeTimer(); + expect(document.querySelector('.popup')).toBeTruthy(); + + // Click on shadow content should not hide + const popup = document.querySelector('.popup'); + fireEvent.mouseDown(popup.shadowRoot.querySelector('.shadow-content')); + await awaitFakeTimer(); + expect(document.querySelector('.popup')).toBeTruthy(); + }); + + it('should works with custom element trigger', async () => { + const container = document.createElement('div'); + document.body.innerHTML = ''; + document.body.appendChild(container); + + act(() => { + createRoot(container).render( + <> +

outer
+ } + > + + + , + ); + }); + + await awaitFakeTimer(); + + // Click to show + const target = document.querySelector('.target'); + fireEvent.click(target); + await awaitFakeTimer(); + expect(document.querySelector('.popup')).toBeTruthy(); + + // Click outside to hide + fireEvent.mouseDown(document.querySelector('.outer')); + await awaitFakeTimer(); + expect(document.querySelector('.popup')).toBeFalsy(); + + // Click shadow content to show + fireEvent.click(target.shadowRoot.querySelector('.shadow-content')); + await awaitFakeTimer(); + expect(document.querySelector('.popup')).toBeTruthy(); + + // Click on shadow content should not hide + const popup = document.querySelector('.popup'); + fireEvent.mouseDown(popup.shadowRoot.querySelector('.shadow-content')); + await awaitFakeTimer(); + expect(document.querySelector('.popup')).toBeTruthy(); + }); +}); From 271112ed8c0888cfd50064cac3686f893108819c Mon Sep 17 00:00:00 2001 From: i18u Date: Fri, 30 Aug 2024 12:12:48 +0800 Subject: [PATCH 3/9] Update index.tsx --- src/index.tsx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index df10f0c..9269d10 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -272,7 +272,7 @@ export function generateTrigger( const originChildProps = child?.props || {}; const cloneProps: typeof originChildProps = {}; - const inContainer = (container: Element, target: Element) => { + const inContainer = (target: Element, container: Element) => { return ( target === container || container.contains(target) || @@ -283,13 +283,12 @@ export function generateTrigger( const inPopupOrChild = useEvent((ele: EventTarget) => { const childDOM = targetEle; + const eleInContainer = inContainer.bind(null, ele as Element); return ( - inContainer(childDOM, ele as Element) || - inContainer(popupEle, ele as Element) || - Object.values(subPopupElements.current).some((subPopupEle) => - inContainer(subPopupEle, ele as Element), - ) + eleInContainer(childDOM) || + eleInContainer(popupEle) || + Object.values(subPopupElements.current).some(eleInContainer) ); }); From 9f887ade0b186a1ffff4083047f00450ae4dbd0e Mon Sep 17 00:00:00 2001 From: afc163 Date: Tue, 3 Sep 2024 15:53:45 +0800 Subject: [PATCH 4/9] Create global.d.ts --- global.d.ts | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 global.d.ts diff --git a/global.d.ts b/global.d.ts new file mode 100644 index 0000000..a08d46e --- /dev/null +++ b/global.d.ts @@ -0,0 +1,6 @@ +// global.d.ts +declare namespace JSX { + interface IntrinsicElements { + 'custom-element': React.DetailedHTMLProps, HTMLElement>; + } +} From fb4ff21261913de7a464fc8e3ae35df01bfbff18 Mon Sep 17 00:00:00 2001 From: afc163 Date: Tue, 3 Sep 2024 15:57:07 +0800 Subject: [PATCH 5/9] Apply suggestions from code review --- tests/shadow.test.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/shadow.test.tsx b/tests/shadow.test.tsx index e2cebf4..8cc0b66 100644 --- a/tests/shadow.test.tsx +++ b/tests/shadow.test.tsx @@ -235,7 +235,7 @@ describe('Popup.Shadow', () => { } + popup={} >

@@ -284,9 +284,9 @@ describe('Popup.Shadow', () => { } + popup={} > - + , ); From 5c9994c8a0cd3bf0d4b7a6baf75d06f19bd333ca Mon Sep 17 00:00:00 2001 From: afc163 Date: Tue, 3 Sep 2024 16:05:43 +0800 Subject: [PATCH 6/9] Update global.d.ts --- global.d.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/global.d.ts b/global.d.ts index a08d46e..0d3572f 100644 --- a/global.d.ts +++ b/global.d.ts @@ -1,6 +1,9 @@ // global.d.ts declare namespace JSX { interface IntrinsicElements { - 'custom-element': React.DetailedHTMLProps, HTMLElement>; + 'custom-element': React.DetailedHTMLProps< + React.HTMLAttributes & { class?: string }, + HTMLElement + >; } } From 9a1cf771558852ec3a1e7bfa6f6ab10af0a290ce Mon Sep 17 00:00:00 2001 From: afc163 Date: Tue, 3 Sep 2024 16:08:05 +0800 Subject: [PATCH 7/9] Update tests/shadow.test.tsx --- tests/shadow.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/shadow.test.tsx b/tests/shadow.test.tsx index 8cc0b66..71eaf94 100644 --- a/tests/shadow.test.tsx +++ b/tests/shadow.test.tsx @@ -235,7 +235,7 @@ describe('Popup.Shadow', () => { } + popup={} >

From 9ba15b28963e18c24cf9f95bf88019f9ac2597ff Mon Sep 17 00:00:00 2001 From: afc163 Date: Tue, 3 Sep 2024 16:08:11 +0800 Subject: [PATCH 8/9] Update tests/shadow.test.tsx --- tests/shadow.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/shadow.test.tsx b/tests/shadow.test.tsx index 71eaf94..b712d0d 100644 --- a/tests/shadow.test.tsx +++ b/tests/shadow.test.tsx @@ -286,7 +286,7 @@ describe('Popup.Shadow', () => { autoDestroy popup={} > - + , ); From b06750f3425cfdd1cbdcbb0c880f9154e2bc7325 Mon Sep 17 00:00:00 2001 From: afc163 Date: Tue, 3 Sep 2024 16:08:17 +0800 Subject: [PATCH 9/9] Update tests/shadow.test.tsx --- tests/shadow.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/shadow.test.tsx b/tests/shadow.test.tsx index b712d0d..e2cebf4 100644 --- a/tests/shadow.test.tsx +++ b/tests/shadow.test.tsx @@ -284,7 +284,7 @@ describe('Popup.Shadow', () => { } + popup={} >