Click here to see code
```tsx
import React from 'react'
import Icon from '@expo/vector-icons/build/Ionicons'
import { styled, useDripsyTheme as useTheme } from 'dripsy'
const StyledIcon = styled(Icon)({})
type Color = (string & {}) | keyof ReturnType['colors']
type Name = React.ComponentProps['name']
type Icon =
| {
name: Name
size?: number
color?: Color
}
| React.ReactElement
| Name
type BaseProps = {
size?: number
color?: Color
name: Name
}
export type IconProps = {
icon: Icon
}
export type IconsBaseProps = BaseProps
export type AllIconProps = (IconProps | BaseProps) & {
sx?: React.ComponentProps['sx']
selectable?: boolean
}
function isIconProps(props: AllIconProps): props is IconProps {
return !!(props as IconProps).icon
}
export default function Ionicons(props: AllIconProps) {
const { colors } = useTheme()
let icon: Icon | undefined
let color: Color = colors.text
if (isIconProps(props)) {
icon = props.icon
} else {
icon = {
name: props.name,
color: props.color,
size: props.size,
}
}
if (React.isValidElement(icon)) {
return icon
}
// this exists for conditional props
if (typeof icon === 'boolean') return null
let name: React.ComponentProps['name'] | null = null
let size = 22
if (typeof icon === 'string') {
name = icon as React.ComponentProps['name']
} else if (icon?.name) {
name = icon.name
if (icon.size) size = icon.size
if (icon.color) {
color = colors?.[icon.color] ?? icon.color
}
}
if (!name) return null
return (
)
}
```
This allows for nice, strictly-typed colors for your icons, and has intellisense for your theme's colors. It also has multiple modes of composition:
While more obscure, the object prop patterns allows you to easily compose other components that wrap the icon. For example, a Button component might have a iconPrefix prop.
type ButtonProps = {
iconPrefix: IconProps['icon']
}
export function Button({ iconPrefix }: ButtonProps) {
return <Ionicons icon={iconPrefix} />
}
I think I have a great system setup for using expo icons with Dripsy. Figured I'd share it here.
I wanted type-safe props that used my theme values for colors.
Note, you should replace
useTheme
with your own customuseTheme
function, as detailed at https://github.com/nandorojo/dripsy/issues/72#issuecomment-828587515Click here to see code
```tsx import React from 'react' import Icon from '@expo/vector-icons/build/Ionicons' import { styled, useDripsyTheme as useTheme } from 'dripsy' const StyledIcon = styled(Icon)({}) type Color = (string & {}) | keyof ReturnTypeThis allows for nice, strictly-typed colors for your icons, and has intellisense for your theme's colors. It also has multiple modes of composition:
Direct props
Object props
While more obscure, the object prop patterns allows you to easily compose other components that wrap the icon. For example, a
Button
component might have aiconPrefix
prop.Now, you can compose the button with ease: