Skip to content

Commit 915b3db

Browse files
fix(popover): working but hacky
1 parent 106fa80 commit 915b3db

File tree

4 files changed

+51
-18
lines changed

4 files changed

+51
-18
lines changed

packages/kit-headless/src/components/combobox/combobox-popover.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { component$, useContext, Slot, useTask$ } from '@builder.io/qwik';
1+
import { component$, useContext, Slot, useTask$, useId } from '@builder.io/qwik';
22
import { Popover, usePopover } from '../popover';
33

44
import ComboboxContextId from './combobox-context-id';
@@ -8,15 +8,16 @@ import { PopoverImplProps } from '../popover/popover-impl';
88
export const ComboboxPopover = component$(
99
(props: Partial<FloatingProps & PopoverImplProps>) => {
1010
const context = useContext(ComboboxContextId);
11-
const popoverId = `${context.localId}-popover`;
12-
const { initPopover$ } = usePopover(popoverId);
11+
const customPopoverId = useId();
12+
console.log('customPopoverId:', customPopoverId);
13+
const { initPopover$ } = usePopover(customPopoverId);
1314

1415
/* REMEMBER, whenever an option is selected or onMouseDown$ the listbox is closed, and the popover should sync to that */
1516
useTask$(async ({ track }) => {
1617
track(() => context.isListboxOpenSig.value);
1718
track(() => context.popoverRef.value);
1819

19-
console.log('LISTBOX OPEN: ', context.isListboxOpenSig.value);
20+
console.log('POPOVER REF:', context.popoverRef.value);
2021

2122
if (context.isListboxOpenSig.value) {
2223
await initPopover$();
@@ -29,7 +30,7 @@ export const ComboboxPopover = component$(
2930
return (
3031
<Popover
3132
{...props}
32-
id={popoverId}
33+
id={customPopoverId}
3334
floating={true}
3435
anchorRef={context.inputRef}
3536
popoverRef={context.popoverRef}

packages/kit-headless/src/components/popover/floating.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ export const FloatingPopover = component$(
8686
const popover = track(() => popoverRef.value);
8787
if (!popover || !anchor) return;
8888

89+
console.log('INSIDE FLOATING: ', popoverRef.value);
90+
8991
const updatePosition = async () => {
9092
const middleware = [
9193
_offset(gutter),

packages/kit-headless/src/components/popover/popover-impl.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import {
44
useSignal,
55
useStyles$,
66
useContext,
7+
useTask$,
78
type Signal,
89
type ClassList,
910
createContextId,
10-
useTask$,
1111
} from '@builder.io/qwik';
1212

1313
import { isServer } from '@builder.io/qwik/build';
@@ -53,17 +53,24 @@ export const PopoverImpl = component$<PopoverImplProps>((props) => {
5353
/** have we rendered on the client yet? 0: no, 1: force, 2: yes */
5454
const hasRenderedOnClientSig = useSignal(isServer ? 0 : 2);
5555
const teleportSig = useSignal(false);
56+
const isToggledSig = useSignal(false);
5657

5758
// This forces a re-render on each popover instance when the signal changes
5859
if (hasRenderedOnClientSig.value === 1) {
59-
console.log('I RERENDER!');
6060
// Now run the task again after we force-rendered the contex
6161
setTimeout(() => (teleportSig.value = true), 0);
6262
}
6363

64+
useTask$(({ track }) => {
65+
track(() => isToggledSig.value);
66+
67+
if (props.popoverRef) {
68+
props.popoverRef.value = popoverRef.value;
69+
}
70+
});
71+
6472
useTask$(async ({ track, cleanup }) => {
6573
track(() => teleportSig.value);
66-
console.log('inside task');
6774

6875
if (isServer) return;
6976

@@ -78,11 +85,6 @@ export const PopoverImpl = component$<PopoverImplProps>((props) => {
7885
}
7986

8087
if (popoverRef.value) {
81-
// user passed in popover ref (context, state, etc.)
82-
if (props.popoverRef) {
83-
props.popoverRef.value = popoverRef.value;
84-
}
85-
8688
polyfillContainer.appendChild(popoverRef.value);
8789

8890
document.dispatchEvent(new CustomEvent('showpopover'));
@@ -102,6 +104,7 @@ export const PopoverImpl = component$<PopoverImplProps>((props) => {
102104
popover={props.manual || props.popover === 'manual' ? 'manual' : 'auto'}
103105
ref={popoverRef}
104106
onToggle$={(e) => {
107+
isToggledSig.value = true;
105108
if (!popoverRef.value) return;
106109

107110
const popover = popoverRef.value;

packages/kit-headless/src/components/popover/popover-trigger.tsx

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { QwikIntrinsicElements, useOnDocument } from '@builder.io/qwik';
1+
import { QwikIntrinsicElements, useOnDocument, useTask$ } from '@builder.io/qwik';
22
import { Slot, component$, useSignal, $ } from '@builder.io/qwik';
3+
import { isBrowser } from '@builder.io/qwik/build';
34

45
type PopoverTriggerProps = {
56
popovertarget: string;
@@ -10,6 +11,7 @@ type PopoverTriggerProps = {
1011
export function usePopover(popovertarget: string) {
1112
const hasPolyfillLoadedSig = useSignal<boolean>(false);
1213
const didInteractSig = useSignal<boolean>(false);
14+
const isSupportedSig = useSignal<boolean>(false);
1315

1416
const loadPolyfill$ = $(async () => {
1517
await import('@oddbird/popover-polyfill');
@@ -23,13 +25,33 @@ export function usePopover(popovertarget: string) {
2325
typeof HTMLElement.prototype === 'object' &&
2426
'popover' in HTMLElement.prototype;
2527

28+
isSupportedSig.value = isSupported;
29+
console.log('INSIDE HERE: ', isSupportedSig.value);
30+
2631
if (!hasPolyfillLoadedSig.value && !isSupported) {
2732
await loadPolyfill$();
2833
hasPolyfillLoadedSig.value = true;
2934
}
3035
didInteractSig.value = true;
3136
});
3237

38+
useTask$(({ track }) => {
39+
track(() => didInteractSig.value);
40+
41+
if (isBrowser && isSupportedSig.value) {
42+
const popover = document.getElementById(popovertarget);
43+
44+
if (!popover) return;
45+
46+
console.log('inside interact task: ', popover);
47+
console.log('popover id: ', popovertarget);
48+
49+
if (popover && popover.hasAttribute('popover')) {
50+
popover.showPopover();
51+
}
52+
}
53+
});
54+
3355
// event is created after teleported properly
3456
useOnDocument(
3557
'showpopover',
@@ -46,24 +68,29 @@ export function usePopover(popovertarget: string) {
4668
if (!popover.classList.contains(':popover-open')) {
4769
// @ts-ignore
4870
popover.showPopover();
49-
console.log('inside the showpopover doc');
5071
}
5172
}),
5273
);
5374

54-
return { initPopover$ };
75+
return { initPopover$, isSupportedSig };
5576
}
5677

5778
export const PopoverTrigger = component$<PopoverTriggerProps>(
5879
({ popovertarget, ...rest }: PopoverTriggerProps) => {
59-
const { initPopover$ } = usePopover(popovertarget);
80+
const { initPopover$, isSupportedSig } = usePopover(popovertarget);
6081

6182
return (
6283
<button
6384
{...rest}
6485
// @ts-expect-error bad types
6586
popovertarget={popovertarget}
66-
onClick$={[rest.onClick$, $(() => initPopover$())]}
87+
onClick$={[
88+
rest.onClick$,
89+
$(() => {
90+
console.log('isSupported: ', isSupportedSig.value);
91+
initPopover$();
92+
}),
93+
]}
6794
>
6895
<Slot />
6996
</button>

0 commit comments

Comments
 (0)