Skip to content

Commit 51d1a7f

Browse files
Merge pull request #716 from thejackshelton/fix-popover
refactor: improved popover middle tests
2 parents 5481490 + 1ff2d38 commit 51d1a7f

File tree

6 files changed

+150
-107
lines changed

6 files changed

+150
-107
lines changed

.changeset/blue-spiders-flash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik-ui/headless': patch
3+
---
4+
5+
fix: race condition in the popover when programmatically opening on supported browsers
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { component$ } from '@builder.io/qwik';
2+
import { Popover, PopoverTrigger } from '@qwik-ui/headless';
3+
export default component$(() => {
4+
return (
5+
<>
6+
<PopoverTrigger popovertarget="hero-id" class="popover-trigger">
7+
Popover Trigger
8+
</PopoverTrigger>
9+
<Popover id="hero-id" class="popover">
10+
My Hero!
11+
</Popover>
12+
</>
13+
);
14+
});

apps/website/src/routes/docs/headless/popover/examples/hero.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
1-
import { component$ } from '@builder.io/qwik';
1+
import { component$, useSignal } from '@builder.io/qwik';
22
import { Popover, PopoverTrigger } from '@qwik-ui/headless';
3+
34
export default component$(() => {
5+
const triggerRef = useSignal<HTMLButtonElement>();
6+
47
return (
58
<>
6-
<PopoverTrigger popovertarget="hero-id" class="popover-trigger">
7-
Popover Trigger
9+
<PopoverTrigger ref={triggerRef} popovertarget="popover-id" class="popover-trigger">
10+
Click me
811
</PopoverTrigger>
9-
<Popover id="hero-id" class="popover">
10-
My Hero!
12+
<Popover
13+
anchorRef={triggerRef}
14+
floating={true}
15+
gutter={4}
16+
id="popover-id"
17+
class="popover"
18+
>
19+
I am anchored to the popover trigger!
1120
</Popover>
1221
</>
1322
);

apps/website/src/routes/docs/headless/popover/index.mdx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,17 @@ A non-modal primitive with overlays that open and close around a DOM element.
2323
]}
2424
/>
2525

26+
<Note status="warning">
27+
You are about to see a fixed scrolling popover. Yes, this behavior is intended. It is
28+
part of the native popover API! If you want to anchor items, there is a floating section
29+
that covers this behavior.
30+
</Note>
31+
32+
<Showcase name="basic" />
33+
2634
The Qwik UI Popover component is designed to align with the [HTML Popover API Specification](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API). As of now, native support for this API is around `82.5%`, and in almost every browser.
2735

28-
To ensure consistent behavior across all browsers, Qwik UI provides a `polyfill` for browser versions that do not support the API natively.
36+
To ensure consistent behavior across all browsers, Qwik UI provides a `polyfill` with feature parity for browser versions that do not support the API natively.
2937

3038
<div class="flex flex-col gap-2">
3139
<div>
@@ -296,7 +304,9 @@ useTask$(async ({ track }) => {
296304

297305
To use the popover API with floating elements, you can add the `floating={true}` prop to the Popover component. This API enables the use of JavaScript to dynamically position the listbox using the `top` & `left` absolute properties.
298306

299-
> Enabling the `floating={true}` property will introduce a slight increase in code size, as we currently utilize JavaScript to implement floating items. We've strived to keep it as minimal as possible, but powerful in building complex components in anticipation of the forthcoming anchor API.
307+
Enabling the `floating={true}` property will introduce a slight increase in code size, as we currently utilize JavaScript to implement floating items. We've strived to keep it as minimal as possible, but powerful in building complex components.
308+
309+
> Once the native anchor API is available in all browsers, you can remove the floating prop and use CSS instead! Smaller bundle size for the win!
300310
301311
To float an element, it must have an anchored element to latch onto. This can be done with the `anchorRef` prop.
302312

packages/kit-headless/src/components/popover/popover.driver.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { type Locator, type Page } from '@playwright/test';
1+
import { expect, type Locator, type Page } from '@playwright/test';
22

33
export type DriverLocator = Locator | Page;
44

5+
export type PopoverOpenKeys = 'Enter' | 'Space';
6+
57
export function createTestDriver<T extends DriverLocator>(rootLocator: T) {
68
const getPopover = () => {
79
return rootLocator.locator('[popover]');
@@ -11,6 +13,21 @@ export function createTestDriver<T extends DriverLocator>(rootLocator: T) {
1113
return rootLocator.locator('[popovertarget]');
1214
};
1315

16+
const openPopover = async (key: PopoverOpenKeys | 'click', index?: number) => {
17+
const action = key === 'click' ? 'click' : 'press';
18+
const trigger = index !== undefined ? getTrigger().nth(index) : getTrigger();
19+
const popover = index !== undefined ? getPopover().nth(index) : getPopover();
20+
21+
if (action === 'click') {
22+
await trigger.click({ position: { x: 1, y: 1 } }); // Modified line
23+
} else {
24+
await trigger.press(key);
25+
}
26+
27+
// Needed because Playwright doesn't wait for the listbox to be visible
28+
await expect(popover).toBeVisible();
29+
};
30+
1431
const getAllPopovers = () => {
1532
return getPopover().all();
1633
};
@@ -30,6 +47,7 @@ export function createTestDriver<T extends DriverLocator>(rootLocator: T) {
3047
getAllPopovers,
3148
getTrigger,
3249
getAllTriggers,
50+
openPopover,
3351
getProgrammaticButtonTrigger,
3452
};
3553
}

0 commit comments

Comments
 (0)