Skip to main content
UI components are low-level building blocks including icons and other interface primitives used throughout the site.

Icon Components

All icon components share a consistent interface and styling approach.

Common Props

All icon components accept the following prop:
class
string
default:"varies by icon"
CSS classes to apply to the SVG element. Each icon has a sensible default size.

Common Features

  • SVG-based for sharp rendering at any size
  • Responsive to text color via currentColor
  • Optimized paths from standard icon libraries
  • Consistent sizing defaults
  • Accessible when used with proper ARIA labels

A diagonal arrow icon commonly used for links and CTAs indicating external navigation or forward movement.Default size: w-4 h-4Usage:
---
import { ArrowIcon } from '@/components/ui/icons';
---

<a href="/projects">
  View Projects
  <ArrowIcon class="w-4 h-4" />
</a>
Features:
  • Stroke-based rendering
  • 2px stroke width
  • Round line caps and joins
  • Points diagonally up-right
A checkmark icon for success states and confirmations.Default size: w-5 h-5Usage:
---
import { CheckIcon } from '@/components/ui/icons';
---

<div class="success-message">
  <CheckIcon class="w-5 h-5 text-green-600" />
  <span>Saved successfully!</span>
</div>
A duplicate/copy icon for clipboard operations.Default size: w-5 h-5Usage:
---
import { CopyIcon } from '@/components/ui/icons';
---

<button onclick="copyToClipboard()">
  <CopyIcon class="w-4 h-4" />
  Copy
</button>

Social Media Icons

All social icons default to w-6 h-6 and use filled rendering for bold, recognizable branding.
GitHub logo icon.Usage:
---
import { GitHubIcon } from '@/components/ui/icons';
---

<a href="https://github.com/username">
  <GitHubIcon class="w-6 h-6" />
</a>
Path data: Complete GitHub Octocat logo path
X (formerly Twitter) logo icon.Usage:
---
import { XIcon } from '@/components/ui/icons';
---

<a href="https://twitter.com/username">
  <XIcon class="w-6 h-6" />
</a>
Path data: Modern X logo design
LinkedIn logo icon.Usage:
---
import { LinkedInIcon } from '@/components/ui/icons';
---

<a href="https://linkedin.com/in/username">
  <LinkedInIcon class="w-6 h-6" />
</a>
Path data: Official LinkedIn logo
Dev.to logo icon for developer community.Usage:
---
import { DevToIcon } from '@/components/ui/icons';
---

<a href="https://dev.to/username">
  <DevToIcon class="w-6 h-6" />
</a>
Email envelope icon. Uses stroke rendering unlike other social icons.Default size: w-6 h-6Usage:
---
import { EmailIcon } from '@/components/ui/icons';
---

<a href="mailto:[email protected]">
  <EmailIcon class="w-6 h-6" />
</a>
Rendering: Stroke-based with 2px width, round caps
Facebook logo icon.Usage:
---
import { FacebookIcon } from '@/components/ui/icons';
---

<a href="https://facebook.com/username">
  <FacebookIcon class="w-6 h-6" />
</a>
Hacker News logo icon.Usage:
---
import { HackerNewsIcon } from '@/components/ui/icons';
---

<a href="https://news.ycombinator.com/user?id=username">
  <HackerNewsIcon class="w-6 h-6" />
</a>
Pinterest logo icon.Usage:
---
import { PinterestIcon } from '@/components/ui/icons';
---

<a href="https://pinterest.com/username">
  <PinterestIcon class="w-6 h-6" />
</a>
Reddit logo icon.Usage:
---
import { RedditIcon } from '@/components/ui/icons';
---

<a href="https://reddit.com/u/username">
  <RedditIcon class="w-6 h-6" />
</a>
Telegram logo icon.Usage:
---
import { TelegramIcon } from '@/components/ui/icons';
---

<a href="https://t.me/username">
  <TelegramIcon class="w-6 h-6" />
</a>
WhatsApp logo icon.Usage:
---
import { WhatsAppIcon } from '@/components/ui/icons';
---

<a href="https://wa.me/1234567890">
  <WhatsAppIcon class="w-6 h-6" />
</a>

Icon Usage Patterns

Icons are commonly used with the SocialLink component:
---
import { SocialLink } from '@/components/shared';
import { GitHubIcon, XIcon, LinkedInIcon } from '@/components/ui/icons';
---

<div class="flex gap-4">
  <SocialLink
    name="github"
    url="https://github.com/username"
    icon="github-path-data"
    ariaLabel="Visit my GitHub"
  />
  <!-- More social links -->
</div>

With Buttons

Icons enhance button actions:
---
import { ArrowIcon } from '@/components/ui/icons';
---

<button class="btn-primary">
  Continue
  <ArrowIcon class="w-4 h-4 ml-2 group-hover:translate-x-1 transition" />
</button>

With Notifications

Icons provide visual context:
---
import { CheckIcon } from '@/components/ui/icons';
---

