From c2a53ab76e34afdcf0f550da5fbcfd4429fe1e95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oktay=20=C5=9Eenkan?= Date: Sat, 5 Oct 2024 14:48:07 +0300 Subject: [PATCH] feat: use icon-loader from ui packages --- apps/react-native-app/App.tsx | 1 + apps/rspack-react/src/App.jsx | 2 +- packages/icon-loader/package.json | 5 -- packages/icon-loader/src/index.ts | 43 +++++++++------- packages/icon-loader/tsup.config.ts | 2 - packages/native/package.json | 9 ++-- packages/native/src/constants.ts | 5 -- packages/native/src/iconify.tsx | 70 ++++++++------------------ packages/native/src/index.ts | 1 + packages/native/src/index.tsx | 2 - packages/native/src/types.ts | 15 ------ packages/native/src/utils.ts | 30 ----------- packages/native/tsup.config.ts | 2 +- packages/react/src/iconify.tsx | 7 +-- packages/react/src/index.tsx | 2 +- packages/react/src/types.ts | 5 -- packages/svelte/package.json | 3 +- packages/svelte/src/lib/Iconify.svelte | 45 ++++------------- packages/vite/src/index.ts | 9 ++-- packages/vue/package.json | 3 +- packages/vue/src/Iconify.vue | 61 ++-------------------- packages/vue/src/index.ts | 4 +- packages/vue/src/main.ts | 4 +- packages/webpack/src/index.ts | 1 - 24 files changed, 88 insertions(+), 243 deletions(-) delete mode 100644 packages/native/src/constants.ts create mode 100644 packages/native/src/index.ts delete mode 100644 packages/native/src/index.tsx delete mode 100644 packages/native/src/types.ts delete mode 100644 packages/native/src/utils.ts delete mode 100644 packages/react/src/types.ts diff --git a/apps/react-native-app/App.tsx b/apps/react-native-app/App.tsx index 78d4a0d..480a856 100644 --- a/apps/react-native-app/App.tsx +++ b/apps/react-native-app/App.tsx @@ -9,6 +9,7 @@ export default function App() { + ); } diff --git a/apps/rspack-react/src/App.jsx b/apps/rspack-react/src/App.jsx index 3f8a803..a2d2a10 100644 --- a/apps/rspack-react/src/App.jsx +++ b/apps/rspack-react/src/App.jsx @@ -6,7 +6,7 @@ import "./App.css"; function App() { return (
- +
); diff --git a/packages/icon-loader/package.json b/packages/icon-loader/package.json index d2beb4d..bd26ed1 100644 --- a/packages/icon-loader/package.json +++ b/packages/icon-loader/package.json @@ -11,11 +11,6 @@ "import": "./dist/index.mjs", "require": "./dist/index.js", "types": "./dist/index.d.ts" - }, - "./constants": { - "import": "./dist/constants.mjs", - "require": "./dist/constants.js", - "types": "./dist/constants.d.mts" } }, "publishConfig": { diff --git a/packages/icon-loader/src/index.ts b/packages/icon-loader/src/index.ts index 850a179..81e8080 100644 --- a/packages/icon-loader/src/index.ts +++ b/packages/icon-loader/src/index.ts @@ -1,18 +1,7 @@ -import type { Icon } from "@oktaytest/core"; +import { Icon } from "@oktaytest/core"; import { parseSync, stringify } from "svgson"; -// @ts-ignore -import _icons from "oktay"; - -const icons = _icons as Record; - -export const fallbackIcon: Icon = { - svg: ' ', - width: 32, - height: 32, -}; - -export type IconProps = { +export type IconifyProps = { name: string; size?: number; color?: string; @@ -20,10 +9,16 @@ export type IconProps = { export type GetIconDetailsOptions = { icon: Icon; - props: IconProps; + props: IconifyProps; }; -const loadIcon = (iconName: string) => { +export const fallbackIcon: Icon = { + svg: ' ', + width: 32, + height: 32, +}; + +const loadIcon = (iconName: string, icons: Record) => { const icon = icons?.[iconName]; if (icon) return icon; @@ -35,8 +30,11 @@ const loadIcon = (iconName: string) => { return fallbackIcon; }; -export const getIconDetails = (props: IconProps) => { - const icon = loadIcon(props.name); +export const getIconDetails = ( + props: IconifyProps, + icons: Record +) => { + const icon = loadIcon(props.name, icons); const parsed = parseSync(icon.svg); @@ -58,8 +56,19 @@ export const getIconDetails = (props: IconProps) => { height: `${height}px`, }; + parsed.attributes = attributes; + + icon.svg = icon.svg + .replace(/width="([^"]+)"/, `width="${width}"`) + .replace(/height="([^"]+)"/, `height="${height}"`); + + if (props.color) { + icon.svg = icon.svg.replace(/fill="([^"]+)"/, `fill="${props.color}"`); + } + return { innerHtml, attributes, + svg: icon.svg, }; }; diff --git a/packages/icon-loader/tsup.config.ts b/packages/icon-loader/tsup.config.ts index ed2c095..410a401 100644 --- a/packages/icon-loader/tsup.config.ts +++ b/packages/icon-loader/tsup.config.ts @@ -2,9 +2,7 @@ import { defineConfig, Options } from "tsup"; export default defineConfig((options: Options) => ({ entry: ["src/index.ts"], - clean: true, format: ["cjs", "esm"], - external: ["oktay"], dts: true, ...options, })); diff --git a/packages/native/package.json b/packages/native/package.json index 85b674b..86b4c4b 100644 --- a/packages/native/package.json +++ b/packages/native/package.json @@ -15,9 +15,9 @@ "import": "./dist/index.mjs", "require": "./dist/index.js" }, - "./iconify": { - "import": "./dist/iconify.mjs", - "require": "./dist/iconify.js" + "./Iconify": { + "import": "./dist/Iconify.mjs", + "require": "./dist/Iconify.js" } }, "scripts": { @@ -35,7 +35,8 @@ }, "dependencies": { "html-react-parser": "^5.1.16", - "@oktaytest/core": "*" + "@oktaytest/core": "*", + "@oktaytest/icon-loader": "*" }, "peerDependencies": { "react": ">=18.2.0", diff --git a/packages/native/src/constants.ts b/packages/native/src/constants.ts deleted file mode 100644 index dc04ecf..0000000 --- a/packages/native/src/constants.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const fallbackIcon = { - svg: ' ', - width: 32, - height: 32, -}; diff --git a/packages/native/src/iconify.tsx b/packages/native/src/iconify.tsx index eca1f01..0b92c7a 100644 --- a/packages/native/src/iconify.tsx +++ b/packages/native/src/iconify.tsx @@ -1,8 +1,5 @@ import React from "react"; - -import { IconifyProps, RuntimeIcon, RuntimeIconifyProps } from "./types"; -import { setAttributes } from "./utils"; -import { fallbackIcon } from "./constants"; +import { getIconDetails, IconifyProps } from "@oktaytest/icon-loader"; const isReactNative = async () => { try { @@ -16,59 +13,34 @@ const isReactNative = async () => { } }; -const getIcon = (iconName: string) => - new Promise(async (resolve, reject) => { - try { - // todo: add error handling - // @ts-ignore - const iconsImport = await import("oktay"); - - const icons = iconsImport.default ?? iconsImport; - - let icon = icons[iconName]; - - if (!icon) { - console.warn( - `[Iconify] The icon "${iconName}" is missing from the configuration. To resolve this, ensure it is added to the 'icons' array within the Iconify plugin's configuration.` - ); - - icon = fallbackIcon; - } - - resolve(icon); - } catch (error) { - reject(error); - } - }); - -const nativeIcon = async (props: RuntimeIconifyProps) => { +const nativeIcon = async (props: ReturnType) => { const { SvgXml } = require("react-native-svg"); return ( ); }; -const webIcon = async (props: RuntimeIconifyProps) => { - // @ts-ignore - const parse = await import("html-react-parser"); - - return parse.default(props.icon.svg); +const webIcon = async (props: ReturnType) => { + return ( + + ); }; -const getComponent = async (props: RuntimeIconifyProps) => { - const formatted = setAttributes(props); - +const getComponent = async (props: ReturnType) => { const isNative = await isReactNative(); - if (isNative) return nativeIcon(formatted); + if (isNative) return nativeIcon(props); - return webIcon(formatted); + return webIcon(props); }; export const Iconify = (props: IconifyProps) => { @@ -77,12 +49,14 @@ export const Iconify = (props: IconifyProps) => { ); const renderIcon = async () => { - const icon = await getIcon(props.name); + // @ts-ignore + const iconsImport = await import("oktay"); + + const icons = iconsImport.default ?? iconsImport; + + const details = getIconDetails(props, icons); - const component = await getComponent({ - ...props, - icon, - }); + const component = await getComponent(details); setComponent(component); }; diff --git a/packages/native/src/index.ts b/packages/native/src/index.ts new file mode 100644 index 0000000..cccc9a7 --- /dev/null +++ b/packages/native/src/index.ts @@ -0,0 +1 @@ +export { Iconify } from "./Iconify"; diff --git a/packages/native/src/index.tsx b/packages/native/src/index.tsx deleted file mode 100644 index 9aa0657..0000000 --- a/packages/native/src/index.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export { Iconify } from "./iconify"; -export { type IconifyProps } from "./types"; diff --git a/packages/native/src/types.ts b/packages/native/src/types.ts deleted file mode 100644 index 8bbbaac..0000000 --- a/packages/native/src/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -export interface IconifyProps { - name: string; - size?: number; - color?: string; -} - -export interface RuntimeIcon { - svg: string; - width: number; - height: number; -} - -export interface RuntimeIconifyProps extends IconifyProps { - icon: RuntimeIcon; -} diff --git a/packages/native/src/utils.ts b/packages/native/src/utils.ts deleted file mode 100644 index e3c4b4c..0000000 --- a/packages/native/src/utils.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { RuntimeIconifyProps } from "./types"; - -export const setAttributes = ( - props: RuntimeIconifyProps -): RuntimeIconifyProps => { - const ratio = props.icon.width / props.icon.height; - - let svg = props.icon.svg; - - const height = props.size ? props.size : props.icon.height; - const width = props.size ? props.size * ratio : props.icon.width; - - svg = svg - .replace(/width="([^"]+)"/, `width="${width}"`) - .replace(/height="([^"]+)"/, `height="${height}"`); - - if (props.color) { - svg = svg.replace(/fill="([^"]+)"/, `fill="${props.color}"`); - } - - return { - ...props, - icon: { - ...props.icon, - svg, - height, - width, - }, - }; -}; diff --git a/packages/native/tsup.config.ts b/packages/native/tsup.config.ts index 952d05a..d730aa6 100644 --- a/packages/native/tsup.config.ts +++ b/packages/native/tsup.config.ts @@ -1,7 +1,7 @@ import { defineConfig, Options } from "tsup"; export default defineConfig((options: Options) => ({ - entry: ["src/index.tsx", "src/iconify.tsx"], + entry: ["src/index.ts", "src/Iconify.tsx"], banner: { js: "'use client'", }, diff --git a/packages/react/src/iconify.tsx b/packages/react/src/iconify.tsx index 5eebf59..6d4f97b 100644 --- a/packages/react/src/iconify.tsx +++ b/packages/react/src/iconify.tsx @@ -1,10 +1,11 @@ import React from "react"; -import { getIconDetails } from "@oktaytest/icon-loader"; +import { getIconDetails, IconifyProps } from "@oktaytest/icon-loader"; -import { IconifyProps } from "./types"; +// @ts-ignore +import icons from "oktay"; export const Iconify = (props: IconifyProps) => { - const details = getIconDetails(props); + const details = getIconDetails(props, icons); return ( - import { parseSync, stringify } from "svgson"; - import { fallbackIcon } from "@oktaytest/core/constants"; - // @ts-ignore - import icons from "oktay"; + import type { Icon } from "@oktaytest/core"; + import { getIconDetails } from "@oktaytest/icon-loader"; export let name: string; export let size: number | undefined = undefined; export let color: string | undefined = undefined; - $: icon = icons[name] || fallbackIcon; - - if (!icons[name]) { - console.warn( - `[Iconify] The icon "${name}" is missing from the configuration. To resolve this, ensure it is added to the 'icons' array within the Iconify plugin's configuration.` - ); - } - - $: parsed = parseSync(icon.svg); - - $: children = parsed.children.map((child) => { - if (child.name !== "path" || !child.attributes.fill || !color) return child; - - child.attributes.fill = color; - return child; - }); - - $: html = stringify(children as any); - - $: ratio = icon.width / icon.height; - - $: height = size ? Number(size) : icon.height; - - $: width = size ? Number(size) * ratio : icon.width; + // @ts-ignore + import icons from "oktay"; - $: attributes = { - ...parsed.attributes, - width, - height, - }; + $: details = getIconDetails( + { name, color, size }, + icons as Record + ); - - {@html html} + + {@html details.innerHtml} diff --git a/packages/vite/src/index.ts b/packages/vite/src/index.ts index 74d28cc..cd47aec 100644 --- a/packages/vite/src/index.ts +++ b/packages/vite/src/index.ts @@ -11,17 +11,14 @@ const alias = getResolveAlias(); export const IconifyPlugin = (options: IconifyOptions): PluginOption[] => [ { name: "vite-plugin-iconify", + async buildStart() { + await loadIcons({ type: "esm", ...options }); + }, resolveId(source) { if (source === alias) return getIconsFilePath({ type: "esm", ...options }); return null; }, - async buildStart() { - await loadIcons({ type: "esm", ...options }); - }, - load(id) { - return null; - }, }, ]; diff --git a/packages/vue/package.json b/packages/vue/package.json index ea07305..69a4ea3 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -31,8 +31,7 @@ "vite-plugin-dts": "^4.2.3" }, "dependencies": { - "@oktaytest/core": "*", - "svgson": "^5.3.1" + "@oktaytest/icon-loader": "*" }, "peerDependencies": { "vue": "^2.6.14 || ^3.0.0" diff --git a/packages/vue/src/Iconify.vue b/packages/vue/src/Iconify.vue index 25ebbe6..991810f 100644 --- a/packages/vue/src/Iconify.vue +++ b/packages/vue/src/Iconify.vue @@ -1,68 +1,15 @@ diff --git a/packages/vue/src/index.ts b/packages/vue/src/index.ts index 2693f69..9826866 100644 --- a/packages/vue/src/index.ts +++ b/packages/vue/src/index.ts @@ -1,4 +1,6 @@ import type { App } from "vue"; +import { IconifyProps } from "@oktaytest/icon-loader"; + import Iconify from "./Iconify.vue"; export default { @@ -7,4 +9,4 @@ export default { }, }; -export { Iconify }; +export { Iconify, type IconifyProps }; diff --git a/packages/vue/src/main.ts b/packages/vue/src/main.ts index 2693f69..9826866 100644 --- a/packages/vue/src/main.ts +++ b/packages/vue/src/main.ts @@ -1,4 +1,6 @@ import type { App } from "vue"; +import { IconifyProps } from "@oktaytest/icon-loader"; + import Iconify from "./Iconify.vue"; export default { @@ -7,4 +9,4 @@ export default { }, }; -export { Iconify }; +export { Iconify, type IconifyProps }; diff --git a/packages/webpack/src/index.ts b/packages/webpack/src/index.ts index 53499f0..e7b3f50 100644 --- a/packages/webpack/src/index.ts +++ b/packages/webpack/src/index.ts @@ -26,7 +26,6 @@ export class IconifyPlugin { this.name, async (params, callback) => { if (!iconsLoaded) { - console.log("beforeCompile"); await loadIcons(this.options); iconsLoaded = true; }