Skip to content

Commit

Permalink
feat: implement copy to clipboard button
Browse files Browse the repository at this point in the history
  • Loading branch information
MH4GF committed Oct 22, 2023
1 parent b374f36 commit 0087c47
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { FC } from 'react'
import { useCallback, useState } from 'react'

import { Tooltip } from './Tooltip'
import { useSuccessTooltip } from './useSuccessTooltip'

import { Button } from '@/app/_components'

interface Props {
text: string
}

export const CopyToClipboardButton: FC<Props> = ({ text }) => {
const [isLoading, setIsLoading] = useState(false)
const [showTooltip, setShowTooltip] = useSuccessTooltip()

const handleClick = useCallback(() => {
setIsLoading(true)
navigator.clipboard
.writeText(text)
.then(() => setShowTooltip(true))
.catch((e) => console.error(e))
setIsLoading(false)
}, [text, setShowTooltip])

return (
<span className="relative">
<Tooltip show={showTooltip} />
<Button isLoading={isLoading} onClick={handleClick} variant="secondary">
Copy to Clipboard
</Button>
</span>
)
}
25 changes: 25 additions & 0 deletions web/src/app/_features/CopyToClipboardButton/Tooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import clsx from 'clsx'
import type { FC } from 'react'

interface Props {
show: boolean
}

export const Tooltip: FC<Props> = ({ show: show }) => {
return (
<span
className={clsx(
show ? 'opacity-100' : 'opacity-0',
`absolute -top-12 left-1/2 -translate-x-1/2
whitespace-nowrap rounded bg-slate-800
px-2 py-1 text-white
transition before:absolute before:left-1/2
before:top-full before:-translate-x-1/2 before:border-4 before:border-transparent
before:border-t-slate-800 before:content-['']
`,
)}
>
Copied!!
</span>
)
}
1 change: 1 addition & 0 deletions web/src/app/_features/CopyToClipboardButton/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './CopyToClipboardButton'
16 changes: 16 additions & 0 deletions web/src/app/_features/CopyToClipboardButton/useSuccessTooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useEffect, useState } from 'react'

export const useSuccessTooltip = () => {
const [show, setShow] = useState(false)

useEffect(() => {
if (!show) return

const timer = setTimeout(() => {
setShow(false)
}, 2000)
return () => clearTimeout(timer)
}, [show])

return [show, setShow] as const
}
4 changes: 4 additions & 0 deletions web/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from 'react-dom'

import { Button, Header, GistIdInput } from './_components'
import { CopyToClipboardButton } from './_features/CopyToClipboardButton'
import { showList } from './showList'

interface SubmitButtonProps {
Expand Down Expand Up @@ -59,6 +60,9 @@ function Home() {
focus:ring-2 focus:ring-inset focus:ring-slate-600 sm:text-sm sm:leading-6"
defaultValue={state.result}
/>
<div className="mt-2">
<CopyToClipboardButton text={state.result} />
</div>
</div>
</main>
</div>
Expand Down

0 comments on commit 0087c47

Please sign in to comment.