<div class="notification success">
  <CheckIcon class="w-5 h-5 text-green-600" />
  <span>Changes saved successfully</span>
</div>

Icon Customization

Size Variants

Common size classes for icons:
w-4 h-4    /* 16px - Used in inline text, buttons */

Color Variants

Icons inherit color from parent or can be colored directly:
<!-- Inherit from parent -->
<a class="text-primary">
  <GitHubIcon class="w-6 h-6" />
</a>

<!-- Direct color -->
<EmailIcon class="w-6 h-6 text-blue-600" />

<!-- With opacity -->
<XIcon class="w-6 h-6 text-foreground/60" />

Animation

Icons can be animated with Tailwind utilities:
<!-- Hover translate -->
<ArrowIcon class="transition-transform group-hover:translate-x-1" />

<!-- Hover rotate -->
<button class="group">
  <svg class="transition-transform group-hover:rotate-12">
    <!-- icon path -->
  </svg>
</button>

<!-- Hover scale -->
<GitHubIcon class="transition-transform hover:scale-110" />

<!-- Spin animation -->
<svg class="animate-spin">
  <!-- loading icon -->
</svg>

Icon Structure

All icon components follow this structure:
---
interface Props {
  class?: string;
}

const { class: className = 'w-6 h-6' } = Astro.props;
---

<svg 
  class={className} 
  fill='currentColor' 
  viewBox='0 0 24 24'
>
  <path d='M...' />
</svg>

Key Attributes

class
string
Accepts any Tailwind or custom CSS classes for sizing and styling
fill
string
Usually currentColor to inherit parent text color. Some icons use none for stroke-based rendering.
stroke
string
Used in stroke-based icons like ArrowIcon and EmailIcon. Also set to currentColor.
viewBox
string
Standard 0 0 24 24 for consistent sizing across all icons

Creating Custom Icons

To add a new icon to the UI components:
  1. Create the component file:
---
// src/components/ui/icons/MyIcon.astro
interface Props {
  class?: string;
}

const { class: className = 'w-6 h-6' } = Astro.props;
---

<svg 
  class={className} 
  fill='currentColor' 
  viewBox='0 0 24 24'
>
  <path d='YOUR_SVG_PATH_DATA' />
</svg>
  1. Export from the icons barrel file:
// src/components/ui/icons/index.ts
export { default as MyIcon } from './MyIcon.astro';
  1. Use in components:
---
import { MyIcon } from '@/components/ui/icons';
---

<MyIcon class="w-5 h-5" />

Finding SVG Path Data

Sources for icon paths:

Optimization Tips

  • Use SVGO to optimize path data
  • Prefer currentColor for fill/stroke
  • Keep viewBox at 0 0 24 24 for consistency
  • Remove unnecessary attributes
  • Simplify complex paths when possible

Icon Export Structure

Icons are exported from the barrel file at: ~/workspace/source/src/components/ui/icons/index.ts Current exports:
export { default as ArrowIcon } from './ArrowIcon.astro';
export { default as CheckIcon } from './CheckIcon.astro';
export { default as CopyIcon } from './CopyIcon.astro';
export { default as DevToIcon } from './DevToIcon.astro';
export { default as EmailIcon } from './EmailIcon.astro';
export { default as FacebookIcon } from './FacebookIcon.astro';
export { default as GitHubIcon } from './GitHubIcon.astro';
export { default as HackerNewsIcon } from './HackerNewsIcon.astro';
export { default as LinkedInIcon } from './LinkedInIcon.astro';
export { default as PinterestIcon } from './PinterestIcon.astro';
export { default as RedditIcon } from './RedditIcon.astro';
export { default as TelegramIcon } from './TelegramIcon.astro';
export { default as WhatsAppIcon } from './WhatsAppIcon.astro';
export { default as XIcon } from './XIcon.astro';
This allows for clean imports:
---
import { 
  GitHubIcon, 
  LinkedInIcon, 
  EmailIcon 
} from '@/components/ui/icons';
---

Best Practices

  • Add aria-label to parent links/buttons
  • Use descriptive labels like “Visit my GitHub profile”
  • Don’t rely on icons alone for meaning
  • Provide text alternatives when needed
  • Icons are inline SVGs (no extra HTTP requests)
  • Small file size per icon
  • Rendered as part of the document
  • No JavaScript required
  • Use consistent sizing across similar elements
  • Maintain 24x24 viewBox for all custom icons
  • Use currentColor for theme compatibility
  • Follow the established component structure
All icons automatically adapt to theme changes:
  • Light theme: Inherits dark text colors
  • Dark theme: Inherits light text colors
  • Retro theme: Works with custom theme colors
  • No additional CSS required

Future UI Components

The UI components directory is designed to accommodate:
  • Button primitives - Reusable button styles
  • Input components - Styled form inputs
  • Badge components - Labels and tags
  • Avatar components - User profile images
  • Skeleton loaders - Loading states
  • Tooltip components - Contextual help
As your design system grows, add new primitives to maintain consistency across the application.

Build docs developers (and LLMs) love