import { define } from 'forge' import { theme } from './theme' import * as icons from 'lucide-static' import { Grid } from './grid' import { VStack } from './stack' import { Section } from './section' import { H2, Text } from './text' export type IconName = keyof typeof icons // Icon wrapper - the SVG is injected via dangerouslySetInnerHTML const IconWrapper = define('Icon', { display: 'block', flexShrink: 0, }) // IconLink wrapper const IconLinkWrapper = define('IconLink', { base: 'a', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', transition: 'opacity 0.2s', states: { ':hover': { opacity: 0.7, }, }, }) type IconProps = Parameters[0] & { name: IconName size?: number } type IconLinkProps = Parameters[0] & { name: IconName size?: number } function sizeToPixels(size: number): number { return size * 4 } export const Icon = (props: IconProps) => { const { name, size = 6, style, ...rest } = props const iconSvg = icons[name] if (!iconSvg) { throw new Error(`Icon "${name}" not found in Lucide icons`) } const pixelSize = sizeToPixels(size) const iconStyle = { width: `${pixelSize}px`, height: `${pixelSize}px`, ...style, } // Modify the SVG string to include our custom attributes const modifiedSvg = iconSvg .replace(/width="[^"]*"/, '') .replace(/height="[^"]*"/, '') .replace(/class="[^"]*"/, '') .replace( /]*)>/, `` ) return } export const IconLink = (props: IconLinkProps) => { const { href = '#', name, size, ...rest } = props return ( ) } export const Test = () => { return (
{/* Size variations */}

Icon Size Variations

{([3, 4, 5, 6, 8, 10, 12, 16] as const).map((size) => ( {size} ))}
{/* Styling with CSS classes */}

Styling with CSS Classes

Default Blue Color Thin Stroke Filled Hover Effect
{/* Advanced styling */}

Advanced Styling

Filled Heart Thick Stroke Sun Icon Drop Shadow
{/* Icon links */}

Icon Links

Home Link External Link Email Link Phone Link
{/* Styled icon links */}

Styled Icon Links

Button Style Circle Border Red Heart Filled Star
) }