Skip to content

Instantly share code, notes, and snippets.

@h-jennings
Last active June 4, 2024 17:24
Show Gist options
  • Save h-jennings/302af00e5527c54ba4ad66d3387fee9c to your computer and use it in GitHub Desktop.
Save h-jennings/302af00e5527c54ba4ad66d3387fee9c to your computer and use it in GitHub Desktop.
Linear-style tooltip UX with Radix UI Primitives
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
import * as React from 'react';
import { twMerge } from 'tailwind-merge';
/**
* With this component, if the user moves the cursor between tooltip group, the
* delay is set to 0, this makes the next tooltip appear immediately.
*/
export const TooltipGroup = React.forwardRef<
HTMLDivElement,
React.ComponentPropsWithoutRef<'div'>
>(({ className, onMouseEnter, onMouseLeave, ...rest }, ref) => {
const [showInstant, setShowInstant] = React.useState(false);
const delay = showInstant ? 0 : 700;
return (
<TooltipGroupContext.Provider value={{ delay }}>
<div
ref={ref}
onMouseEnter={(e) => {
setShowInstant(true);
onMouseEnter?.(e);
}}
onMouseLeave={(e) => {
setShowInstant(false);
onMouseLeave?.(e);
}}
className={twMerge('h-fit', className)}
{...rest}
/>
</TooltipGroupContext.Provider>
);
});
TooltipGroup.displayName = 'TooltipGroup';
const TooltipGroupContext = React.createContext<{ delay: number } | null>(null);
export function TooltipProvider({
delayDuration,
...rest
}: React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Provider>) {
const { delay } = React.useContext(TooltipGroupContext) ?? {};
return (
<TooltipPrimitive.Provider
delayDuration={delayDuration ?? delay}
{...rest}
/>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment