feat: implement share button
This commit is contained in:
parent
e0e961e886
commit
e4869d1c8e
|
@ -9,6 +9,7 @@ import { LPE } from '../../../types/lpe.types'
|
|||
import { ArticleImageBlockWrapper } from '../Article.ImageBlockWrapper'
|
||||
import ArticleStats from '../Article.Stats'
|
||||
import ArticleSummary from './Article.Summary'
|
||||
import { TagsAndSocial } from '@/components/TagsAndSocial'
|
||||
|
||||
export type ArticleHeaderProps = LPE.Article.Data
|
||||
|
||||
|
@ -53,7 +54,7 @@ const ArticleHeader = ({
|
|||
{subtitle}
|
||||
</ArticleSubtitle>
|
||||
)}
|
||||
<Tags tags={tags} className={'articleTags'} />
|
||||
<TagsAndSocial tags={tags} className={'articleTags'} />
|
||||
<AuthorsContainer>
|
||||
<Authors authors={authors} email={true} gap={12} />
|
||||
</AuthorsContainer>
|
||||
|
|
|
@ -7,6 +7,8 @@ import EpisodeStats from '../Episode.Stats'
|
|||
import EpisodePlayer from './Episode.Player'
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
import { ShareButton } from '@/components/ShareButton'
|
||||
import { TagsAndSocial } from '@/components/TagsAndSocial'
|
||||
|
||||
export type EpisodeHeaderProps = LPE.Podcast.Document & {
|
||||
channel: LPE.Podcast.Channel
|
||||
|
@ -51,7 +53,7 @@ const EpisodeHeader = ({
|
|||
</Show>
|
||||
</CustomLink>
|
||||
)}
|
||||
{tags && <Tags tags={tags} />}
|
||||
<TagsAndSocial tags={tags} />
|
||||
{channels && <EpisodeChannels channels={channels} />}
|
||||
{description && (
|
||||
<EpisodeSubtitle
|
||||
|
@ -106,6 +108,7 @@ const Show = styled.div`
|
|||
|
||||
const CustomLink = styled(Link)`
|
||||
text-decoration: none;
|
||||
width: fit-content;
|
||||
`
|
||||
|
||||
export default EpisodeHeader
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import { LsdIcon } from '@acid-info/lsd-react'
|
||||
|
||||
export const CopyIcon = LsdIcon(
|
||||
(props) => (
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 14 14"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M9.33268 0.583313H2.33268C1.69102 0.583313 1.16602 1.10831 1.16602 1.74998V9.91665H2.33268V1.74998H9.33268V0.583313ZM8.74935 2.91665H4.66602C4.02435 2.91665 3.50518 3.44165 3.50518 4.08331L3.49935 12.25C3.49935 12.8916 4.01852 13.4166 4.66018 13.4166H11.0827C11.7243 13.4166 12.2493 12.8916 12.2493 12.25V6.41665L8.74935 2.91665ZM4.66602 12.25V4.08331H8.16602V6.99998H11.0827V12.25H4.66602Z"
|
||||
fill="black"
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
{ filled: true },
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
export * from './CopyIcon'
|
|
@ -0,0 +1,20 @@
|
|||
import { LsdIcon } from '@acid-info/lsd-react'
|
||||
|
||||
export const ShareIcon = LsdIcon(
|
||||
(props) => (
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 14 14"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M10.5 9.37999C10.0567 9.37999 9.66 9.55499 9.35667 9.82916L5.1975 7.40832C5.22667 7.27416 5.25 7.13999 5.25 6.99999C5.25 6.85999 5.22667 6.72582 5.1975 6.59166L9.31 4.19416C9.625 4.48582 10.0392 4.66666 10.5 4.66666C11.4683 4.66666 12.25 3.88499 12.25 2.91666C12.25 1.94832 11.4683 1.16666 10.5 1.16666C9.53167 1.16666 8.75 1.94832 8.75 2.91666C8.75 3.05666 8.77333 3.19082 8.8025 3.32499L4.69 5.72249C4.375 5.43082 3.96083 5.24999 3.5 5.24999C2.53167 5.24999 1.75 6.03166 1.75 6.99999C1.75 7.96832 2.53167 8.74999 3.5 8.74999C3.96083 8.74999 4.375 8.56916 4.69 8.27749L8.84333 10.7042C8.81417 10.8267 8.79667 10.955 8.79667 11.0833C8.79667 12.0225 9.56083 12.7867 10.5 12.7867C11.4392 12.7867 12.2033 12.0225 12.2033 11.0833C12.2033 10.1442 11.4392 9.37999 10.5 9.37999ZM10.5 2.33332C10.8208 2.33332 11.0833 2.59582 11.0833 2.91666C11.0833 3.23749 10.8208 3.49999 10.5 3.49999C10.1792 3.49999 9.91667 3.23749 9.91667 2.91666C9.91667 2.59582 10.1792 2.33332 10.5 2.33332ZM3.5 7.58332C3.17917 7.58332 2.91667 7.32082 2.91667 6.99999C2.91667 6.67916 3.17917 6.41666 3.5 6.41666C3.82083 6.41666 4.08333 6.67916 4.08333 6.99999C4.08333 7.32082 3.82083 7.58332 3.5 7.58332ZM10.5 11.6783C10.1792 11.6783 9.91667 11.4158 9.91667 11.095C9.91667 10.7742 10.1792 10.5117 10.5 10.5117C10.8208 10.5117 11.0833 10.7742 11.0833 11.095C11.0833 11.4158 10.8208 11.6783 10.5 11.6783Z"
|
||||
fill="black"
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
{ filled: true },
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
export * from './ShareIcon'
|
|
@ -0,0 +1,118 @@
|
|||
import { Tag, Typography } from '@acid-info/lsd-react'
|
||||
import styled from '@emotion/styled'
|
||||
import { ShareIcon } from '../Icons/ShareIcon'
|
||||
import { useRef, useState } from 'react'
|
||||
import { CopyIcon } from '../Icons/CopyIcon'
|
||||
import { XIcon } from '../Icons/XIcon'
|
||||
import Link from 'next/link'
|
||||
import { useClickAway } from 'react-use'
|
||||
|
||||
type Props = {
|
||||
url: string
|
||||
}
|
||||
|
||||
export default function ShareButton({ url }: Props) {
|
||||
const [showOptions, setShowOptions] = useState(false)
|
||||
const [copied, setCopied] = useState(false)
|
||||
const ref = useRef(null)
|
||||
|
||||
useClickAway(ref, () => {
|
||||
setShowOptions(false)
|
||||
})
|
||||
|
||||
const handleCopyClipBoard = async (text: string) => {
|
||||
await navigator.clipboard.writeText(text)
|
||||
setCopied(true)
|
||||
|
||||
// TODO : Temporary solution
|
||||
setTimeout(() => {
|
||||
setCopied(false)
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
return (
|
||||
<Container ref={ref}>
|
||||
<CustomTag
|
||||
onClick={() => setShowOptions(!showOptions)}
|
||||
icon={<ShareIcon width={14} height={14} />}
|
||||
iconDirection="left"
|
||||
showOptions={showOptions}
|
||||
>
|
||||
<Typography variant="body3">Share</Typography>
|
||||
</CustomTag>
|
||||
{showOptions && (
|
||||
<Options>
|
||||
<Label>
|
||||
<Typography variant="body3">Share Options</Typography>
|
||||
</Label>
|
||||
<ShareOption onClick={() => handleCopyClipBoard(url)}>
|
||||
<CopyIcon width={14} height={14} />
|
||||
<Typography variant="body2">
|
||||
{copied ? 'Copied' : 'Copy link'}
|
||||
</Typography>
|
||||
</ShareOption>
|
||||
<CustomLink href={`http://www.twitter.com/share?url=${url}`}>
|
||||
<ShareOption>
|
||||
<XIcon />
|
||||
<Typography variant="body2">X</Typography>
|
||||
</ShareOption>
|
||||
</CustomLink>
|
||||
</Options>
|
||||
)}
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
const HEIGHT = 24
|
||||
|
||||
const Container = styled.div`
|
||||
position: relative;
|
||||
`
|
||||
|
||||
const CustomTag = styled(Tag)<{ showOptions: boolean }>`
|
||||
width: 69px;
|
||||
height: ${HEIGHT}px;
|
||||
padding: 0 8px;
|
||||
border-bottom: ${(props) =>
|
||||
props.showOptions
|
||||
? '1px solid transparent'
|
||||
: '1px solid rgb(var(--lsd-border-primary))'};
|
||||
`
|
||||
|
||||
const Options = styled.div`
|
||||
top: ${HEIGHT - 1}px;
|
||||
left: 0;
|
||||
width: 169px;
|
||||
border: 1px solid rgb(var(--lsd-border-primary));
|
||||
position: absolute;
|
||||
background-color: rgb(var(--lsd-surface-primary));
|
||||
padding-bottom: 8px;
|
||||
z-index: 1;
|
||||
`
|
||||
|
||||
const Label = styled.div`
|
||||
padding: 12px;
|
||||
`
|
||||
|
||||
const ShareOption = styled.div`
|
||||
cursor: pointer;
|
||||
padding: 6px 12px 6px 14px;
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
`
|
||||
|
||||
const CustomLink = styled(Link)`
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
`
|
|
@ -0,0 +1 @@
|
|||
export { default as ShareButton } from './ShareButton'
|
|
@ -0,0 +1,34 @@
|
|||
import styled from '@emotion/styled'
|
||||
import { ShareButton } from '../ShareButton'
|
||||
import { Tags } from '../Tags'
|
||||
|
||||
export type TagsProps = {
|
||||
tags: string[]
|
||||
className?: string
|
||||
}
|
||||
|
||||
const TagsAndSocial: React.FC<TagsProps> = ({ tags, className }) => {
|
||||
const currentUrl = typeof window !== 'undefined' ? window.location.href : ''
|
||||
|
||||
return (
|
||||
<Container>
|
||||
{tags && <Tags tags={tags} className={className} />}
|
||||
<VerticalLine />
|
||||
<ShareButton url={currentUrl} />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
const Container = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
width: fit-content;
|
||||
`
|
||||
|
||||
const VerticalLine = styled.div`
|
||||
height: 12px;
|
||||
border-left: 1px solid rgb(var(--lsd-border-primary));
|
||||
`
|
||||
|
||||
export default TagsAndSocial
|
|
@ -0,0 +1 @@
|
|||
export { default as TagsAndSocial } from './TagsAndSocial'
|
Loading…
Reference in New Issue