-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Event handling for "click outside" when mounted in shadow dom
- Loading branch information
1 parent
0063cdb
commit 122d15f
Showing
9 changed files
with
149 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { eventIsInside } from './events'; | ||
|
||
describe('eventIsInside', () => { | ||
it('should return true when event target\'s is inside the container', () => { | ||
const container = document.createElement('div'); | ||
const target = document.createElement('a'); | ||
container.appendChild(target); | ||
const event = { | ||
target, | ||
} as Partial<Event> as Event; | ||
|
||
const isInside = eventIsInside(event, container); | ||
|
||
expect(isInside).toBe(true); | ||
}); | ||
|
||
it('should return true when event target\'s is the container', () => { | ||
const container = document.createElement('div'); | ||
const event = { | ||
target: container, | ||
} as Partial<Event> as Event; | ||
|
||
const isInside = eventIsInside(event, container); | ||
|
||
expect(isInside).toBe(true); | ||
}); | ||
|
||
it('should return false when event target\'s is outside the container', () => { | ||
const container = document.createElement('div'); | ||
const target = document.createElement('a'); | ||
const event = { | ||
target, | ||
} as Partial<Event> as Event; | ||
|
||
const isInside = eventIsInside(event, container); | ||
|
||
expect(isInside).toBe(false); | ||
}); | ||
|
||
it('should return true when event target\'s from composedPath is inside the container', () => { | ||
const container = document.createElement('div'); | ||
const target = document.createElement('a'); | ||
container.appendChild(target); | ||
const event = { | ||
composed: true, | ||
composedPath(): EventTarget[] { | ||
return [target, container, document]; | ||
}, | ||
} as Partial<Event> as Event; | ||
|
||
const isInside = eventIsInside(event, container); | ||
|
||
expect(isInside).toBe(true); | ||
}); | ||
|
||
it('should return true when event target\'s from composedPath is the container', () => { | ||
const container = document.createElement('div'); | ||
const event = { | ||
composed: true, | ||
composedPath(): EventTarget[] { | ||
return [container, document]; | ||
}, | ||
} as Partial<Event> as Event; | ||
|
||
const isInside = eventIsInside(event, container); | ||
|
||
expect(isInside).toBe(true); | ||
}); | ||
|
||
it('should return false when event target\'s from composedPath is outside the container', () => { | ||
const container = document.createElement('div'); | ||
const target = document.createElement('a'); | ||
const event = { | ||
composed: true, | ||
composedPath(): EventTarget[] { | ||
return [target, document]; | ||
}, | ||
} as Partial<Event> as Event; | ||
|
||
const isInside = eventIsInside(event, container); | ||
|
||
expect(isInside).toBe(false); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
function extractNodes(eventTargets: EventTarget[]): Node[] { | ||
return eventTargets.filter((eventTarget): eventTarget is Node => eventTarget instanceof Node); | ||
} | ||
|
||
export function eventIsInside<T extends Event>(event: T, ...containers: (HTMLElement | null)[]): boolean { | ||
const composedNodes: Node[] = event.composed ? extractNodes(event.composedPath()) : []; | ||
|
||
return containers.filter(Boolean).some((container) => ( | ||
container?.contains(event.target as Node) | ||
|| (event.composed && composedNodes.some((composedNode) => container?.contains(composedNode))) | ||
)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { ThemeWrapper } from '@equisoft/design-elements-react'; | ||
import React, { ComponentType } from 'react'; | ||
import { Decorator } from './decorator'; | ||
|
||
export const ShadowDomDecorator: Decorator = (Story: ComponentType) => ( | ||
<ThemeWrapper isolateStyles><Story /></ThemeWrapper> | ||
); |