Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delay Before Popover Appears #85

Open
shelbyt opened this issue Dec 1, 2021 · 6 comments
Open

Delay Before Popover Appears #85

shelbyt opened this issue Dec 1, 2021 · 6 comments

Comments

@shelbyt
Copy link

shelbyt commented Dec 1, 2021

for the Mouse Over Interaction is it possible to have a delay (for debounce purposes) before the popover appears? i.e. Instead of the content showing up immediately, a user has to hover for about 800ms before the popover shows up.

Transition duration doesn't work because that just delays the animation, an 800ms transitionDuration just makes the fade come in over 800ms.

@jedwards1211
Copy link
Member

sorry for the delay. I'm busy with work stuff so it will take me awhile to look into this. I'd be open to a PR if I don't get to it first

@braco
Copy link

braco commented Feb 26, 2022

Did this ever get implemented?

@sidrak19
Copy link

+1 for this

@yunxu1630
Copy link

+1

@punkle
Copy link

punkle commented Dec 16, 2022

I wonder has anyone found a work around to achieve this?

@mfen
Copy link

mfen commented Apr 14, 2023

+1.

I wonder has anyone found a work around to achieve this?

A workaround might be to wrap the event handlers returned from bindHover() to inject a delay; seems to work with some light testing. e.g. with a custom hook:

export function bindDelayedHover(popupState: PopupState, delayMs = 200) {
  const { onTouchStart, onMouseOver, onMouseLeave, ...hoverAriaProps } =
    bindHover(popupState);

  const timeout = useRef<NodeJS.Timeout | null>(null);

  const delayedMouseOver = useCallback(
    (e: React.MouseEvent) => {
      if (timeout.current) clearTimeout(timeout.current);

      // material-ui-popup-state's event handler uses currentTarget to set the anchorEl, but
      // currentTarget is only defined while the initial event is firing. Save the original
      // and set it again before calling the delayed event handler
      const { currentTarget } = e;
      timeout.current = setTimeout(() => {
        e.currentTarget = currentTarget;
        onMouseOver(e);
      }, delayMs);
    },
    [onMouseOver]
  );

  const handleMouseLeave = useCallback(
    (e: React.MouseEvent) => {
      if (timeout.current) clearTimeout(timeout.current);
      onMouseLeave(e);
    },
    [onMouseLeave]
  );

  return {
    onTouchStart,
    onMouseOver: delayedMouseOver,
    onMouseLeave: handleMouseLeave,
    ...hoverAriaProps,
  };
}

Sample usage:

const popupState = usePopupState({
  variant: "popover",
  popupId: "example"
});

return (
  <>
    <span {...bindDelayedHover(popupState, 500)}>
      Example Hover
    </span>
    <HoverMenu
      {...bindMenu(popupState)}
      ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants