Skip to content

Commit

Permalink
feat: add react-native-web support
Browse files Browse the repository at this point in the history
fix: #8
  • Loading branch information
oktaysenkan committed Jan 25, 2024
1 parent f6b23df commit 0bec175
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 38 deletions.
1 change: 1 addition & 0 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"web": "expo start --web"
},
"dependencies": {
"@expo/metro-runtime": "^3.1.2",
"@shopify/flash-list": "1.4.0",
"expo": "~48.0.6",
"expo-status-bar": "~1.4.4",
Expand Down
5 changes: 5 additions & 0 deletions example/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,11 @@
resolve-from "^5.0.0"
sucrase "^3.20.0"

"@expo/metro-runtime@^3.1.2":
version "3.1.2"
resolved "https://registry.yarnpkg.com/@expo/metro-runtime/-/metro-runtime-3.1.2.tgz#4cc4fe53aa8f716307f584c67db76268d38c2ed7"
integrity sha512-Wekv2AZ3HY0NG9Im8AMB1KHGyHjmALg6xekVK34724I/DLtcocLKtQEP04oI9GcAZBotAhROHH5E4ADhJAEgYg==

"@expo/[email protected]", "@expo/osascript@^2.0.31":
version "2.0.33"
resolved "https://registry.npmjs.org/@expo/osascript/-/osascript-2.0.33.tgz"
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
},
"dependencies": {
"@iconify/json": "^2.2.174",
"@iconify/utils": "^2.1.16"
"@iconify/utils": "^2.1.16",
"html-react-parser": "^5.1.1"
}
}
41 changes: 7 additions & 34 deletions src/Iconify.tsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,28 @@
import { FullExtendedIconifyIcon, iconToHTML, iconToSVG } from '@iconify/utils';
import React, { useMemo } from 'react';
import { SvgXml, XmlProps } from 'react-native-svg';
import { FullExtendedIconifyIcon } from '@iconify/utils';
import { XmlProps } from 'react-native-svg';
import { renderIcon } from './icon';

type Props = {
icon: string;
size?: number;
} & Omit<XmlProps, 'xml'>;

