S
SolidJS4mo ago
Paul

@Floating-ui/solid port. 2 stories don't work.

Hello.
Firstly, thank you for taking a look at this humble support request. 😄 I do apologise in advance for the body of work this will entail. There is quite a lot of code to go through and due to that. This will probably take some time to not only understand the problem but also to provide a fix.
So I appreciate anyone who takes a look! Thank you! 🙇‍♂️ Code: https://github.com/paulm17/floating-ui Steps:
- Fork it: git clone https://github.com/paulm17/floating-ui
- cd floating-ui, pnpm i
- cd packages/utils, pnpm build
- cd packages/dom, pnpm build
- cd packages/core, pnpm build
- cd packages/solid, pnpm build
- cd apps/solid_docs, pnpm storybook
- Fork it: git clone https://github.com/paulm17/floating-ui
- cd floating-ui, pnpm i
- cd packages/utils, pnpm build
- cd packages/dom, pnpm build
- cd packages/core, pnpm build
- cd packages/solid, pnpm build
- cd apps/solid_docs, pnpm storybook
3 stories do not work - forgot 1 😮‍💨: 1) FloatingDelayGroup Once the tooltip has appeared, it should show immediately upon every next button hovered. Instead there is always a delay. The 2 lower buttons should always have a delay. 2) FloatingTree 2A) The floating popup disappears once the mouse enters a menu item. Note: sometimes it works but... 2B) then crashes once a submenu is opened. 3) FloatingList The solid version seems to want a context, when the react version doesn't. 🤷‍♂️ Note: don't worry about tests when making changes. Just getting to a point where this works is more than enough. 🚀 Finally, there is a react storybook for reference:
- cd apps/react_docs, pnpm storybook
- cd apps/react_docs, pnpm storybook
22 Replies
REEEEE
REEEEE4mo ago
Without actually running the code, for issue 1, I think it's because you're destructuring the delay from group context here and passing it on to useHover I would just make useHover only accept an Accessor for all props that you want to be reactive
Paul
PaulOP4mo ago
Ok, I missed that one 😩. Thanks for pointing it out. Oh right I remember now. The old storybook had useDelayGroupContext which is deprecated and so I asked Claude to change to useDelayGroup and thus I missed that. 🙄 I don't think the issue is in useHover. It's actually FloatingDelayGroup that's in play here.
createEffect(() => {
const { currentId, initialDelay, timeoutMs } = group;
const { open, onOpenChange } = floatingContext();

if (!open() && currentId === props.id) {
const unset = () => {
onOpenChange(false);
group.setState({ delay: initialDelay, currentId: null });
};

if (timeoutMs) {
const t = window.setTimeout(unset, timeoutMs);
onCleanup(() => {
clearTimeout(t);
});
} else {
unset();
}
}
});
createEffect(() => {
const { currentId, initialDelay, timeoutMs } = group;
const { open, onOpenChange } = floatingContext();

if (!open() && currentId === props.id) {
const unset = () => {
onOpenChange(false);
group.setState({ delay: initialDelay, currentId: null });
};

if (timeoutMs) {
const t = window.setTimeout(unset, timeoutMs);
onCleanup(() => {
clearTimeout(t);
});
} else {
unset();
}
}
});
This is the offending code. I believe it's always being called.
When the button loses focus, unset gets called. This doesn't happen in the react version.
Paul
PaulOP4mo ago
This one is funny: https://github.com/paulm17/floating-ui/blob/main/packages/solid/src/hooks/useHover.ts#L122 Change:
const {open, onOpenChange, refs} = context();
To:
// const {open, onOpenChange, refs} = context();
And set all the variables to context().open() for example. If you click the document a new window will open 😂
Paul
PaulOP4mo ago
😮‍💨
REEEEE
REEEEE4mo ago
Yeah open is a global thing in the browser so you have to be careful haha That would mean that timeoutMs is always undefined or 0?
Paul
PaulOP4mo ago
I'm pretty sure i changed all that destructuring. So annoying. 😮‍💨 I have updated the code.
createEffect(() => {
if (!floatingContext().open() && group.currentId === props.id) {
const unset = () => {
floatingContext().onOpenChange(false);
group.setState({ delay: group.initialDelay, currentId: null });
};

console.log('timeoutMs', group.timeoutMs)

if (group.timeoutMs) {
const t = window.setTimeout(unset, group.timeoutMs);
onCleanup(() => {
clearTimeout(t);
});
} else {
unset();
}
}
});
createEffect(() => {
if (!floatingContext().open() && group.currentId === props.id) {
const unset = () => {
floatingContext().onOpenChange(false);
group.setState({ delay: group.initialDelay, currentId: null });
};

console.log('timeoutMs', group.timeoutMs)

if (group.timeoutMs) {
const t = window.setTimeout(unset, group.timeoutMs);
onCleanup(() => {
clearTimeout(t);
});
} else {
unset();
}
}
});
console.log('timeoutMs', group.timeoutMs) fires 0 for the first button on mouseover and then nothing on subsequent hovers.
REEEEE
REEEEE4mo ago
Where does it get set?
Paul
PaulOP4mo ago
The default value is 0.
const FloatingDelayGroupContext = createContext<GroupContext>({
timeoutMs: props.timeoutMs ?? 0,
const FloatingDelayGroupContext = createContext<GroupContext>({
timeoutMs: props.timeoutMs ?? 0,
Right at the top of FloatingDelayGroup.tsx
REEEEE
REEEEE4mo ago
And it doesn't change?
Paul
PaulOP4mo ago
I don't think so. The only thing that mutates it is:
timeoutMs: props.timeoutMs ?? 0,
REEEEE
REEEEE4mo ago
So it would always run the else part then 🤔
Paul
PaulOP4mo ago
Yes, which I think the react version due to it blowing away and being diff'd. Doesn't have this issue.
I did make an issue for this yesterday: https://discord.com/channels/722131463138705510/1379096243585814619/1379118538442412276 I did try to make a single createEffect but I just couldn't get the desired result.
REEEEE
REEEEE4mo ago
Maybe it's this? What happens if you remove this else block
No description
Paul
PaulOP4mo ago
Nothing happens.
REEEEE
REEEEE4mo ago
does the other effect run? I'll take a deeper look later, pretty sure it's just some destructuring/reading properties in a non reactive context that's causing it
Paul
PaulOP4mo ago
yes the 2nd then the first
Paul
PaulOP4mo ago
Paul
PaulOP4mo ago
Thanks I appreciate that. I just went through the components/hooks and I changed any destructuring. except: - useClick - useClientPoint - useFocus
const {open, dataRef, refs} = context();
If I change them, then I get that window open issue and I don't know how to fix that yet. I tried to make it easy and provide a stackblitz: https://stackblitz.com/edit/create-storybook-solid-sdpsbcoy?file=storybook%2F.storybook%2Fmain.ts I can't even get that to work. I shouldn't have to be fighting solid all the time. I'm kinda getting burnt out.
Madaxen86
Madaxen864mo ago
'@tailwindcss/vite' doesn't in stackblitz because it runs binary code which is blocked by stackblitz. No Solid problem.
Paul
PaulOP4mo ago
Yes it does. I'm starting from https://discord.com/channels/722131463138705510/1103677541769814046/1379344014309986365 this dev's work. Here: https://stackblitz.com/edit/create-storybook-solid-6hbvzvto?file=storybook%2Fpackage.json So I took a working stackblitz added code and then it stopped working. @REEEEE just tried to DM you. So let me know when you get this message. Thanks!
REEEEE
REEEEE4mo ago
Update: think I fixed it? Although the example for the tooltips that should be receiving the full delay seems to be wrong/broken in both react and solid. Unsure if those were modified from any original Welp it was working and then I tried to remove some of the stuff I did and it broke 😂
Paul
PaulOP4mo ago
think I fixed it?
Nice! Good work! 🚀
Although the example for the tooltips that should be receiving the full delay seems to be wrong/broken in both react and solid.
My bad. I didn't notice that. I just updated both storybooks and the react version works now.

Did you find this page helpful?