Template
139 lines
2.6 KiB
TypeScript
139 lines
2.6 KiB
TypeScript
import type { ComponentType, SVGProps } from 'react'
|
|
import {
|
|
Search,
|
|
Sun,
|
|
Moon,
|
|
Copy,
|
|
Check,
|
|
Eye,
|
|
ArrowRight,
|
|
ArrowLeft,
|
|
Menu,
|
|
Layers,
|
|
Sparkles,
|
|
Terminal,
|
|
AlertTriangle,
|
|
AlertCircle,
|
|
Info,
|
|
CheckCircle2,
|
|
X,
|
|
Plus,
|
|
Minus,
|
|
Trash2,
|
|
ExternalLink,
|
|
ChevronDown,
|
|
ChevronRight,
|
|
ChevronLeft,
|
|
ChevronUp,
|
|
Filter,
|
|
SlidersHorizontal,
|
|
Code2,
|
|
Cpu,
|
|
Database,
|
|
User,
|
|
Shield,
|
|
Folder,
|
|
FileText,
|
|
Calendar,
|
|
Clock,
|
|
RefreshCw,
|
|
Download,
|
|
Upload,
|
|
Settings,
|
|
HelpCircle,
|
|
type LucideIcon,
|
|
type LucideProps,
|
|
} from 'lucide-react'
|
|
|
|
export type { LucideIcon, LucideProps }
|
|
|
|
const iconMap: Record<string, LucideIcon> = {
|
|
// Northstar legacy shorthands
|
|
search: Search,
|
|
sun: Sun,
|
|
moon: Moon,
|
|
copy: Copy,
|
|
check: Check,
|
|
eye: Eye,
|
|
arrow: ArrowRight,
|
|
'arrow-right': ArrowRight,
|
|
'arrow-left': ArrowLeft,
|
|
menu: Menu,
|
|
layers: Layers,
|
|
sparkle: Sparkles,
|
|
sparkles: Sparkles,
|
|
terminal: Terminal,
|
|
|
|
// Common UI primitives
|
|
close: X,
|
|
x: X,
|
|
plus: Plus,
|
|
minus: Minus,
|
|
trash: Trash2,
|
|
'trash-2': Trash2,
|
|
settings: Settings,
|
|
filter: Filter,
|
|
sliders: SlidersHorizontal,
|
|
refresh: RefreshCw,
|
|
download: Download,
|
|
upload: Upload,
|
|
external: ExternalLink,
|
|
'external-link': ExternalLink,
|
|
info: Info,
|
|
warning: AlertTriangle,
|
|
'alert-triangle': AlertTriangle,
|
|
alert: AlertCircle,
|
|
'alert-circle': AlertCircle,
|
|
'check-circle': CheckCircle2,
|
|
help: HelpCircle,
|
|
'chevron-down': ChevronDown,
|
|
'chevron-right': ChevronRight,
|
|
'chevron-left': ChevronLeft,
|
|
'chevron-up': ChevronUp,
|
|
code: Code2,
|
|
cpu: Cpu,
|
|
database: Database,
|
|
user: User,
|
|
shield: Shield,
|
|
folder: Folder,
|
|
file: FileText,
|
|
calendar: Calendar,
|
|
clock: Clock,
|
|
}
|
|
|
|
export type IconName = keyof typeof iconMap | string
|
|
|
|
export type IconProps = Omit<SVGProps<SVGSVGElement>, 'ref'> & {
|
|
name?: IconName
|
|
icon?: LucideIcon | ComponentType<{ size?: number | string; strokeWidth?: number; className?: string }>
|
|
size?: number | string
|
|
strokeWidth?: number
|
|
className?: string
|
|
}
|
|
|
|
/**
|
|
* Universal Icon component backed by lucide-react.
|
|
* Accepts either a shorthand name (e.g. name="sparkle", name="check")
|
|
* or a direct Lucide icon component (e.g. icon={Sparkles}).
|
|
*/
|
|
export function Icon({
|
|
name,
|
|
icon: IconComponent,
|
|
size = 18,
|
|
strokeWidth = 1.8,
|
|
className,
|
|
...props
|
|
}: IconProps) {
|
|
const Component = IconComponent || (name ? iconMap[name.toLowerCase()] : undefined) || Layers
|
|
|
|
return (
|
|
<Component
|
|
size={size}
|
|
strokeWidth={strokeWidth}
|
|
className={className}
|
|
aria-hidden="true"
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|