import { ComponentType } from "react" import { StyleProp, TouchableOpacity, TouchableOpacityProps, View, ViewProps, ViewStyle, } from "react-native" import { ArrowLeft, BarChart2, Bell, Bug, Camera, Check, ChevronLeft, ChevronRight, Copy, CreditCard, Eye, EyeOff, FileText, Github, Globe, HandMetal, Heart, Home, Info, Layers, Lock, LogOut, Mail, MapPin, Menu, MessageSquare, Mic, Monitor, Moon, MoreHorizontal, Pencil, Settings, Shield, Smartphone, Sun, Tablet, Tag, User, Users, X, LucideProps, } from "lucide-react-native" import { useAppTheme } from "@/theme/context" import { s } from "@/utils/responsive" // Map icon names to Lucide components const iconRegistry: Record> = { back: ArrowLeft, barChart: BarChart2, bell: Bell, camera: Camera, caretLeft: ChevronLeft, caretRight: ChevronRight, check: Check, clap: HandMetal, community: Users, components: Layers, copy: Copy, creditCard: CreditCard, debug: Bug, fileText: FileText, github: Github, globe: Globe, heart: Heart, hidden: EyeOff, home: Home, info: Info, ladybug: Bug, lock: Lock, logout: LogOut, mail: Mail, menu: Menu, monitor: Monitor, moon: Moon, more: MoreHorizontal, pencil: Pencil, pin: MapPin, podcast: Mic, settings: Settings, shield: Shield, slack: MessageSquare, smartphone: Smartphone, sun: Sun, tablet: Tablet, tag: Tag, user: User, view: Eye, x: X, } export type IconTypes = keyof typeof iconRegistry type BaseIconProps = { /** * The name of the icon */ icon: IconTypes /** * An optional tint color for the icon */ color?: string /** * An optional size for the icon. If not provided, defaults to 24. */ size?: number /** * Style overrides for the icon container */ containerStyle?: StyleProp /** * Stroke width for the icon (default: 2) */ strokeWidth?: number } type PressableIconProps = Omit & BaseIconProps type IconProps = Omit & BaseIconProps /** * A component to render a registered icon. * It is wrapped in a * @see [Documentation and Examples]{@link https://docs.infinite.red/ignite-cli/boilerplate/app/components/Icon/} * @param {PressableIconProps} props - The props for the `PressableIcon` component. * @returns {JSX.Element} The rendered `PressableIcon` component. */ export function PressableIcon(props: PressableIconProps) { const { icon, color, size = s(24), containerStyle: $containerStyleOverride, strokeWidth = 2, ...pressableProps } = props const { theme } = useAppTheme() const IconComponent = iconRegistry[icon] if (!IconComponent) { if (__DEV__) console.warn(`Icon "${icon}" not found in registry`) return null } return ( ) } /** * A component to render a registered icon. * It is wrapped in a , use `PressableIcon` if you want to react to input * @see [Documentation and Examples]{@link https://docs.infinite.red/ignite-cli/boilerplate/app/components/Icon/} * @param {IconProps} props - The props for the `Icon` component. * @returns {JSX.Element} The rendered `Icon` component. */ export function Icon(props: IconProps) { const { icon, color, size = s(24), containerStyle: $containerStyleOverride, strokeWidth = 2, ...viewProps } = props const { theme } = useAppTheme() const IconComponent = iconRegistry[icon] if (!IconComponent) { if (__DEV__) console.warn(`Icon "${icon}" not found in registry`) return null } return ( ) } export { iconRegistry }