The link() function is a higher-order function that generates animated SVG badges for social media links with rotating arrow indicators.
Function Signature
export const link = (
props: Props & { index: number }
) => (label: string) => string
This is a curried function that takes props first, then returns a function that accepts a label.
Type Definitions
Props
interface Props {
width?: number;
height: number;
theme: "light" | "dark";
}
Parameters
First Call (Configuration)
The height of the SVG in pixels (typically 18-20px)
The width of the SVG in pixels (typically 100px)
Color theme for the link badge
Numeric index used for staggered animation delays. Each link should have a unique index.
Second Call (Label)
The text to display (e.g., “LinkedIn”, “Twitter”, “Resume”)
What It Renders
The link() function renders a compact SVG badge with:
- Link label: Displays the social platform or link name
- Animated arrow: A rotating ”↗” arrow that spins periodically
- Shine effect: The label text has an animated gradient shine
- Staggered animations: Each link animates in with a delay based on its index
Real Usage Examples
From worker.ts:25-42:
// Resume link (index 0)
if (section === "link-resume") {
const index = Number(searchParams.get("i")) ?? 0;
content = link({ height: 18, width: 100, index, theme })("Resume");
}
// Website link (index 1)
else if (section === "link-website") {
const index = Number(searchParams.get("i")) ?? 0;
content = link({ height: 18, width: 100, index, theme })("Website");
}
// LinkedIn link (index 2)
else if (section === "link-linkedin") {
const index = Number(searchParams.get("i")) ?? 0;
content = link({ height: 18, width: 100, index, theme })("LinkedIn");
}
// Instagram link (slightly taller)
else if (section === "link-instagram") {
const index = Number(searchParams.get("i")) ?? 0;
content = link({ height: 20, width: 100, index, theme })("Instagram");
}
Usage in GitHub README
<a href="https://linkedin.com/in/username">
<picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://readme.aidre.com/?section=link-linkedin&i=0&theme=dark">
<source media="(prefers-color-scheme: light)"
srcset="https://readme.aidre.com/?section=link-linkedin&i=0&theme=light">
<img alt="LinkedIn" src="https://readme.aidre.com/?section=link-linkedin&i=0">
</picture>
</a>
Animation Details
Staggered Fade-In
Each link fades in with a delay based on its index:
.wrapper {
--delay: calc(var(--animate-in-links-delay) + var(--i) * 1.2s);
}
With an index of 0, 1, 2, etc., links appear sequentially with 1.2s between each.
Rotating Arrow
The arrow rotates 360° periodically with randomized timing:
.link__arrow {
animation-name: rotate;
animation-duration: 5s;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-delay: ${Math.random() * 5}s; /* Random 0-5s delay */
}
@keyframes rotate {
0% {
transform: rotate(0deg);
}
10%, 100% {
transform: rotate(360deg);
}
}
The rotation happens in the first 10% of the animation cycle (0.5s), then stays rotated.
Shine Effect on Label
The label text uses the shared .shine class:
.link__label {
animation-delay: ${Math.random() * 10}s; /* Random 0-10s delay */
}
Each link’s shine animation starts at a random time, creating visual variety.
Firefox Compatibility
Unlike other render functions, link badges are explicitly enabled in Firefox:
@-moz-document url-prefix() {
/* Override default, allow this to show in FF */
.wrapper {
display: block;
}
}
This ensures social media links remain visible even if the main contribution graph is hidden in Firefox.
Returns
Type: string (returned from inner function)
Returns a complete SVG string with:
- Fixed width and height
- Animated arrow indicator
- Shine effect on text
- Theme-aware colors
- Staggered entrance animation
Design Considerations
- Consistent sizing: Most links use 18px height and 100px width
- Index management: Ensure each link has a unique index for proper animation timing
- Label length: Keep labels short (6-10 characters) to fit within the 100px width
- Theme support: Links automatically adapt to light/dark themes