type RuntimeProps = Props & {
export type RuntimeProps = Props & {
isPluginInstalled: boolean;
iconData: FullExtendedIconifyIcon;
};

export const Iconify = ({ size = 24, color = 'black', ...props }: Props) => {
export const Iconify = (props: Props) => {
const runtimeProps = props as RuntimeProps;
const { isPluginInstalled, iconData } = runtimeProps;

const svg = useMemo(() => {
if (!iconData) {
return null;
}

const iconBuildResult = iconToSVG(iconData, {
height: size,
});

return {
...iconBuildResult,
body: iconToHTML(iconBuildResult.body, iconBuildResult.attributes),
};
}, [size, iconData]);
const { isPluginInstalled } = runtimeProps;

if (!isPluginInstalled) {
throw new Error(
'Iconify: You need to install a Babel plugin before using this library. You can continue by adding the following to your babel.config.js'
);
}

if (!iconData || !svg || !svg.body) {
return null;
}

return (
<SvgXml
xml={svg.body}
height={svg.attributes.height}
width={svg.attributes.width}
color={color}
{...props}
/>
);
return renderIcon(runtimeProps);
};

export default Iconify;
58 changes: 58 additions & 0 deletions src/icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react';
import { Platform } from 'react-native';
import { SvgXml } from 'react-native-svg';
import { IconifyIconBuildResult, iconToHTML, iconToSVG } from '@iconify/utils';
import parse from 'html-react-parser';
import { RuntimeProps } from './Iconify';

export type SVGIcon = IconifyIconBuildResult & {
body: string;
};

const prepareSvgIcon = ({ iconData, size }: RuntimeProps): SVGIcon => {
const iconBuildResult = iconToSVG(iconData, {
height: size,
});

return {
...iconBuildResult,
body: iconToHTML(iconBuildResult.body, iconBuildResult.attributes),
};
};

export const renderWebIcon = (svg: SVGIcon, props: RuntimeProps) => {
const svgAsHtml = props.color
? svg.body.replace(
/<svg([^>]*)>/,
`<svg$1 style="color: ${String(props.color)};">`
)
: svg.body;

return <>{parse(svgAsHtml)}</>;
};

export const renderNativeIcon = (svg: SVGIcon, props: RuntimeProps) => {
return (
<SvgXml
xml={svg.body}
height={svg.attributes.height}
width={svg.attributes.width}
color={props.color}
{...props}
/>
);
};

export const renderIcon = (props: RuntimeProps) => {
const svg = prepareSvgIcon(props);

if (!props.iconData || !svg || !svg.body) {
return null;
}

if (Platform.OS === 'web') {
return renderWebIcon(svg, props);
}

return renderNativeIcon(svg, props);
};
58 changes: 55 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4172,14 +4172,14 @@ domelementtype@^2.3.0:
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==

domhandler@^5.0.2, domhandler@^5.0.3:
domhandler@5.0.3, domhandler@^5.0.2, domhandler@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
dependencies:
domelementtype "^2.3.0"

domutils@^3.0.1:
domutils@^3.0.1, domutils@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e"
integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==
Expand Down Expand Up @@ -4244,7 +4244,7 @@ end-of-stream@^1.1.0:
dependencies:
once "^1.4.0"

entities@^4.2.0:
entities@^4.2.0, entities@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
Expand Down Expand Up @@ -5390,11 +5390,39 @@ hosted-git-info@^4.0.0, hosted-git-info@^4.0.1:
dependencies:
lru-cache "^6.0.0"

[email protected]:
version "5.0.7"
resolved "https://registry.yarnpkg.com/html-dom-parser/-/html-dom-parser-5.0.7.tgz#33f029b34e8ec4076b7e2624c97debc79abb0c75"
integrity sha512-2YD2/yB0QgrlkBIn0CsGaRXC89E1gtuPVpiOGC52NTzPCC83n0WMdGD+5q7lpcKqbCpnWValQbovuy/NI/0kag==
dependencies:
domhandler "5.0.3"
htmlparser2 "9.1.0"

html-escaper@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==

html-react-parser@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/html-react-parser/-/html-react-parser-5.1.1.tgz#9863709ab1bb5d15bce273253b539a6dd4fa28e2"
integrity sha512-L5VK0rKN3VM7uzRH+4wxAL9elvHuCNDjyWKKjcCDR+YWW5Qr7WWSK7+e627DcePVAFi5IMqc+rAU8j/1DpC/Tw==
dependencies:
domhandler "5.0.3"
html-dom-parser "5.0.7"
react-property "2.0.2"
style-to-js "1.1.10"

[email protected]:
version "9.1.0"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-9.1.0.tgz#cdb498d8a75a51f739b61d3f718136c369bc8c23"
integrity sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.3"
domutils "^3.1.0"
entities "^4.5.0"

http-cache-semantics@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
Expand Down Expand Up @@ -5539,6 +5567,11 @@ ini@^1.3.2, ini@^1.3.4, ini@~1.3.0:
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==

[email protected]:
version "0.2.2"
resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.2.2.tgz#d498b4e6de0373458fc610ff793f6b14ebf45633"
integrity sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==

[email protected]:
version "9.2.6"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-9.2.6.tgz#802a61ee3eefbf1cb82a7fb6c2ae95a106050e01"
Expand Down Expand Up @@ -8559,6 +8592,11 @@ [email protected]:
whatwg-fetch "^3.0.0"
ws "^6.2.2"

[email protected]:
version "2.0.2"
resolved "https://registry.yarnpkg.com/react-property/-/react-property-2.0.2.tgz#d5ac9e244cef564880a610bc8d868bd6f60fdda6"
integrity sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug==

react-refresh@^0.4.0:
version "0.4.3"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.3.tgz#966f1750c191672e76e16c2efa569150cc73ab53"
Expand Down Expand Up @@ -9554,6 +9592,20 @@ strnum@^1.0.5:
resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db"
integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==

[email protected]:
version "1.1.10"
resolved "https://registry.yarnpkg.com/style-to-js/-/style-to-js-1.1.10.tgz#ec20e1264ba11dc7f71b94b3a3a05566ed856e54"
integrity sha512-VC7MBJa+y0RZhpnLKDPmVRLRswsASLmixkiZ5R8xZpNT9VyjeRzwnXd2pBzAWdgSGv/pCNNH01gPCCUsB9exYg==
dependencies:
style-to-object "1.0.5"

[email protected]:
version "1.0.5"
resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-1.0.5.tgz#5e918349bc3a39eee3a804497d97fcbbf2f0d7c0"
integrity sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==
dependencies:
inline-style-parser "0.2.2"

sudo-prompt@^9.0.0:
version "9.2.1"
resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.2.1.tgz#77efb84309c9ca489527a4e749f287e6bdd52afd"
Expand Down

0 comments on commit 0bec175

Please sign in to comment.