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