atomiks/tippyjs-react

Show different text on hover (Copy To Clipboard) & on click (Copied)?

deadcoder0904 opened this issue · 2 comments

I have a simple FadeDown component that uses framer-motion for animation like:

import React from 'react'
import Tippy from '@tippyjs/react/headless'
import { useSpring, motion } from 'framer-motion'

interface IFadeDown {
	content: string
	children: React.ReactElement<any, string | React.JSXElementConstructor<any>>
}

export const FadeDown = ({ content, children }: IFadeDown) => {
	const springConfig = { damping: 15, stiffness: 120 }
	const initialTranslateY = -5
	const opacity = useSpring(0, springConfig)
	const translateY = useSpring(initialTranslateY, springConfig)

	function onMount() {
		translateY.set(5)
		opacity.set(1)
	}

	function onHide({ unmount }: { unmount: Function }) {
		const cleanup = translateY.onChange((value) => {
			if (value <= initialTranslateY) {
				cleanup()
				unmount()
			}
		})

		translateY.set(initialTranslateY)
		opacity.set(0)
	}

	return (
		<Tippy
			render={(attrs) => (
				<motion.div
					style={{ translateY, opacity }}
					{...attrs}
					className="px-2 py-1 font-sans text-sm font-bold text-gray-900 uppercase bg-gray-300 rounded-md"
				>
					{content}
				</motion.div>
			)}
			placement="bottom"
			animation={true}
			onMount={onMount}
			onHide={onHide}
		>
			{children}
		</Tippy>
	)
}

And I use it like:

<FadeDownTippy content="Copy URL to Clipboard">
  <motion.li
    whileHover={{
      translateY: -4,
    }}
  >
    <a className="cursor-pointer">
      <LinkIcon
        className="w-6 h-6"
        onClick={() => {
          navigator.clipboard.writeText(window.location.href)
        }}
      />
    </a>
  </motion.li>
</FadeDownTippy>

How can I make it so that the content changes when I click on it to Copied?

I tried something like:

const [copied, setCopied] = React.useState(false)

.
.
.

<FadeDownTippy content={copied ? 'Copied' : 'Copy URL to Clipboard'}>
  <motion.li
    whileHover={{
      translateY: -4,
    }}
  >
    <a className="cursor-pointer">
      <LinkIcon
        className="w-6 h-6"
        onClick={() => {
          navigator.clipboard.writeText(window.location.href)
          setCopied(true)
          setTimeout(() => {
            setCopied(false)
          }, 3000)
        }}
      />
    </a>
  </motion.li>
</FadeDownTippy>

But it doesn't work :(

How do I make it work?

What you've done should work. Have you tried replicating it on CodeSandbox?

@atomiks Yes, it works. Weirdly, Next.js HMR didn't update properly & I hadn't used hideOnClick={false} yet but when I tried replicating on Stackblitz, it worked → https://stackblitz.com/edit/tippy-js-react-tooltip?file=pages%2Findex.js

Turns out, I had to restart my Next.js app 😂

Thanks for this awesome library. Makes my site look 10x cool :)