From c1e084245724f73af87b579a0a117a275d04c081 Mon Sep 17 00:00:00 2001
From: philipp lang <philipp@aweos.de>
Date: Sat, 26 Oct 2024 15:55:22 +0200
Subject: [PATCH] Add vite spritemap

---
 app/View/Ui/Sprite.php |   9 ++-
 package-lock.json      | 167 +++++++++++++++++++++++++++++++++++++++++
 package.json           |   3 +-
 vite.config.js         |   2 +
 4 files changed, 178 insertions(+), 3 deletions(-)

diff --git a/app/View/Ui/Sprite.php b/app/View/Ui/Sprite.php
index 09243864..2130f6ba 100644
--- a/app/View/Ui/Sprite.php
+++ b/app/View/Ui/Sprite.php
@@ -2,20 +2,27 @@
 
 namespace App\View\Ui;
 
+use Illuminate\Support\Facades\Cache;
 use Illuminate\View\Component;
 
 class Sprite extends Component
 {
 
+    public string $spritemapFile;
+
     public function __construct(
         public string $src = '',
     ) {
+        $this->spritemapFile = Cache::rememberForever('spritemap_file', function () {
+            $manifest = json_decode(file_get_contents(public_path('build/manifest.json')), true);
+            return asset('build/' . $manifest['spritemap.svg']['file']);
+        });
     }
 
     public function render()
     {
         return <<<'HTML'
-            <svg {{ $attributes->merge(['class' => 'fill-current']) }}><use xlink:href="/sprite.svg#{{$src}}" /></svg>
+            <svg {{ $attributes->merge(['class' => 'fill-current']) }}><use xlink:href="{{$spritemapFile}}#sprite-{{$src}}" /></svg>
         HTML;
     }
 }
diff --git a/package-lock.json b/package-lock.json
index ee145d8e..a0b1fc01 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,7 @@
                 "@editorjs/paragraph": "^2.11.3",
                 "@inertiajs/vue3": "^1.0.14",
                 "@ryangjchandler/alpine-tooltip": "^2.0.1",
+                "@spiriit/vite-plugin-svg-spritemap": "2.2.4",
                 "@tailwindcss/container-queries": "^0.1.1",
                 "@tailwindcss/forms": "^0.5.7",
                 "@tailwindcss/typography": "^0.5.10",
@@ -1027,6 +1028,167 @@
                 "tippy.js": "^6.3.1"
             }
         },
