template_0205
This commit is contained in:
198
RN_TEMPLATE/app/components/Icon.tsx
Normal file
198
RN_TEMPLATE/app/components/Icon.tsx
Normal file
@@ -0,0 +1,198 @@
|
||||
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<string, ComponentType<LucideProps>> = {
|
||||
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<ViewStyle>
|
||||
|
||||
/**
|
||||
* Stroke width for the icon (default: 2)
|
||||
*/
|
||||
strokeWidth?: number
|
||||
}
|
||||
|
||||
type PressableIconProps = Omit<TouchableOpacityProps, "style"> & BaseIconProps
|
||||
type IconProps = Omit<ViewProps, "style"> & BaseIconProps
|
||||
|
||||
/**
|
||||
* A component to render a registered icon.
|
||||
* It is wrapped in a <TouchableOpacity />
|
||||
* @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 (
|
||||
<TouchableOpacity {...pressableProps} style={$containerStyleOverride}>
|
||||
<IconComponent color={color ?? theme.colors.text} size={size} strokeWidth={strokeWidth} />
|
||||
</TouchableOpacity>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A component to render a registered icon.
|
||||
* It is wrapped in a <View />, 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 (
|
||||
<View {...viewProps} style={$containerStyleOverride}>
|
||||
<IconComponent color={color ?? theme.colors.text} size={size} strokeWidth={strokeWidth} />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
export { iconRegistry }
|
||||
Reference in New Issue
Block a user