-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #49 from getcronit/rework-landing-page
docs: rework landing page
- Loading branch information
Showing
10 changed files
with
767 additions
and
45 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
'use client' | ||
|
||
import React, {useEffect, useRef, useState} from 'react' | ||
import {AnimatePresence, motion} from 'framer-motion' | ||
import {cn} from '@/lib/utils' | ||
import {useTheme} from 'nextra-theme-docs' | ||
|
||
export const GlowingStarsCard = ({ | ||
className, | ||
children, | ||
hoverEfect = true | ||
}: { | ||
className?: string | ||
children?: React.ReactNode | ||
hoverEfect?: boolean | ||
}) => { | ||
const [mouseEnter, setMouseEnter] = useState(false) | ||
|
||
return ( | ||
<div | ||
onMouseEnter={() => { | ||
if (!hoverEfect) return | ||
setMouseEnter(true) | ||
}} | ||
onMouseLeave={() => { | ||
if (!hoverEfect) return | ||
setMouseEnter(false) | ||
}} | ||
className={cn( | ||
'p-6 max-w-md h-full w-full rounded-xl border border-[#eaeaea] dark:border-gray-800', | ||
className | ||
)}> | ||
<div className="flex justify-center items-center"> | ||
<Illustration mouseEnter={mouseEnter} /> | ||
</div> | ||
<div className="px-2 pb-6">{children}</div> | ||
</div> | ||
) | ||
} | ||
|
||
export const GlowingStarsDescription = ({ | ||
className, | ||
children | ||
}: { | ||
className?: string | ||
children?: React.ReactNode | ||
}) => { | ||
return ( | ||
<p className={cn('text-base text-white max-w-[16rem]', className)}> | ||
{children} | ||
</p> | ||
) | ||
} | ||
|
||
export const GlowingStarsTitle = ({ | ||
className, | ||
children | ||
}: { | ||
className?: string | ||
children?: React.ReactNode | ||
}) => { | ||
return ( | ||
<h2 className={cn('font-bold text-2xl text-[#eaeaea]', className)}> | ||
{children} | ||
</h2> | ||
) | ||
} | ||
|
||
export const Illustration = ({mouseEnter}: {mouseEnter: boolean}) => { | ||
const stars = 108 | ||
const columns = 18 | ||
|
||
const [glowingStars, setGlowingStars] = useState<number[]>([]) | ||
|
||
const highlightedStars = useRef<number[]>([]) | ||
|
||
useEffect(() => { | ||
const interval = setInterval(() => { | ||
highlightedStars.current = Array.from({length: 5}, () => | ||
Math.floor(Math.random() * stars) | ||
) | ||
setGlowingStars([...highlightedStars.current]) | ||
}, 3000) | ||
|
||
return () => clearInterval(interval) | ||
}, []) | ||
|
||
return ( | ||
<div | ||
className="h-[180px] p-1 w-full" | ||
style={{ | ||
display: 'grid', | ||
gridTemplateColumns: `repeat(${columns}, 1fr)`, | ||
gap: `1px` | ||
}}> | ||
{[...Array(stars)].map((_, starIdx) => { | ||
const isGlowing = glowingStars.includes(starIdx) | ||
const delay = (starIdx % 10) * 0.1 | ||
const staticDelay = starIdx * 0.01 | ||
return ( | ||
<div | ||
key={`matrix-col-${starIdx}}`} | ||
className="relative flex items-center justify-center"> | ||
<Star | ||
isGlowing={mouseEnter ? true : isGlowing} | ||
delay={mouseEnter ? staticDelay : delay} | ||
/> | ||
{mouseEnter && <Glow delay={staticDelay} />} | ||
<AnimatePresence mode="wait"> | ||
{isGlowing && <Glow delay={delay} />} | ||
</AnimatePresence> | ||
</div> | ||
) | ||
})} | ||
</div> | ||
) | ||
} | ||
|
||
const Star = ({isGlowing, delay}: {isGlowing: boolean; delay: number}) => { | ||
const {resolvedTheme} = useTheme() | ||
const isDarkTheme = resolvedTheme === 'dark' | ||
return ( | ||
<motion.div | ||
key={delay} | ||
initial={{ | ||
scale: 1 | ||
}} | ||
animate={{ | ||
scale: isGlowing ? [1, 1.2, 2.5, 2.2, 1.5] : 1, | ||
background: isGlowing | ||
? isDarkTheme | ||
? '#fff' | ||
: '#f3f3f3' | ||
: isDarkTheme | ||
? '#666' | ||
: '#4f4f4f' | ||
}} | ||
transition={{ | ||
duration: 2, | ||
ease: 'easeInOut', | ||
delay: delay | ||
}} | ||
className={cn( | ||
'bg-[#4f4f4f] dark:bg-[#666] size-[2px] dark:size-[1px] rounded-full relative z-20' | ||
)}></motion.div> | ||
) | ||
} | ||
|
||
const Glow = ({delay}: {delay: number}) => { | ||
return ( | ||
<motion.div | ||
initial={{ | ||
opacity: 0 | ||
}} | ||
animate={{ | ||
opacity: 1 | ||
}} | ||
transition={{ | ||
duration: 2, | ||
ease: 'easeInOut', | ||
delay: delay | ||
}} | ||
exit={{ | ||
opacity: 0 | ||
}} | ||
className="absolute left-1/2 -translate-x-1/2 z-10 h-[4px] w-[4px] rounded-full bg-blue-500 blur-[1px] shadow-2xl shadow-blue-400" | ||
/> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
'use client' | ||
import React, {useState, useEffect} from 'react' | ||
import {motion} from 'framer-motion' | ||
import {useTheme} from 'nextra-theme-docs' | ||
|
||
import {cn} from '@/lib/utils' | ||
|
||
type Direction = 'TOP' | 'LEFT' | 'BOTTOM' | 'RIGHT' | ||
|
||
export function HoverBorderGradient({ | ||
children, | ||
containerClassName, | ||
className, | ||
as: Tag = 'button', | ||
duration = 1, | ||
clockwise = true, | ||
...props | ||
}: React.PropsWithChildren< | ||
{ | ||
as?: React.ElementType | ||
containerClassName?: string | ||
className?: string | ||
duration?: number | ||
clockwise?: boolean | ||
} & React.HTMLAttributes<HTMLElement> | ||
>) { | ||
const [hovered, setHovered] = useState<boolean>(false) | ||
const [direction, setDirection] = useState<Direction>('TOP') | ||
|
||
const {resolvedTheme} = useTheme() | ||
|
||
// Usually, we wouldnt need this, but the useTheme hook from nextra-theme-docs seem to have (a) bug(s) | ||
const theme = | ||
resolvedTheme && resolvedTheme === 'system' | ||
? 'dark' | ||
: resolvedTheme ?? 'dark' | ||
|
||
const rotateDirection = (currentDirection: Direction): Direction => { | ||
const directions: Direction[] = ['TOP', 'LEFT', 'BOTTOM', 'RIGHT'] | ||
const currentIndex = directions.indexOf(currentDirection) | ||
const nextIndex = clockwise | ||
? (currentIndex - 1 + directions.length) % directions.length | ||
: (currentIndex + 1) % directions.length | ||
return directions[nextIndex] | ||
} | ||
|
||
const movingMap: Record<'dark' | 'light', Record<Direction, string>> = { | ||
dark: { | ||
TOP: 'radial-gradient(20.7% 50% at 50% 0%, #3275F8 0%, rgba(255, 255, 255, 0) 100%)', | ||
LEFT: 'radial-gradient(16.6% 43.1% at 0% 50%, #3275F8 0%, rgba(255, 255, 255, 0) 100%)', | ||
BOTTOM: | ||
'radial-gradient(20.7% 50% at 50% 100%, #3275F8 0%, rgba(255, 255, 255, 0) 100%)', | ||
RIGHT: | ||
'radial-gradient(16.2% 41.199999999999996% at 100% 50%, #3275F8 0%, rgba(255, 255, 255, 0) 100%)' | ||
}, | ||
light: { | ||
TOP: 'radial-gradient(20.7% 50% at 50% 0%, #3275F8 0%, rgba(255, 255, 255, 1) 100%)', | ||
LEFT: 'radial-gradient(16.6% 43.1% at 0% 50%, #3275F8 0%, rgba(255, 255, 255, 1) 100%)', | ||
BOTTOM: | ||
'radial-gradient(20.7% 50% at 50% 100%, #3275F8 0%, rgba(255, 255, 255, 1) 100%)', | ||
RIGHT: | ||
'radial-gradient(16.2% 41.199999999999996% at 100% 50%, #3275F8 0%, rgba(255, 255, 255, 1) 100%)' | ||
} | ||
} | ||
|
||
const highlight = | ||
theme === 'dark' | ||
? 'radial-gradient(75% 181.15942028985506% at 50% 50%, #3275F8 0%, rgba(255, 255, 255, 0) 100%)' | ||
: 'radial-gradient(75% 181.15942028985506% at 50% 50%, #3275F8 0%, rgba(255, 255, 255, 1) 100%)' | ||
|
||
useEffect(() => { | ||
if (!hovered) { | ||
const interval = setInterval(() => { | ||
setDirection(prevState => rotateDirection(prevState)) | ||
}, duration * 1000) | ||
return () => clearInterval(interval) | ||
} | ||
}, [hovered]) | ||
return ( | ||
<Tag | ||
onMouseEnter={(event: React.MouseEvent<HTMLDivElement>) => { | ||
setHovered(true) | ||
}} | ||
onMouseLeave={() => setHovered(false)} | ||
className={cn( | ||
'relative flex rounded-full border content-center bg-border dark:hover:bg-white/10 transition duration-500 dark:bg-white/20 items-center flex-col flex-nowrap gap-10 h-min justify-center overflow-visible p-px decoration-clone w-fit', | ||
containerClassName | ||
)} | ||
{...props}> | ||
<div | ||
className={cn( | ||
'w-auto text-primary z-10 bg-white dark:bg-[#0a0a0a] px-4 py-2 rounded-[inherit]', | ||
className | ||
)}> | ||
{children} | ||
</div> | ||
<motion.div | ||
className={cn( | ||
'flex-none inset-0 overflow-hidden absolute z-0 rounded-[inherit]' | ||
)} | ||
style={{ | ||
filter: 'blur(2px)', | ||
position: 'absolute', | ||
width: '100%', | ||
height: '100%' | ||
}} | ||
initial={{background: movingMap[direction]}} | ||
animate={{ | ||
background: hovered | ||
? [movingMap[theme][direction], highlight] | ||
: movingMap[theme][direction] | ||
}} | ||
transition={{ease: 'linear', duration: duration ?? 1}} | ||
/> | ||
<div className="bg-black absolute z-1 flex-none inset-[2px] rounded-[100px]" /> | ||
</Tag> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ | |
"display": "hidden", | ||
"theme": { | ||
"timestamp": false, | ||
"layout": "full" | ||
"layout": "raw" | ||
} | ||
}, | ||
"docs": { | ||
|
Oops, something went wrong.
3cc9d5c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deploy preview for pylon-docs ready!
✅ Preview
https://pylon-docs-gi3h6qtt6-schettns-projects.vercel.app
Built with commit 3cc9d5c.
This pull request is being automatically deployed with vercel-action