Skip to content

Commit

Permalink
Properly set copy button everywhere
Browse files Browse the repository at this point in the history
Also fix issue with copy button not preventing default behavior (which
was causing links to be followed when the copy was on a link).
  • Loading branch information
elboletaire committed Jul 2, 2024
1 parent 380981a commit 6c9f95e
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 25 deletions.
52 changes: 31 additions & 21 deletions src/components/CopyButton.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ButtonProps, IconButton, Tooltip, useClipboard } from '@chakra-ui/react'
import { Button, ButtonProps, IconButton, Tooltip, useClipboard } from '@chakra-ui/react'
import { useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { IoCheckmark, IoCopy } from 'react-icons/io5'
Expand All @@ -8,30 +8,40 @@ type ICopyButton = ButtonProps & {
toCopy: string
}

export const CopyButton = ({ toCopy, ...rest }: ICopyButton) => {
const { t } = useTranslation()
const { onCopy, setValue, hasCopied } = useClipboard(toCopy, { timeout: 1000 })
const label = hasCopied
? t('copy.copied_to_clipboard', { defaultValue: 'Copied!' })
: t('copy.copy_to_clipboard', { defaultValue: 'Copy to clipboard' })
const withCopyLogic = (Component: typeof IconButton | typeof Button) => {
return ({ toCopy, ...rest }: ICopyButton) => {
const { t } = useTranslation()
const { onCopy, setValue, hasCopied } = useClipboard(toCopy, { timeout: 1000 })
const label = hasCopied
? t('copy.copied_to_clipboard', { defaultValue: 'Copied!' })
: t('copy.copy_to_clipboard', { defaultValue: 'Copy to clipboard' })

useEffect(() => {
setValue(toCopy)
}, [toCopy])
useEffect(() => {
setValue(toCopy)
}, [toCopy, setValue])

return (
<Tooltip label={label} aria-label={label} isOpen={hasCopied ? hasCopied : undefined} placement='top'>
<IconButton
variant={'text'}
aria-label={label}
onClick={() => onCopy()}
icon={hasCopied ? <IoCheckmark /> : <IoCopy />}
{...rest}
/>
</Tooltip>
)
const icon = hasCopied ? <IoCheckmark /> : <IoCopy />

return (
<Tooltip label={label} aria-label={label} isOpen={hasCopied ? hasCopied : undefined} placement='top'>
<Component
variant={'text'}
aria-label={label}
onClick={(e) => {
e.preventDefault()
onCopy()
}}
{...(Component === Button ? { rightIcon: icon } : { icon })}
{...rest}
/>
</Tooltip>
)
}
}

export const CopyButton = withCopyLogic(Button)
export const CopyButtonIcon = withCopyLogic(IconButton)

export const ReducedTextAndCopy = ({ children, ...rest }: ICopyButton) => {
let text = children
if (typeof children === 'string' && children.length > 13) {
Expand Down
8 changes: 4 additions & 4 deletions src/layout/ShowRawButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Box, BoxProps, Button, ButtonProps, useDisclosure } from '@chakra-ui/react'
import { Trans } from 'react-i18next'
import { CopyButton } from '~components/CopyButton'
import { CopyButtonIcon } from '~components/CopyButton'
import { JsonViewer } from './JsonViewer'

const ShowRawButton = ({ obj, ...props }: { obj: object } & Omit<ButtonProps, 'onClick'>) => {
Expand All @@ -13,16 +13,16 @@ const ShowRawButton = ({ obj, ...props }: { obj: object } & Omit<ButtonProps, 'o
<Button {...buttonProps} {...props}>
<Trans i18nKey={'raw_content'}>Raw content</Trans>
</Button>
<Box {...disclosureProps} position='relative'>
<CopyButton toCopy={JSON.stringify(obj, null, 2)} pos='absolute' top={2} right={2} variant='solid' />
<Box {...disclosureProps}>
<RawContentBox obj={obj} />
</Box>
</>
)
}

export const RawContentBox = ({ obj, ...rest }: { obj: object } & BoxProps) => (
<Box borderRadius='md' backgroundColor='gray.50' {...rest}>
<Box borderRadius='md' backgroundColor='gray.50' position='relative' {...rest}>
<CopyButtonIcon toCopy={JSON.stringify(obj, null, 2)} pos='absolute' top={2} right={2} variant='solid' />
<JsonViewer json={obj} />
</Box>
)
Expand Down

2 comments on commit 6c9f95e

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.