parent
68597d58d2
commit
6decf1eb70
9 changed files with 170 additions and 94 deletions
@ -0,0 +1,20 @@ |
||||
import { cn } from '../../lib/classname'; |
||||
|
||||
interface HackerNewsIconProps { |
||||
className?: string; |
||||
} |
||||
|
||||
export function HackerNewsIcon(props: HackerNewsIconProps) { |
||||
const { className } = props; |
||||
|
||||
return ( |
||||
<svg |
||||
xmlns="http://www.w3.org/2000/svg" |
||||
viewBox="0 0 448 512" |
||||
fill="currentColor" |
||||
className={cn('h-[26px] w-[26px]', className)} |
||||
> |
||||
<path d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM21.2 229.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z" /> |
||||
</svg> |
||||
); |
||||
} |
@ -0,0 +1,20 @@ |
||||
import { cn } from '../../lib/classname'; |
||||
|
||||
interface RedditIconProps { |
||||
className?: string; |
||||
} |
||||
|
||||
export function RedditIcon(props: RedditIconProps) { |
||||
const { className } = props; |
||||
|
||||
return ( |
||||
<svg |
||||
xmlns="http://www.w3.org/2000/svg" |
||||
viewBox="0 0 448 512" |
||||
fill="currentColor" |
||||
className={cn('h-[26px] w-[26px]', className)} |
||||
> |
||||
<path d="M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8a26.67 26.67 0 0 0-26.8 26.8c0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5a26.67 26.67 0 0 0-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8s-11.9-26.8-26.8-26.8c-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z" /> |
||||
</svg> |
||||
); |
||||
} |
@ -1,34 +0,0 @@ |
||||
--- |
||||
import Icon from '../AstroIcon.astro'; |
||||
|
||||
export interface Props { |
||||
pageUrl: string; |
||||
description: string; |
||||
} |
||||
|
||||
const { pageUrl, description } = Astro.props; |
||||
|
||||
const twitterUrl = `https://twitter.com/intent/tweet?text=${description}&url=${pageUrl}`; |
||||
const fbUrl = `https://www.facebook.com/sharer/sharer.php?quote=${description}&u=${pageUrl}`; |
||||
const hnUrl = `https://news.ycombinator.com/submitlink?t=${description}&u=${pageUrl}`; |
||||
const redditUrl = `https://www.reddit.com/submit?title=${description}&url=${pageUrl}`; |
||||
--- |
||||
|
||||
<div class='absolute left-[-18px] top-[110px] h-full hidden' id='page-share-icons'> |
||||
<div class='flex sticky top-[100px] flex-col gap-1.5 items-center'> |
||||
<a href={twitterUrl} target='_blank' class='text-gray-500 hover:text-gray-700 mb-0.5'> |
||||
<Icon icon='twitter' /> |
||||
</a> |
||||
<a href={fbUrl} target='_blank' class='text-gray-500 hover:text-gray-700'> |
||||
<Icon icon='facebook' /> |
||||
</a> |
||||
<a href={hnUrl} target='_blank' class='text-gray-500 hover:text-gray-700'> |
||||
<Icon icon='hackernews' /> |
||||
</a> |
||||
<a href={redditUrl} target='_blank' class='text-gray-500 hover:text-gray-700'> |
||||
<Icon icon='reddit' /> |
||||
</a> |
||||
</div> |
||||
</div> |
||||
|
||||
<script src='./sharer.js'></script> |
@ -0,0 +1,99 @@ |
||||
import { useEffect, useRef } from 'react'; |
||||
import { cn } from '../../lib/classname'; |
||||
import { FacebookIcon } from '../ReactIcons/FacebookIcon'; |
||||
import { HackerNewsIcon } from '../ReactIcons/HackerNewsIcon'; |
||||
import { RedditIcon } from '../ReactIcons/RedditIcon'; |
||||
import { TwitterIcon } from '../ReactIcons/TwitterIcon'; |
||||
|
||||
type ShareIconsProps = { |
||||
pageUrl: string; |
||||
description: string; |
||||
}; |
||||
|
||||
export function ShareIcons(props: ShareIconsProps) { |
||||
const { pageUrl, description } = props; |
||||
|
||||
const shareIconsRef = useRef<HTMLDivElement>(null); |
||||
|
||||
const twitterUrl = `https://twitter.com/intent/tweet?text=${description}&url=${pageUrl}`; |
||||
const fbUrl = `https://www.facebook.com/sharer/sharer.php?quote=${description}&u=${pageUrl}`; |
||||
const hnUrl = `https://news.ycombinator.com/submitlink?t=${description}&u=${pageUrl}`; |
||||
const redditUrl = `https://www.reddit.com/submit?title=${description}&url=${pageUrl}`; |
||||
|
||||
const icons = [ |
||||
{ |
||||
url: twitterUrl, |
||||
icon: ( |
||||
<TwitterIcon |
||||
className="size-[24px] [&>path]:fill-[#E5E5E5]" |
||||
boxColor="currentColor" |
||||
/> |
||||
), |
||||
}, |
||||
{ |
||||
url: fbUrl, |
||||
icon: <FacebookIcon className="size-[26px]" />, |
||||
}, |
||||
{ |
||||
url: hnUrl, |
||||
icon: <HackerNewsIcon className="size-[26px]" />, |
||||
}, |
||||
{ |
||||
url: redditUrl, |
||||
icon: <RedditIcon className="size-[26px]" />, |
||||
}, |
||||
]; |
||||
|
||||
useEffect(() => { |
||||
const shareIcons = shareIconsRef.current; |
||||
if (!shareIcons) { |
||||
return; |
||||
} |
||||
|
||||
const onScroll = () => { |
||||
if (window.scrollY < 100 || window.innerWidth < 1050) { |
||||
shareIcons.classList.add('hidden'); |
||||
return null; |
||||
} |
||||
|
||||
shareIcons.classList.remove('hidden'); |
||||
}; |
||||
|
||||
onScroll(); |
||||
|
||||
window.addEventListener('scroll', onScroll); |
||||
return () => { |
||||
window.removeEventListener('scroll', onScroll); |
||||
}; |
||||
}, []); |
||||
|
||||
return ( |
||||
<div |
||||
className="absolute left-[-18px] top-[110px] hidden h-full" |
||||
ref={shareIconsRef} |
||||
> |
||||
<div className="sticky top-[100px] flex flex-col items-center gap-1.5"> |
||||
{icons.map((icon, index) => ( |
||||
<a |
||||
key={index} |
||||
href={icon.url} |
||||
target="_blank" |
||||
className={cn( |
||||
'text-gray-500 hover:text-gray-700', |
||||
index === 0 && 'mt-0.5', |
||||
)} |
||||
onClick={() => { |
||||
window.fireEvent({ |
||||
category: 'RoadmapShareLink', |
||||
action: 'Roadmap Share Link Clicked', |
||||
label: icon.url, |
||||
}); |
||||
}} |
||||
> |
||||
{icon.icon} |
||||
</a> |
||||
))} |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
@ -1,32 +0,0 @@ |
||||
export class Sharer { |
||||
constructor() { |
||||
this.init = this.init.bind(this); |
||||
this.onScroll = this.onScroll.bind(this); |
||||
|
||||
this.shareIconsId = 'page-share-icons'; |
||||
} |
||||
|
||||
get shareIconsEl() { |
||||
return document.getElementById(this.shareIconsId); |
||||
} |
||||
|
||||
onScroll() { |
||||
if (window.scrollY < 100 || window.innerWidth < 1050) { |
||||
this.shareIconsEl.classList.add('hidden'); |
||||
return null; |
||||
} |
||||
|
||||
this.shareIconsEl.classList.remove('hidden'); |
||||
} |
||||
|
||||
init() { |
||||
if (!this.shareIconsEl) { |
||||
return; |
||||
} |
||||
|
||||
window.addEventListener('scroll', this.onScroll, { passive: true }); |
||||
} |
||||
} |
||||
|
||||
const sharer = new Sharer(); |
||||
sharer.init(); |
Loading…
Reference in new issue