ui icon indicating copy to clipboard operation
ui copied to clipboard

Improvement: Tooltip and HoverCard Mobile Support

Open chukwumaokere opened this issue 1 year ago • 8 comments

This is part of radix-ui but I noticed that there is no mobile support for HoverCard or Tooltip components. I have a web app where I use these for the desktop experience but a few users have said that it doesnt work on mobile, which is understandable given the library.

Just wanted to flag this as a possible future improvement. I'm thinking of implementing it myself, so I might open a PR to add tap support to Tooltips for mobile. Let me know if this is something we SHOULDNT pursue for any reason.

chukwumaokere avatar Jan 12 '24 19:01 chukwumaokere

Might hold off on this: https://github.com/shadcn-ui/ui/issues/86

In case you "need a tooltip" use a popover instead, as they do in their documentation.

chukwumaokere avatar Jan 12 '24 19:01 chukwumaokere

Yes, tooltips are designed for hover interaction while this interaction is not available on the mobile devices. However, I have noticed that some popular products use hybrid interactions based on the size on the screen.

  1. Desktop: Hover.
  2. Mobile: Click.

alamenai avatar Jan 13 '24 22:01 alamenai

I'm confused on the situation in terms of triggering tooltips with mobile touch.

It seems like a really obvious thing that desktop hover and mobile click are 1:1, and I'm sure most people who start using shadcn and radix are going to assume this is how it works.

It seems like it's possible the authors disagree / ignore (e.g. #86), but I am not sure where that puts us. Does anyone have a solution for converting existing tooltips to work for mobile?

My app is basically unusable on mobile without tooltip support, so really desperate for a solution 🙏

0xbid avatar Jan 22 '24 02:01 0xbid

But yeah @chukwumaokere I would totally use this change, it would be a lifesaver. Even if it didn't get merged I'd use the fork.

0xbid avatar Jan 22 '24 02:01 0xbid

Here's a component following the logic described by @alamenai

'use client';

import { PropsWithChildren, createContext, useContext, useEffect, useState } from 'react';
import { Tooltip, TooltipTrigger, TooltipContent } from './tooltip';
import { Popover, PopoverTrigger, PopoverContent } from './popover';
import { TooltipContentProps, TooltipProps, TooltipTriggerProps } from '@radix-ui/react-tooltip';
import { PopoverContentProps, PopoverProps, PopoverTriggerProps } from '@radix-ui/react-popover';

const TouchContext = createContext<boolean | undefined>(undefined);
const useTouch = () => useContext(TouchContext);

export const TouchProvider = (props: PropsWithChildren) => {
  const [isTouch, setTouch] = useState<boolean>();

  useEffect(() => {
    setTouch(window.matchMedia('(pointer: coarse)').matches);
  }, []);

  return <TouchContext.Provider value={isTouch} {...props} />;
};

export const HybridTooltip = (props: TooltipProps & PopoverProps) => {
  const isTouch = useTouch();

  return isTouch ? <Popover {...props} /> : <Tooltip {...props} />;
};

export const HybridTooltipTrigger = (props: TooltipTriggerProps & PopoverTriggerProps) => {
  const isTouch = useTouch();

  return isTouch ? <PopoverTrigger {...props} /> : <TooltipTrigger {...props} />;
};

export const HybridTooltipContent = (props: TooltipContentProps & PopoverContentProps) => {
  const isTouch = useTouch();

  return isTouch ? <PopoverContent {...props} /> : <TooltipContent {...props} />;
};

It mounts popover on touch devices and a tooltip by default.

luisdralves avatar Feb 06 '24 22:02 luisdralves

thanks @luisdralves!

0xbid avatar Feb 14 '24 05:02 0xbid

To summarise, they are three components:

Tooltip and Hover Card are only meant to be used on desktop. Popover is meant to be used on desktop and mobile.

This is a design choice by the Radix people. I think it wouldn't make sense to change it here at Shadcn-UI :thinking: so I reckon this issue can be closed.

Zwyx avatar Mar 12 '24 10:03 Zwyx

@luisdralves can you please show an example of how to use the hybrid tooltip component?

maatouk-j1 avatar Mar 23 '24 07:03 maatouk-j1

Sure, it's very similar to the regular tooltip. Just wrap your layout with the touch provider so that the isTouch state is calculated only once.


// Layout

import { TouchProvider } from '@/components/ui/hybrid-tooltip';
import './globals.css';

export default function RootLayout({ children }: React.PropsWithChildren) {
  return (
    <html lang='en'>
      <body>
        <TouchProvider>
          <main>{children}</main>
        </TouchProvider>
      </body>
    </html>
  );
}


// Page
import { HybridTooltip, HybridTooltipContent, HybridTooltipTrigger } from '@/components/ui/hybrid-tooltip';
import { TooltipProvider } from '@/components/ui/tooltip';

//...

export default function Page() {
  return (
    <div className='flex items-center gap-2'>
      <span>Tooltip example</span>
      
      <TooltipProvider delayDuration={0}>
        <HybridTooltip>
          <HybridTooltipTrigger asChild>
            <Button
              type='button'
              variant={'ghost'}
              className='h-6 w-6 rounded-full p-1 text-muted-foreground'
            >
              <Info className='h-4 w-4' />
            </Button>
          </HybridTooltipTrigger>

          <HybridTooltipContent>
            <p>Content</p>
          </HybridTooltipContent>
        </HybridTooltip>
      </TooltipProvider>
    </div>
  );
}

luisdralves avatar Mar 26 '24 13:03 luisdralves

I propose a different alternative, take a look at this gist below, it uses @floating-ui/react

https://gist.github.com/oxuk85/34e6969d6ec3971f4561d69f26571bb4

Here is the demo I found and used as the template for my own re-usable component. It works great on touch devices. https://codesandbox.io/p/sandbox/xenodochial-grass-js3bo9?file=%2Fsrc%2FTooltip.tsx

I found the suggestion using popover does not look great on mobile devices.

oxuk85 avatar Apr 10 '24 17:04 oxuk85

This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please leave a comment. Thank you.

shadcn avatar Jun 27 '24 23:06 shadcn