Skip to content

Commit

Permalink
Merge pull request #39 from route06inc/implement-share-dropdown-menu
Browse files Browse the repository at this point in the history
feat: implement ShareDropdownMenu
  • Loading branch information
MH4GF authored Oct 15, 2024
2 parents 0f9d8a6 + 28aa0c0 commit ed86227
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { TranslationFn } from '@/features/i18n'
import {
DropdownMenuItem,
TooltipContent,
TooltipPortal,
TooltipProvider,
TooltipRoot,
TooltipTrigger,
} from '@packages/ui'
import { CopyIcon } from 'lucide-react'
import { type FC, useCallback, useEffect, useState } from 'react'
import styles from './ShareDropdownMenu.module.css'

type Props = {
t: TranslationFn
onOpenChange: (open: boolean) => void
}

export const CopyLinkItem: FC<Props> = ({ t, onOpenChange }) => {
const [show, setShow] = useState(false)

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

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

const handleCopyLink = useCallback(async (event: Event) => {
event.preventDefault()
navigator.clipboard.writeText(window.location.href).then(() => {
setShow(true)
})
}, [])

return (
<TooltipProvider>
<TooltipRoot open={show}>
<TooltipTrigger asChild>
<DropdownMenuItem
leftIcon={<CopyIcon className={styles.icon} />}
onSelect={handleCopyLink}
>
<span>{t('posts.share.copyLink')}</span>
</DropdownMenuItem>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent sideOffset={5}>Link Copied</TooltipContent>
</TooltipPortal>
</TooltipRoot>
</TooltipProvider>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@
height: 10px;
color: var(--overlay-70);
}

.link {
width: 100%;
height: 100%;
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import type { Meta, StoryObj } from '@storybook/react'

import { getTranslation } from '@/features/i18n'
import { ShareDropdownMenu } from '.'

const { t } = getTranslation('en')

const meta = {
component: ShareDropdownMenu,
args: {
t,
lang: 'en',
children: <button type="button">Share</button>,
},
} satisfies Meta<typeof ShareDropdownMenu>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { TranslationFn } from '@/features/i18n'
import { type Lang, getTranslation } from '@/features/i18n'
import {
DropdownMenuContent,
DropdownMenuItem,
Expand All @@ -9,42 +9,52 @@ import {
LinkedInIcon,
XIcon,
} from '@packages/ui'
import { CopyIcon } from 'lucide-react'
import type { FC, PropsWithChildren } from 'react'
import { type FC, type PropsWithChildren, useState } from 'react'
import { CopyLinkItem } from './CopyLinkItem'
import styles from './ShareDropdownMenu.module.css'

type Props = PropsWithChildren<{
t: TranslationFn
lang: Lang
}>

export const ShareDropdownMenu: FC<Props> = ({ children, t }) => {
const handleSelect = (url: string) => () => {
window.open(url, '_blank', 'noreferrer')
}

export const ShareDropdownMenu: FC<Props> = ({ children, lang }) => {
const [open, setOpen] = useState(false)
const { t } = getTranslation(lang)
const url = encodeURIComponent(window.location.href)
const title = encodeURIComponent(document.title)

return (
<DropdownMenuRoot>
<DropdownMenuRoot open={open} onOpenChange={setOpen}>
<DropdownMenuTrigger asChild>{children}</DropdownMenuTrigger>

<DropdownMenuPortal>
<DropdownMenuContent sideOffset={5} align="start">
<DropdownMenuItem
leftIcon={<CopyIcon className={styles.icon} />}
onSelect={() => alert('Item 1 clicked')}
>
<span>{t('posts.share.copyLink')}</span>
</DropdownMenuItem>
<CopyLinkItem t={t} onOpenChange={setOpen} />
<DropdownMenuItem
leftIcon={<XIcon className={styles.icon} />}
onSelect={() => alert('Item 2 clicked')}
onSelect={handleSelect(
`http://twitter.com/share?url=${url}&text=${title}`,
)}
>
<span>{t('posts.share.x')}</span>
</DropdownMenuItem>
<DropdownMenuItem
leftIcon={<FacebookIcon className={styles.icon} />}
onSelect={() => alert('Item 3 clicked')}
onSelect={handleSelect(
`http://www.facebook.com/share.php?u=${url}`,
)}
>
<span>{t('posts.share.facebook')}</span>
</DropdownMenuItem>
<DropdownMenuItem
leftIcon={<LinkedInIcon className={styles.icon} />}
onSelect={() => alert('Item 3 clicked')}
onSelect={handleSelect(
`https://www.linkedin.com/sharing/share-offsite/?url=${url}`,
)}
>
<span>{t('posts.share.linkedin')}</span>
</DropdownMenuItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const DropdownMenuItem = forwardRef<
{leftIcon && (
<span className={clsx(styles.icon, styles.leftIcon)}>{leftIcon}</span>
)}
<div>{children}</div>
{children}
</Item>
)
},
Expand Down

0 comments on commit ed86227

Please sign in to comment.