diff --git a/README.md b/README.md index d490ae628..89aa97687 100644 --- a/README.md +++ b/README.md @@ -686,6 +686,12 @@ Component test verifies Vue components in `src/components/`. Playwright test verifies the whole app. See for details. +### Custom Icons + +The project supports custom SVG icons through the unplugin-icons system. Custom icons are stored in `src/assets/icons/custom/` and can be used as Vue components with the `i-comfy:` prefix. + +For detailed instructions on adding and using custom icons, see [src/assets/icons/README.md](src/assets/icons/README.md). + ### litegraph.js This repo is using litegraph package hosted on . Any changes to litegraph should be submitted in that repo instead. diff --git a/package-lock.json b/package-lock.json index c62c30977..ee2dda5f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -88,8 +88,8 @@ "tsx": "^4.15.6", "typescript": "^5.4.5", "typescript-eslint": "^8.0.0", - "unplugin-icons": "^0.19.3", - "unplugin-vue-components": "^0.27.4", + "unplugin-icons": "^0.22.0", + "unplugin-vue-components": "^0.28.0", "vite": "^5.4.19", "vite-plugin-dts": "^4.3.0", "vite-plugin-html": "^3.2.2", @@ -441,13 +441,13 @@ } }, "node_modules/@antfu/install-pkg": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.4.1.tgz", - "integrity": "sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.5.0.tgz", + "integrity": "sha512-dKnk2xlAyC7rvTkpkHmu+Qy/2Zc3Vm/l8PtNyIOGDBtXPY3kThfU4ORNEp3V7SXw5XSOb+tOJaUYpfquPzL/Tg==", "dev": true, "dependencies": { - "package-manager-detector": "^0.2.0", - "tinyexec": "^0.3.0" + "package-manager-detector": "^0.2.5", + "tinyexec": "^0.3.1" }, "funding": { "url": "https://github.com/sponsors/antfu" @@ -2329,20 +2329,112 @@ "dev": true }, "node_modules/@iconify/utils": { - "version": "2.1.32", - "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.1.32.tgz", - "integrity": "sha512-LeifFZPPKu28O3AEDpYJNdEbvS4/ojAPyIW+pF/vUpJTYnbTiXUHkCh0bwgFRzKvdpb8H4Fbfd/742++MF4fPQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.3.0.tgz", + "integrity": "sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==", "dev": true, "dependencies": { - "@antfu/install-pkg": "^0.4.0", - "@antfu/utils": "^0.7.10", + "@antfu/install-pkg": "^1.0.0", + "@antfu/utils": "^8.1.0", "@iconify/types": "^2.0.0", - "debug": "^4.3.6", + "debug": "^4.4.0", + "globals": "^15.14.0", "kolorist": "^1.8.0", - "local-pkg": "^0.5.0", - "mlly": "^1.7.1" + "local-pkg": "^1.0.0", + "mlly": "^1.7.4" } }, + "node_modules/@iconify/utils/node_modules/@antfu/install-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", + "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==", + "dev": true, + "dependencies": { + "package-manager-detector": "^1.3.0", + "tinyexec": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@iconify/utils/node_modules/@antfu/utils": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.1.tgz", + "integrity": "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@iconify/utils/node_modules/confbox": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", + "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "dev": true + }, + "node_modules/@iconify/utils/node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@iconify/utils/node_modules/local-pkg": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz", + "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", + "dev": true, + "dependencies": { + "mlly": "^1.7.4", + "pkg-types": "^2.0.1", + "quansync": "^0.2.8" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@iconify/utils/node_modules/package-manager-detector": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.3.0.tgz", + "integrity": "sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==", + "dev": true + }, + "node_modules/@iconify/utils/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true + }, + "node_modules/@iconify/utils/node_modules/pkg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.2.0.tgz", + "integrity": "sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ==", + "dev": true, + "dependencies": { + "confbox": "^0.2.2", + "exsolve": "^1.0.7", + "pathe": "^2.0.3" + } + }, + "node_modules/@iconify/utils/node_modules/tinyexec": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", + "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", + "dev": true + }, "node_modules/@inkjs/ui": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@inkjs/ui/-/ui-1.0.0.tgz", @@ -6572,9 +6664,9 @@ "license": "MIT" }, "node_modules/confbox": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", - "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", "dev": true }, "node_modules/config-chain": { @@ -8293,6 +8385,12 @@ "node": ">= 0.6" } }, + "node_modules/exsolve": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", + "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", + "dev": true + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -9028,11 +9126,10 @@ } }, "node_modules/globals": { - "version": "15.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz", - "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==", + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" }, @@ -10884,13 +10981,13 @@ } }, "node_modules/local-pkg": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", - "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz", + "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", "dev": true, "dependencies": { - "mlly": "^1.4.2", - "pkg-types": "^1.0.3" + "mlly": "^1.7.3", + "pkg-types": "^1.2.1" }, "engines": { "node": ">=14" @@ -12197,17 +12294,23 @@ "dev": true }, "node_modules/mlly": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz", - "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", "dev": true, "dependencies": { - "acorn": "^8.11.3", - "pathe": "^1.1.2", - "pkg-types": "^1.1.1", - "ufo": "^1.5.3" + "acorn": "^8.14.0", + "pathe": "^2.0.1", + "pkg-types": "^1.3.0", + "ufo": "^1.5.4" } }, + "node_modules/mlly/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true + }, "node_modules/mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -12760,10 +12863,13 @@ "dev": true }, "node_modules/package-manager-detector": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.0.tgz", - "integrity": "sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog==", - "dev": true + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz", + "integrity": "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==", + "dev": true, + "dependencies": { + "quansync": "^0.2.7" + } }, "node_modules/pako": { "version": "1.0.11", @@ -13057,16 +13163,22 @@ } }, "node_modules/pkg-types": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.0.tgz", - "integrity": "sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", "dev": true, "dependencies": { - "confbox": "^0.1.7", - "mlly": "^1.7.1", - "pathe": "^1.1.2" + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" } }, + "node_modules/pkg-types/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true + }, "node_modules/playwright": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.52.0.tgz", @@ -13655,6 +13767,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/quansync": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.10.tgz", + "integrity": "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ] + }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -15205,8 +15333,7 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/tinypool": { "version": "1.0.1", @@ -16138,39 +16265,32 @@ } }, "node_modules/unplugin": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.13.1.tgz", - "integrity": "sha512-6Kq1iSSwg7KyjcThRUks9LuqDAKvtnioxbL9iEtB9ctTyBA5OmrB8gZd/d225VJu1w3UpUsKV7eGrvf59J7+VA==", + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.5.tgz", + "integrity": "sha512-RyWSb5AHmGtjjNQ6gIlA67sHOsWpsbWpwDokLwTcejVdOjEkJZh7QKu14J00gDDVSh8kGH4KYC/TNBceXFZhtw==", "dev": true, "dependencies": { - "acorn": "^8.12.1", + "acorn": "^8.14.1", + "picomatch": "^4.0.2", "webpack-virtual-modules": "^0.6.2" }, "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "webpack-sources": "^3" - }, - "peerDependenciesMeta": { - "webpack-sources": { - "optional": true - } + "node": ">=18.12.0" } }, "node_modules/unplugin-icons": { - "version": "0.19.3", - "resolved": "https://registry.npmjs.org/unplugin-icons/-/unplugin-icons-0.19.3.tgz", - "integrity": "sha512-EUegRmsAI6+rrYr0vXjFlIP+lg4fSC4zb62zAZKx8FGXlWAGgEGBCa3JDe27aRAXhistObLPbBPhwa/0jYLFkQ==", + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/unplugin-icons/-/unplugin-icons-0.22.0.tgz", + "integrity": "sha512-CP+iZq5U7doOifer5bcM0jQ9t3Is7EGybIYt3myVxceI8Zuk8EZEpe1NPtJvh7iqMs1VdbK0L41t9+um9VuuLw==", "dev": true, "dependencies": { - "@antfu/install-pkg": "^0.4.1", + "@antfu/install-pkg": "^0.5.0", "@antfu/utils": "^0.7.10", - "@iconify/utils": "^2.1.29", - "debug": "^4.3.6", + "@iconify/utils": "^2.2.0", + "debug": "^4.4.0", "kolorist": "^1.8.0", - "local-pkg": "^0.5.0", - "unplugin": "^1.12.0" + "local-pkg": "^0.5.1", + "unplugin": "^2.1.0" }, "funding": { "url": "https://github.com/sponsors/antfu" @@ -16179,6 +16299,7 @@ "@svgr/core": ">=7.0.0", "@svgx/core": "^1.0.1", "@vue/compiler-sfc": "^3.0.2 || ^2.7.0", + "svelte": "^3.0.0 || ^4.0.0 || ^5.0.0", "vue-template-compiler": "^2.6.12", "vue-template-es2015-compiler": "^1.9.0" }, @@ -16192,6 +16313,9 @@ "@vue/compiler-sfc": { "optional": true }, + "svelte": { + "optional": true + }, "vue-template-compiler": { "optional": true }, @@ -16200,22 +16324,39 @@ } } }, + "node_modules/unplugin-icons/node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/unplugin-vue-components": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/unplugin-vue-components/-/unplugin-vue-components-0.27.4.tgz", - "integrity": "sha512-1XVl5iXG7P1UrOMnaj2ogYa5YTq8aoh5jwDPQhemwO/OrXW+lPQKDXd1hMz15qxQPxgb/XXlbgo3HQ2rLEbmXQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/unplugin-vue-components/-/unplugin-vue-components-0.28.0.tgz", + "integrity": "sha512-jiTGtJ3JsRFBjgvyilfrX7yUoGKScFgbdNw+6p6kEXU+Spf/rhxzgvdfuMcvhCcLmflB/dY3pGQshYBVGOUx7Q==", "dev": true, "dependencies": { "@antfu/utils": "^0.7.10", - "@rollup/pluginutils": "^5.1.0", + "@rollup/pluginutils": "^5.1.4", "chokidar": "^3.6.0", - "debug": "^4.3.6", + "debug": "^4.4.0", "fast-glob": "^3.3.2", - "local-pkg": "^0.5.0", - "magic-string": "^0.30.11", + "local-pkg": "^0.5.1", + "magic-string": "^0.30.15", "minimatch": "^9.0.5", - "mlly": "^1.7.1", - "unplugin": "^1.12.1" + "mlly": "^1.7.3", + "unplugin": "^2.1.0" }, "engines": { "node": ">=14" @@ -16246,6 +16387,23 @@ "balanced-match": "^1.0.0" } }, + "node_modules/unplugin-vue-components/node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/unplugin-vue-components/node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", @@ -16261,6 +16419,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/unplugin/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", diff --git a/package.json b/package.json index cd1a72d94..f91fce258 100644 --- a/package.json +++ b/package.json @@ -63,8 +63,8 @@ "tsx": "^4.15.6", "typescript": "^5.4.5", "typescript-eslint": "^8.0.0", - "unplugin-icons": "^0.19.3", - "unplugin-vue-components": "^0.27.4", + "unplugin-icons": "^0.22.0", + "unplugin-vue-components": "^0.28.0", "vite": "^5.4.19", "vite-plugin-dts": "^4.3.0", "vite-plugin-html": "^3.2.2", diff --git a/src/assets/icons/README.md b/src/assets/icons/README.md new file mode 100644 index 000000000..ce227de35 --- /dev/null +++ b/src/assets/icons/README.md @@ -0,0 +1,184 @@ +# ComfyUI Custom Icons Guide + +This guide explains how to add and use custom SVG icons in the ComfyUI frontend. + +## Overview + +ComfyUI uses a hybrid icon system that supports: +- **PrimeIcons** - Legacy icon library (CSS classes like `pi pi-plus`) +- **Iconify** - Modern icon system with 200,000+ icons +- **Custom Icons** - Your own SVG icons + +Custom icons are powered by [unplugin-icons](https://github.com/unplugin/unplugin-icons) and integrate seamlessly with Vue's component system. + +## Quick Start + +### 1. Add Your SVG Icon + +Place your SVG file in the `custom/` directory: +``` +src/assets/icons/custom/ +└── your-icon.svg +``` + +### 2. Use in Components + +```vue + +``` + +## SVG Requirements + +### File Naming +- Use kebab-case: `workflow-icon.svg`, `node-tree.svg` +- Avoid special characters and spaces +- The filename becomes the icon name + +### SVG Format +```xml + + + +``` + +**Important:** +- Use `viewBox` for proper scaling (24x24 is standard) +- Don't include `width` or `height` attributes +- Use `currentColor` for theme-aware icons +- Keep SVGs optimized and simple + +### Color Theming + +For icons that adapt to the current theme, use `currentColor`: + +```xml + + + + + + + + + +``` + +## Usage Examples + +### Basic Icon +```vue + +``` + +### With Classes +```vue + +``` + +### In Buttons +```vue + +``` + +### Conditional Icons +```vue + +``` + +## Technical Details + +### How It Works + +1. **unplugin-icons** automatically discovers SVG files in `custom/` +2. During build, SVGs are converted to Vue components +3. Components are tree-shaken - only used icons are bundled +4. The `i-` prefix and `comfy:` namespace identify custom icons + +### Configuration + +The icon system is configured in `vite.config.mts`: + +```typescript +Icons({ + compiler: 'vue3', + customCollections: { + 'comfy': FileSystemIconLoader('src/assets/icons/custom'), + } +}) +``` + +### TypeScript Support + +Icons are automatically typed. If TypeScript doesn't recognize a new icon: +1. Restart your dev server +2. Check that the SVG file is valid +3. Ensure the filename follows kebab-case convention + +## Troubleshooting + +### Icon Not Showing +1. **Check filename**: Must be kebab-case without special characters +2. **Restart dev server**: Required after adding new icons +3. **Verify SVG**: Ensure it's valid SVG syntax +4. **Check console**: Look for Vue component resolution errors + +### Icon Wrong Color +- Replace hardcoded colors with `currentColor` +- Use `stroke="currentColor"` for outlines +- Use `fill="currentColor"` for filled shapes + +### Icon Wrong Size +- Remove `width` and `height` from SVG +- Ensure `viewBox` is present +- Use CSS classes for sizing: `class="w-6 h-6"` + +## Best Practices + +1. **Optimize SVGs**: Use tools like [SVGO](https://jakearchibald.github.io/svgomg/) to minimize file size +2. **Consistent viewBox**: Stick to 24x24 or 16x16 for consistency +3. **Semantic names**: Use descriptive names like `workflow-duplicate` not `icon1` +4. **Theme support**: Always use `currentColor` for adaptable icons +5. **Test both themes**: Verify icons look good in light and dark modes + +## Migration from PrimeIcons + +When replacing a PrimeIcon with a custom icon: + +```vue + + +``` + +## Adding Icon Collections + +To add an entire icon set from npm: + +1. Install the icon package +2. Configure in `vite.config.mts` +3. Use with the appropriate prefix + +See the [unplugin-icons documentation](https://github.com/unplugin/unplugin-icons) for details. \ No newline at end of file diff --git a/src/assets/icons/custom/workflow.svg b/src/assets/icons/custom/workflow.svg new file mode 100644 index 000000000..72f90c1a4 --- /dev/null +++ b/src/assets/icons/custom/workflow.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/components/graph/selectionToolbox/ConvertToSubgraphButton.vue b/src/components/graph/selectionToolbox/ConvertToSubgraphButton.vue index c86582a60..e1f6ee08c 100644 --- a/src/components/graph/selectionToolbox/ConvertToSubgraphButton.vue +++ b/src/components/graph/selectionToolbox/ConvertToSubgraphButton.vue @@ -7,9 +7,12 @@ }" severity="secondary" text - icon="pi pi-box" @click="() => commandStore.execute('Comfy.Graph.ConvertToSubgraph')" - /> + > + +