Better ways of using Monicon with Nativewind
I am not sure if here is the right place to post this (since there are no Discussions tab on this project), but I have something to say.
I am using Monicon with React Native in my project, and it works well in most cases. However, I want to styling Monicon components with Nativewind v4 for these reasons:
- Setting icon color bases on color scheme and user preferences. I am already managing all of theme tokens with Nativewind, and I hope I can coloring icons in a unified way just like other components.
- Setting icon size bases on screen or container sizes; since my app would be used on mobile, tablet and desktop (web), responsive design would be important for me.
Currently, I am getting this working on native platforms with workarounds suggested in Nativewind's documents:
<Monicon name="fa6-solid:pause" className={"{}-[size]:size-[32px] {}-[color]:color-background-0"} />
However, it doesn't works on web, the size and color props were not applied.
Now, I am considering using some other workarounds (like writing custom hooks for styling icons bases on various scanarios), but it would be much appreciated if you are able to make styling with community solutions (like Nativewind) smoothly. ❤️
I think you need a custom hook returns plain javascript object.
const theme = useTheme()
<Monicon color={theme.colors.background.primary} size={theme.sizing[32]} />
If you have an different idea, i want to discuss.
Sure, now I am already using my custom hooks for that.
Personally, I think being able to style width, height and color via community styling solutions like Nativewind are already a good addition; When needs complex styling, it would be much easier to just copy the SVG content and use react-native-svg directly.
If it's really hard to implement, that's not a huge problem, and I can still come with a solution.
This works for me:
import React from 'react'
import { Platform } from 'react-native'
import { cssInterop } from 'nativewind'
import { Monicon, MoniconProps } from '@monicon/native'
// browse icons at https://icones.js.org/ and https://icon-sets.iconify.design/ then add individual icons or icon sets in metro.config.js
export type MoniconPropsWithClassName = MoniconProps & {
className?: string
}
const BaseIcon = cssInterop(
Monicon as React.ComponentType<MoniconPropsWithClassName>,
{
className: {
target: 'className',
nativeStyleToProp: {
color: true,
},
},
},
)
export const Icon: React.FC<MoniconPropsWithClassName> = (props) => {
const { color, className, name, size, ...restProps } = props as any
if (Platform.OS === 'web') {
return (
<span className={className}>
<BaseIcon name={name} size={size} {...restProps} />
</span>
)
}
// Native platforms: forward props directly.
return <BaseIcon name={name} size={size} {...restProps} className={className} />
}
export default Icon
Usage:
<Icon name="mingcute:user-2-fill" size={20} className="color-red-500" /> // or text-red-500
Works for color but maybe you can add support for size if you need it, check this: https://www.nativewind.dev/docs/api/css-interop