+        "node_modules/@spiriit/vite-plugin-svg-spritemap": {
+            "version": "2.2.4",
+            "resolved": "https://registry.npmjs.org/@spiriit/vite-plugin-svg-spritemap/-/vite-plugin-svg-spritemap-2.2.4.tgz",
+            "integrity": "sha512-0UQLolc8AaYM8I82Bkz+gS2p9SGEVUn430xEmSA1wf1YlOsSSbbLpuRsC5pEhvUFj80JNZtuiRE6xeAEipE0/g==",
+            "dependencies": {
+                "@xmldom/xmldom": "^0.8.10",
+                "fast-glob": "^3.3.2",
+                "hash-sum": "^2.0.0",
+                "mini-svg-data-uri": "^1.4.4",
+                "svgo": "^3.2.0"
+            },
+            "engines": {
+                "node": "^14.18.0 || >=16.0.0"
+            },
+            "peerDependencies": {
+                "vite": "^4.0.0 || ^5.0.0",
+                "vue": "^3.0.0"
+            },
+            "peerDependenciesMeta": {
+                "vue": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@spiriit/vite-plugin-svg-spritemap/node_modules/css-select": {
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+            "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+            "dependencies": {
+                "boolbase": "^1.0.0",
+                "css-what": "^6.1.0",
+                "domhandler": "^5.0.2",
+                "domutils": "^3.0.1",
+                "nth-check": "^2.0.1"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/fb55"
+            }
+        },
+        "node_modules/@spiriit/vite-plugin-svg-spritemap/node_modules/css-tree": {
+            "version": "2.3.1",
+            "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
+            "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
+            "dependencies": {
+                "mdn-data": "2.0.30",
+                "source-map-js": "^1.0.1"
+            },
+            "engines": {
+                "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+            }
+        },
+        "node_modules/@spiriit/vite-plugin-svg-spritemap/node_modules/csso": {
+            "version": "5.0.5",
+            "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
+            "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
+            "dependencies": {
+                "css-tree": "~2.2.0"
+            },
+            "engines": {
+                "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
+                "npm": ">=7.0.0"
+            }
+        },
+        "node_modules/@spiriit/vite-plugin-svg-spritemap/node_modules/csso/node_modules/css-tree": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
+            "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
+            "dependencies": {
+                "mdn-data": "2.0.28",
+                "source-map-js": "^1.0.1"
+            },
+            "engines": {
+                "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
+                "npm": ">=7.0.0"
+            }
+        },
+        "node_modules/@spiriit/vite-plugin-svg-spritemap/node_modules/csso/node_modules/mdn-data": {
+            "version": "2.0.28",
+            "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
+            "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="
+        },
+        "node_modules/@spiriit/vite-plugin-svg-spritemap/node_modules/dom-serializer": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+            "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+            "dependencies": {
+                "domelementtype": "^2.3.0",
+                "domhandler": "^5.0.2",
+                "entities": "^4.2.0"
+            },
+            "funding": {
+                "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+            }
+        },
+        "node_modules/@spiriit/vite-plugin-svg-spritemap/node_modules/domhandler": {
+            "version": "5.0.3",
+            "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+            "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+            "dependencies": {
+                "domelementtype": "^2.3.0"
+            },
+            "engines": {
+                "node": ">= 4"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/domhandler?sponsor=1"
+            }
+        },
+        "node_modules/@spiriit/vite-plugin-svg-spritemap/node_modules/domutils": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
+            "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
+            "dependencies": {
+                "dom-serializer": "^2.0.0",
+                "domelementtype": "^2.3.0",
+                "domhandler": "^5.0.3"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/domutils?sponsor=1"
+            }
+        },
+        "node_modules/@spiriit/vite-plugin-svg-spritemap/node_modules/entities": {
+            "version": "4.5.0",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+            "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+            "engines": {
+                "node": ">=0.12"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/entities?sponsor=1"
+            }
+        },
+        "node_modules/@spiriit/vite-plugin-svg-spritemap/node_modules/mdn-data": {
+            "version": "2.0.30",
+            "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
+            "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="
+        },
+        "node_modules/@spiriit/vite-plugin-svg-spritemap/node_modules/svgo": {
+            "version": "3.3.2",
+            "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz",
+            "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==",
+            "dependencies": {
+                "@trysound/sax": "0.2.0",
+                "commander": "^7.2.0",
+                "css-select": "^5.1.0",
+                "css-tree": "^2.3.1",
+                "css-what": "^6.1.0",
+                "csso": "^5.0.5",
+                "picocolors": "^1.0.0"
+            },
+            "bin": {
+                "svgo": "bin/svgo"
+            },
+            "engines": {
+                "node": ">=14.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/svgo"
+            }
+        },
         "node_modules/@tailwindcss/container-queries": {
             "version": "0.1.1",
             "resolved": "https://registry.npmjs.org/@tailwindcss/container-queries/-/container-queries-0.1.1.tgz",
@@ -2651,6 +2813,11 @@
                 "url": "https://github.com/sponsors/ljharb"
             }
         },
+        "node_modules/hash-sum": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz",
+            "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg=="
+        },
         "node_modules/hasown": {
             "version": "2.0.2",
             "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
diff --git a/package.json b/package.json
index 5a6b244a..b0e0baaf 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,6 @@
         "hot": "npx vite",
         "prod": "npx vite build",
         "production": "npm run prod",
-        "img": "cd resources/img/svg && npx svg-sprite -s --symbol-dest=sprite *.svg && mv sprite/svg/sprite.css.svg ../../../public/sprite.svg && rm -R sprite",
         "lint": "eslint \"resources/js/**/*.{js,vue}\"",
         "fix": "eslint \"resources/js/**/*.{js,vue}\" --fix"
     },
@@ -30,6 +29,7 @@
         "@editorjs/paragraph": "^2.11.3",
         "@inertiajs/vue3": "^1.0.14",
         "@ryangjchandler/alpine-tooltip": "^2.0.1",
+        "@spiriit/vite-plugin-svg-spritemap": "2.2.4",
         "@tailwindcss/container-queries": "^0.1.1",
         "@tailwindcss/forms": "^0.5.7",
         "@tailwindcss/typography": "^0.5.10",
@@ -47,7 +47,6 @@
         "postcss-import": "^14.1.0",
         "prettier": "^2.8.8",
         "pusher-js": "^8.3.0",
-        "svg-sprite": "^2.0.2",
         "tippy.js": "^6.3.7",
         "toastify-js": "^1.12.0",
         "vite": "^4.5.2",
diff --git a/vite.config.js b/vite.config.js
index b77ca7e3..cb2e4a65 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -2,6 +2,7 @@ import {defineConfig} from 'vite';
 import laravel from 'laravel-vite-plugin';
 import vue from '@vitejs/plugin-vue';
 import path from 'path';
+import VitePluginSvgSpritemap from '@spiriit/vite-plugin-svg-spritemap';
 
 export default defineConfig({
     plugins: [
@@ -27,6 +28,7 @@ export default defineConfig({
                 },
             },
         }),
+        VitePluginSvgSpritemap('./resources/img/svg/*.svg'),
     ],
     resolve: {
         alias: {