Skip to content

Commit

Permalink
Add support for slotting elements into popovers
Browse files Browse the repository at this point in the history
  • Loading branch information
Totati committed Jul 19, 2024
1 parent 3e33182 commit cb6cce3
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 1 deletion.
44 changes: 44 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,50 @@ <h2 data-header>
&lt;div id="shadowedPopover" popover&gt;Shadowed Popover&lt;/div&gt;
&lt;div&gt;
&lt;div id="shadowedNestedPopover" popover&gt;Shadowed Nested Popover&lt;/div&gt;
&lt;/div&gt;</code></pre>
</section>

<section id="popover-shadow-root-with-slot" class="demo-item">
<h2 data-header>
<a href="#popover-shadow-root-with-slot" aria-hidden="true">🔗</a>
Element slotted in an Shadow Root Popover
</h2>
<p class="note">
Here, both the popover control button and the popover are created in
the Shadow DOM, but an element is slotted in the popover
</p>
<div id="shadowHostWithSlot">
<div><span>I'm a slotted element</span></div>
</div>
<script type="module">
const shadowHostWithSlot =
document.getElementById('shadowHostWithSlot'),
shadowHostWithSlotRoot = shadowHostWithSlot.attachShadow({
mode: 'open',
});
shadowHostWithSlotRoot.innerHTML = `
<style>
@layer reset, initial, popover-polyfill, default, demo;
@import url('/css/demo.css') layer(demo);
@import url('/css/fonts.css') layer(initial);
@import url('/css/base.css') layer(default);
</style>
<div id="shadowedPopoverWithSlot" popover data-popover><slot><slot></div>
<div class="button-group">
<button popovertarget="shadowedPopoverWithSlot" data-btn>
Toggle Shadowed Popover
</button>
</div>`;
</script>
<pre><code class="language-html"
>&lt;!-- Shadow DOM --&gt;
&lt;button popovertarget="shadowedPopoverWithSlot"&gt;
Toggle Shadowed Popover
&lt;/button&gt;

&lt;div id="shadowedPopoverWithSlot" popover&gt;
&lt;/slot&gt;&lt;/slot&gt;
&lt;/div&gt;</code></pre>
</section>
</div>
Expand Down
5 changes: 4 additions & 1 deletion src/popover-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,10 @@ function nearestInclusiveOpenPopover(
) {
return node;
}
node = node.parentElement || getRootNode(node);
node =
(node instanceof Element && node.assignedSlot) ||
node.parentElement ||
getRootNode(node);
if (node instanceof ShadowRoot) node = node.host;
if (node instanceof Document) return;
}
Expand Down
14 changes: 14 additions & 0 deletions tests/dismiss.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,17 @@ test('pressing Escape focused in popover dismisses auto popovers', async ({

await expect(singleActionShowPopover).toBeHidden();
});

test('click inside auto popover with a slotted element does not dismiss itself', async ({
page,
}) => {
const testPopover = (await page.locator('#shadowedPopoverWithSlot')).nth(0);
await expect(
await testPopover.evaluate((node) => node.showPopover()),
).toBeUndefined();
await expect(testPopover).toBeVisible();

const slottedText = (await page.locator('#shadowHostWithSlot span')).nth(0);
await slottedText.evaluate((node) => node.click());
await expect(testPopover).toBeVisible();
});

0 comments on commit cb6cce3

Please sign in to comment.