Closed alwyntan closed 1 year ago
For some reason this seems to be related to a problem where SVG child attributes are not inheriting the parent's properties (fill, stroke, etc). On development it works, but once an OTA update is released, it breaks.
And for the currentColor
to work as a color, the parent Svg component seems to need the prop color
to be defined, eg: <Svg color="red" />
, for the currentColor
of the child to work properly.
What I've done to make this work is explicitly copy the properties over to the SVG children in the function createLucideIcon
for OTA updates to work. Happy to open a PR.
Related issues in react-native-svg
:
https://github.com/software-mansion/react-native-svg/issues/1284
https://github.com/software-mansion/react-native-svg/issues/1287
Proposed solution/patch solution I'm using right now:
import { forwardRef, createElement, ReactSVG, ReactNode, FunctionComponent } from 'react';
import PropTypes from 'prop-types';
import * as NativeSvg from 'react-native-svg';
import defaultAttributes from './defaultAttributes';
import type { SvgProps } from 'react-native-svg';
type IconNode = [elementName: keyof ReactSVG, attrs: Record<string, string>][]
export interface LucideProps extends SvgProps {
size?: string | number
absoluteStrokeWidth?: boolean
}
const createLucideIcon = (iconName: string, iconNode: IconNode) => {
const Component = forwardRef(
({ color = 'currentColor', size = 24, strokeWidth = 2, absoluteStrokeWidth, children, ...rest }: LucideProps, ref) =>
createElement(
NativeSvg.Svg as unknown as string,
{
ref,
...defaultAttributes,
width: size,
height: size,
stroke: color,
strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
+ color,
...rest,
},
[
...iconNode.map(([tag, attrs]) => {
const upperCasedTag = (tag.charAt(0).toUpperCase() + tag.slice(1)) as keyof (typeof NativeSvg);
- return createElement(NativeSvg[upperCasedTag] as FunctionComponent<Record<string, string>>, attrs);
+ // add this to the defaultAttributes file
+ const defaultChildProps = {
+ stroke: defaultAttributes.stroke, // or we can just have it use the "color" prop directly, and we wont have to add the color line above
+ strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
+ strokeLinecap: defaultAttributes.strokeLinecap,
+ strokeLinejoin: defaultAttributes.strokeLinejoin
+ }
+ return createElement(NativeSvg[upperCasedTag] as FunctionComponent<Record<string, string>>, { ...defaultChildProps, ...attrs }); // add the properties explicitly here, can consider adding ...rest here
}),
...(
(Array.isArray(children) ? children : [children]) || []
),
],
),
);
Component.propTypes = {
color: PropTypes.string,
size: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
strokeWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
};
Component.displayName = `${iconName}`;
return Component;
};
export default createLucideIcon;
@alwyntan Thanks for reporting this. Feel free to open a PR!
Prerequisites
Step to reproduce
Install lucide react native as per the documentations. During development, the builds work fine, and production builds work fine **until an over the air update is served through Codepush. (expo updates could have the same issue too)
Actual behavior
Icons black out and only shows the silhouettes after an over the air update. It might be a JS bundling issue that is resulting in this.
Any message or error
No message or error
Resources
See screenshots below:
Before an OTA update:
After an OTA update: