diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index 8c746e27..e4a3299b 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -80,7 +80,7 @@ module.exports = {
'import/no-relative-parent-imports': [
'error',
{
- ignore: ['#[src,types,root,components,utils]/*'],
+ ignore: ['#[src,types,root,components,utils,assets]/*'],
},
],
'import/no-self-import': 'error',
diff --git a/package-lock.json b/package-lock.json
index d6ad1280..3f3684c4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "utopia-ui",
- "version": "3.0.60",
+ "version": "3.0.64",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "utopia-ui",
- "version": "3.0.60",
+ "version": "3.0.64",
"license": "GPL-3.0-only",
"dependencies": {
"@heroicons/react": "^2.0.17",
@@ -70,12 +70,14 @@
"rollup": "^4.34.6",
"rollup-plugin-dts": "^6.1.1",
"rollup-plugin-postcss": "^4.0.2",
+ "rollup-plugin-svg": "^2.0.0",
"tailwindcss": "^3.3.1",
"typedoc": "^0.27.6",
"typedoc-plugin-coverage": "^3.4.1",
"typedoc-plugin-missing-exports": "^3.1.0",
"typescript": "^5.7.3",
"vite": "^6.0.11",
+ "vite-plugin-svgr": "^4.3.0",
"vitest": "^3.0.5"
},
"peerDependencies": {
@@ -1718,6 +1720,244 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@svgr/babel-plugin-add-jsx-attribute": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
+ "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-remove-jsx-attribute": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz",
+ "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz",
+ "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz",
+ "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-svg-dynamic-title": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz",
+ "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-svg-em-dimensions": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz",
+ "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-transform-react-native-svg": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz",
+ "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-transform-svg-component": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz",
+ "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-preset": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz",
+ "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@svgr/babel-plugin-add-jsx-attribute": "8.0.0",
+ "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0",
+ "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0",
+ "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0",
+ "@svgr/babel-plugin-svg-dynamic-title": "8.0.0",
+ "@svgr/babel-plugin-svg-em-dimensions": "8.0.0",
+ "@svgr/babel-plugin-transform-react-native-svg": "8.1.0",
+ "@svgr/babel-plugin-transform-svg-component": "8.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/core": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz",
+ "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.21.3",
+ "@svgr/babel-preset": "8.1.0",
+ "camelcase": "^6.2.0",
+ "cosmiconfig": "^8.1.3",
+ "snake-case": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ }
+ },
+ "node_modules/@svgr/hast-util-to-babel-ast": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz",
+ "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.21.3",
+ "entities": "^4.4.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ }
+ },
+ "node_modules/@svgr/hast-util-to-babel-ast/node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/@svgr/plugin-jsx": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz",
+ "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.21.3",
+ "@svgr/babel-preset": "8.1.0",
+ "@svgr/hast-util-to-babel-ast": "8.0.0",
+ "svg-parser": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@svgr/core": "*"
+ }
+ },
"node_modules/@tanstack/query-core": {
"version": "5.66.4",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.66.4.tgz",
@@ -3221,6 +3461,19 @@
"node": ">=6"
}
},
+ "node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/camelcase-css": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
@@ -3612,6 +3865,33 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/cosmiconfig": {
+ "version": "8.3.6",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
+ "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "import-fresh": "^3.3.0",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.2.0",
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/d-fischer"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -4260,6 +4540,17 @@
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
+ "node_modules/dot-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
+ "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@@ -4352,6 +4643,16 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
"node_modules/es-abstract": {
"version": "1.23.9",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz",
@@ -6405,6 +6706,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/is-async-function": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
@@ -7069,6 +7377,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/json-schema": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
@@ -7436,6 +7751,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/lower-case": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
+ "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.3"
+ }
+ },
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -8356,6 +8681,17 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/no-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
+ "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lower-case": "^2.0.2",
+ "tslib": "^2.0.3"
+ }
+ },
"node_modules/node-releases": {
"version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
@@ -8752,6 +9088,25 @@
"integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
"license": "MIT"
},
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -10356,6 +10711,34 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/rollup-plugin-svg": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-svg/-/rollup-plugin-svg-2.0.0.tgz",
+ "integrity": "sha512-DmE7dSQHo1SC5L2uH2qul3Mjyd5oV6U1aVVkyvTLX/mUsRink7f1b1zaIm+32GEBA6EHu8H/JJi3DdWqM53ySQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "rollup-pluginutils": "^1.3.1"
+ }
+ },
+ "node_modules/rollup-plugin-svg/node_modules/estree-walker": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.2.1.tgz",
+ "integrity": "sha512-6/I1dwNKk0N9iGOU3ydzAAurz4NPo/ttxZNCqgIVbWFvWyzWBSNonRrJ5CpjDuyBfmM7ENN7WCzUi9aT/UPXXQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rollup-plugin-svg/node_modules/rollup-pluginutils": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz",
+ "integrity": "sha512-SjdWWWO/CUoMpDy8RUbZ/pSpG68YHmhk5ROKNIoi2En9bJ8bTt3IhYi254RWiTclQmL7Awmrq+rZFOhZkJAHmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "estree-walker": "^0.2.1",
+ "minimatch": "^3.0.2"
+ }
+ },
"node_modules/rollup-pluginutils": {
"version": "2.8.2",
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
@@ -10713,6 +11096,17 @@
"node": ">=8"
}
},
+ "node_modules/snake-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
+ "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dot-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -11149,6 +11543,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/svg-parser": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz",
+ "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/svgo": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
@@ -12246,6 +12647,21 @@
"url": "https://opencollective.com/vitest"
}
},
+ "node_modules/vite-plugin-svgr": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.3.0.tgz",
+ "integrity": "sha512-Jy9qLB2/PyWklpYy0xk0UU3TlU0t2UMpJXZvf+hWII1lAmRHrOUKi11Uw8N3rxoNk7atZNYO3pR3vI1f7oi+6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.1.3",
+ "@svgr/core": "^8.1.0",
+ "@svgr/plugin-jsx": "^8.1.0"
+ },
+ "peerDependencies": {
+ "vite": ">=2.6.0"
+ }
+ },
"node_modules/vitest": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.5.tgz",
diff --git a/package.json b/package.json
index f7ee70b5..a230b773 100644
--- a/package.json
+++ b/package.json
@@ -75,12 +75,14 @@
"rollup": "^4.34.6",
"rollup-plugin-dts": "^6.1.1",
"rollup-plugin-postcss": "^4.0.2",
+ "rollup-plugin-svg": "^2.0.0",
"tailwindcss": "^3.3.1",
"typedoc": "^0.27.6",
"typedoc-plugin-coverage": "^3.4.1",
"typedoc-plugin-missing-exports": "^3.1.0",
"typescript": "^5.7.3",
"vite": "^6.0.11",
+ "vite-plugin-svgr": "^4.3.0",
"vitest": "^3.0.5"
},
"peerDependencies": {
@@ -108,6 +110,7 @@
"yet-another-react-lightbox": "^3.21.7"
},
"imports": {
+ "#assets/*": "./src/assets/*",
"#components/*": "./src/Components/*",
"#utils/*": "./src/Utils/*",
"#types/*": "./src/types/*",
diff --git a/rollup.config.js b/rollup.config.js
index 0370b6cc..33893a11 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -6,6 +6,7 @@ import resolve from '@rollup/plugin-node-resolve'
import typescript from '@rollup/plugin-typescript'
import { dts } from 'rollup-plugin-dts'
import postcss from 'rollup-plugin-postcss'
+import svg from 'rollup-plugin-svg'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
@@ -40,6 +41,7 @@ export default [
typescript({
tsconfig: './tsconfig.json',
}),
+ svg({ base64: true }),
],
external: [
'react',
@@ -87,5 +89,6 @@ export default [
}),
],
external: [/\.css$/], //, /\.d\.ts$/
+ watch: false,
},
]
diff --git a/src/Components/AppShell/Content.tsx b/src/Components/AppShell/Content.tsx
index 42dfbf5f..9adaf028 100644
--- a/src/Components/AppShell/Content.tsx
+++ b/src/Components/AppShell/Content.tsx
@@ -1,5 +1,4 @@
-/* eslint-disable @typescript-eslint/consistent-type-definitions */
-type ContentProps = {
+interface ContentProps {
children?: React.ReactNode
}
diff --git a/src/Components/AppShell/ContextWrapper.tsx b/src/Components/AppShell/ContextWrapper.tsx
index cde23c2d..ece603ad 100644
--- a/src/Components/AppShell/ContextWrapper.tsx
+++ b/src/Components/AppShell/ContextWrapper.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable @typescript-eslint/no-unsafe-return */
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { useContext, createContext } from 'react'
import { BrowserRouter as Router, useLocation } from 'react-router-dom'
@@ -19,8 +18,7 @@ import { AppStateProvider } from './hooks/useAppState'
// Helper context to determine if the ContextWrapper is already present.
const ContextCheckContext = createContext(false)
-// eslint-disable-next-line react/prop-types
-export const ContextWrapper = ({ children }) => {
+export const ContextWrapper = ({ children }: { children: React.ReactNode }) => {
const isWrapped = useContext(ContextCheckContext)
// Check if we are already inside a Router
diff --git a/src/Components/AppShell/NavBar.tsx b/src/Components/AppShell/NavBar.tsx
index 4c038d25..10b717b9 100644
--- a/src/Components/AppShell/NavBar.tsx
+++ b/src/Components/AppShell/NavBar.tsx
@@ -1,3 +1,5 @@
+import Bars3Icon from '@heroicons/react/16/solid/Bars3Icon'
+import EllipsisVerticalIcon from '@heroicons/react/16/solid/EllipsisVerticalIcon'
import QuestionMarkIcon from '@heroicons/react/24/outline/QuestionMarkCircleIcon'
import { useEffect, useRef, useState } from 'react'
import { Link, useLocation } from 'react-router-dom'
@@ -68,19 +70,7 @@ export default function NavBar({ appName }: { appName: string }) {
aria-controls='#sidenav'
aria-haspopup='true'
>
-
+
Level 1
-
+
-
diff --git a/src/Components/Gaming/hooks/useQuests.tsx b/src/Components/Gaming/hooks/useQuests.tsx
index 336d7a8f..1b3cc1d4 100644
--- a/src/Components/Gaming/hooks/useQuests.tsx
+++ b/src/Components/Gaming/hooks/useQuests.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable react/prop-types */
/* eslint-disable @typescript-eslint/no-empty-function */
import { useCallback, useState, createContext, useContext } from 'react'
@@ -22,10 +21,15 @@ function useQuestsManager(initialOpen: boolean): {
return { open, setQuestsOpen }
}
-export const QuestsProvider: React.FunctionComponent<{
+interface QuestProviderProps {
initialOpen: boolean
children?: React.ReactNode
-}> = ({ initialOpen, children }) => (
+}
+
+export const QuestsProvider: React.FunctionComponent = ({
+ initialOpen,
+ children,
+}: QuestProviderProps) => (
{children}
)
diff --git a/src/Components/Input/SelectBox.tsx b/src/Components/Input/SelectBox.tsx
index c4d4282e..f91ed194 100644
--- a/src/Components/Input/SelectBox.tsx
+++ b/src/Components/Input/SelectBox.tsx
@@ -1,9 +1,7 @@
-/* eslint-disable @typescript-eslint/consistent-type-definitions */
-/* eslint-disable @typescript-eslint/restrict-template-expressions */
import InformationCircleIcon from '@heroicons/react/24/outline/InformationCircleIcon'
import { useState } from 'react'
-type SelectBoxProps = {
+interface SelectBoxProps {
labelTitle?: string
labelStyle?: string
type?: string
@@ -40,9 +38,9 @@ export function SelectBox(props: SelectBoxProps) {
}
return (
-
+
{labelTitle ? (
-
diff --git a/src/Components/Map/Subcomponents/Controls/LocateControl.tsx b/src/Components/Map/Subcomponents/Controls/LocateControl.tsx
index 6bd649ec..3380f6bc 100644
--- a/src/Components/Map/Subcomponents/Controls/LocateControl.tsx
+++ b/src/Components/Map/Subcomponents/Controls/LocateControl.tsx
@@ -7,6 +7,9 @@
import { control } from 'leaflet'
import { useEffect, useRef, useState } from 'react'
import { useMap, useMapEvents } from 'react-leaflet'
+
+import TargetSVG from '#assets/target.svg'
+
// eslint-disable-next-line import/no-unassigned-import
import 'leaflet.locatecontrol'
import 'leaflet.locatecontrol/dist/L.Control.Locate.css'
@@ -56,15 +59,12 @@ export const LocateControl = () => {
{loading ? (
) : (
-
+ style={{ fill: `${active ? '#fc8702' : 'currentColor'}` }}
+ />
)}
diff --git a/src/Components/Map/Subcomponents/Controls/QuestControl.tsx b/src/Components/Map/Subcomponents/Controls/QuestControl.tsx
index 1ebd60c2..cbc2e859 100644
--- a/src/Components/Map/Subcomponents/Controls/QuestControl.tsx
+++ b/src/Components/Map/Subcomponents/Controls/QuestControl.tsx
@@ -1,3 +1,4 @@
+import FistSVG from '#assets/fist.svg'
import { useQuestsOpen, useSetQuestOpen } from '#components/Gaming/hooks/useQuests'
export function QuestControl() {
@@ -17,14 +18,7 @@ export function QuestControl() {
className='tw-card-body hover:tw-bg-slate-300 tw-rounded-2xl tw-p-2 tw-h-10 tw-w-10 tw-transition-all tw-duration-300 hover:tw-cursor-pointer'
onClick={() => setQuestsOpen(true)}
>
-
+
)}
diff --git a/src/Components/Map/Subcomponents/Controls/SearchControl.tsx b/src/Components/Map/Subcomponents/Controls/SearchControl.tsx
index e197ea03..a267019e 100644
--- a/src/Components/Map/Subcomponents/Controls/SearchControl.tsx
+++ b/src/Components/Map/Subcomponents/Controls/SearchControl.tsx
@@ -10,6 +10,8 @@
/* eslint-disable @typescript-eslint/restrict-plus-operands */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-call */
+import FlagIcon from '@heroicons/react/24/outline/FlagIcon'
+import MagnifyingGlassIcon from '@heroicons/react/24/outline/MagnifyingGlassIcon'
import axios from 'axios'
import { LatLng, LatLngBounds, marker } from 'leaflet'
import { useEffect, useRef, useState } from 'react'
@@ -234,21 +236,7 @@ export const SearchControl = () => {
hide()
}}
>
-
-
+
{geo?.properties.name ? geo?.properties.name : value}
@@ -295,21 +283,7 @@ export const SearchControl = () => {
)
}}
>
-
-
+
{value}
diff --git a/src/Components/Map/Subcomponents/Controls/SidebarControl.tsx b/src/Components/Map/Subcomponents/Controls/SidebarControl.tsx
index 76f27776..6172a78c 100644
--- a/src/Components/Map/Subcomponents/Controls/SidebarControl.tsx
+++ b/src/Components/Map/Subcomponents/Controls/SidebarControl.tsx
@@ -1,3 +1,5 @@
+import Bars3Icon from '@heroicons/react/16/solid/Bars3Icon'
+
// Converts leaflet.locatecontrol to a React Component
export const SidebarControl = () => {
return (
@@ -11,19 +13,7 @@ export const SidebarControl = () => {
aria-controls='#sidenav'
aria-haspopup='true'
>
-
+
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx
index 96fec05f..835da429 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx
@@ -9,9 +9,13 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+import EllipsisVerticalIcon from '@heroicons/react/16/solid/EllipsisVerticalIcon'
+import PencilIcon from '@heroicons/react/24/solid/PencilIcon'
+import TrashIcon from '@heroicons/react/24/solid/TrashIcon'
import { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
+import TargetDotSVG from '#assets/targetDot.svg'
import { useAppState } from '#components/AppShell/hooks/useAppState'
import { useHasUserPermission } from '#components/Map/hooks/usePermissions'
import DialogModal from '#components/Templates/DialogModal'
@@ -127,14 +131,7 @@ export function HeaderView({
tabIndex={0}
className='tw-bg-base-100 tw-btn tw-m-1 tw-leading-3 tw-border-none tw-min-h-0 tw-h-6'
>
-
+
-
+
)}
@@ -173,16 +163,7 @@ export function HeaderView({
className='!tw-text-base-content tw-cursor-pointer'
onClick={setPositionCallback}
>
-
+
)}
@@ -194,18 +175,7 @@ export function HeaderView({
{loading ? (
) : (
-
+
)}
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx
index eaf2c56c..23c3c385 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx
@@ -1,4 +1,6 @@
/* eslint-disable @typescript-eslint/prefer-optional-chain */
+import CalendarIcon from '@heroicons/react/24/solid/CalendarDaysIcon'
+
import type { Item } from '#types/Item'
/**
@@ -8,20 +10,7 @@ export const StartEndView = ({ item }: { item?: Item }) => {
return (
-
+
diff --git a/src/Components/Profile/Subcomponents/AvatarWidget.tsx b/src/Components/Profile/Subcomponents/AvatarWidget.tsx
index b67c2c52..94d1e1f4 100644
--- a/src/Components/Profile/Subcomponents/AvatarWidget.tsx
+++ b/src/Components/Profile/Subcomponents/AvatarWidget.tsx
@@ -2,9 +2,11 @@
/* eslint-disable @typescript-eslint/no-floating-promises */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/prefer-optional-chain */
+import ArrowUpTrayIcon from '@heroicons/react/24/outline/ArrowUpTrayIcon'
import { useState, useCallback, useRef } from 'react'
import { ReactCrop, centerCrop, makeAspectCrop } from 'react-image-crop'
+import UserSVG from '#assets/user.svg'
import { useAppState } from '#components/AppShell/hooks/useAppState'
import 'react-image-crop/dist/ReactCrop.css'
import DialogModal from '#components/Templates/DialogModal'
@@ -169,20 +171,7 @@ export const AvatarWidget: React.FC
= ({ avatar, setAvatar })
onChange={onImageChange}
/>
{avatar ? (
@@ -193,22 +182,7 @@ export const AvatarWidget: React.FC
= ({ avatar, setAvatar })
) : (
-
+
)}
diff --git a/src/Components/Profile/Subcomponents/ContactInfoView.tsx b/src/Components/Profile/Subcomponents/ContactInfoView.tsx
index 3c11e641..dbf0af25 100644
--- a/src/Components/Profile/Subcomponents/ContactInfoView.tsx
+++ b/src/Components/Profile/Subcomponents/ContactInfoView.tsx
@@ -2,6 +2,8 @@
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/restrict-plus-operands */
+import EnvelopeIcon from '@heroicons/react/24/outline/EnvelopeIcon'
+import PhoneIcon from '@heroicons/react/24/outline/PhoneIcon'
import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
@@ -48,19 +50,7 @@ export const ContactInfoView = ({ item, heading }: { item: Item; heading: string
href={`mailto:${item.contact}`}
className='tw-mt-2 tw-text-green-500 tw-inline-flex tw-items-center'
>
-
+
{item.contact}
@@ -71,18 +61,7 @@ export const ContactInfoView = ({ item, heading }: { item: Item; heading: string
href={`tel:${item.telephone}`}
className='tw-mt-2 tw-text-green-500 tw-inline-flex tw-items-center tw-whitespace-nowrap'
>
-
+
{item.telephone}
diff --git a/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx b/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx
index 6c205aa7..cc298dc6 100644
--- a/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx
+++ b/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx
@@ -5,6 +5,8 @@
/* eslint-disable @typescript-eslint/restrict-plus-operands */
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
+import EllipsisVerticalIcon from '@heroicons/react/16/solid/EllipsisVerticalIcon'
+import LinkSlashIcon from '@heroicons/react/24/outline/LinkSlashIcon'
import { useEffect } from 'react'
import { useAppState } from '#components/AppShell/hooks/useAppState'
@@ -57,14 +59,7 @@ export function LinkedItemsHeaderView({
tabIndex={0}
className=' tw-btn tw-m-1 tw-leading-3 tw-border-none tw-min-h-0 tw-h-6'
>
-
+
) : (
-
+
)}
diff --git a/src/Components/Profile/Subcomponents/MarkdownHint.tsx b/src/Components/Profile/Subcomponents/MarkdownHint.tsx
index 1b79bbc3..bf8c8b37 100644
--- a/src/Components/Profile/Subcomponents/MarkdownHint.tsx
+++ b/src/Components/Profile/Subcomponents/MarkdownHint.tsx
@@ -1,5 +1,7 @@
import { useState } from 'react'
+import MarkdownSVG from '#assets/markdown.svg'
+
export const MarkdownHint = () => {
const [expended, setExpended] = useState(false)
return (
@@ -8,18 +10,7 @@ export const MarkdownHint = () => {
title='Markdown is supported'
className='flex tw-flex-row tw-text-gray-400 tw-cursor-pointer tw-items-center'
>
-
+
{expended && (
-
+
)}
diff --git a/src/Components/Profile/Subcomponents/ProfileTextView.tsx b/src/Components/Profile/Subcomponents/ProfileTextView.tsx
index 9fc35bbb..f2f1d283 100644
--- a/src/Components/Profile/Subcomponents/ProfileTextView.tsx
+++ b/src/Components/Profile/Subcomponents/ProfileTextView.tsx
@@ -17,9 +17,7 @@ export const ProfileTextView = ({
}) => {
const text = get(item, dataField)
- if (typeof text !== 'string') {
- throw new Error('ProfileTextView: text is not a string')
- }
+ const parsedText = typeof text !== 'string' ? '' : text
return (
@@ -27,7 +25,7 @@ export const ProfileTextView = ({
{heading}
)}
-
+
)
diff --git a/src/Components/Profile/Subcomponents/SocialShareBar.tsx b/src/Components/Profile/Subcomponents/SocialShareBar.tsx
index 150fde40..4c23fe88 100644
--- a/src/Components/Profile/Subcomponents/SocialShareBar.tsx
+++ b/src/Components/Profile/Subcomponents/SocialShareBar.tsx
@@ -1,5 +1,8 @@
import { toast } from 'react-toastify'
+import ChevronSVG from '#assets/chevron.svg'
+import ClipboardSVG from '#assets/share/clipboard.svg'
+
import SocialShareButton from './SocialShareButton'
const SocialShareBar = ({
@@ -41,14 +44,7 @@ const SocialShareBar = ({
onClick={() => copyLink()}
title='share link via email'
>
-
+
)}
{platforms.includes('clipboard') && (
@@ -62,17 +58,7 @@ const SocialShareBar = ({
onClick={() => copyLink()}
title='copy Link'
>
-
+
)}
diff --git a/src/Components/Profile/Subcomponents/SocialShareButton.tsx b/src/Components/Profile/Subcomponents/SocialShareButton.tsx
index 64f0858a..93f5dbde 100644
--- a/src/Components/Profile/Subcomponents/SocialShareButton.tsx
+++ b/src/Components/Profile/Subcomponents/SocialShareButton.tsx
@@ -5,72 +5,42 @@
import { cloneElement } from 'react'
+import FacebookSVG from '#assets/share/facebook.svg'
+import LinkedinSVG from '#assets/share/linkedin.svg'
+import TelegramSVG from '#assets/share/telegram.svg'
+import TwitterSVG from '#assets/share/twitter.svg'
+import WhatsappSVG from '#assets/share/whatsapp.svg'
+import XingSVG from '#assets/share/xing.svg'
+
const platformConfigs = {
facebook: {
shareUrl: 'https://www.facebook.com/sharer/sharer.php?u={url}',
- icon: (
-
- ),
+ icon:

,
bgColor: '#3b5998',
},
twitter: {
shareUrl: 'https://twitter.com/intent/tweet?text={title}:%20{url}',
- icon: (
-
- ),
+ icon:

,
bgColor: '#55acee',
},
linkedin: {
shareUrl: 'http://www.linkedin.com/shareArticle?mini=true&url={url}&title={title}',
- icon: (
-
- ),
+ icon:

,
bgColor: '#4875b4',
},
xing: {
shareUrl: 'https://www.xing-share.com/app/user?op=share;sc_p=xing-share;url={url}',
- icon: (
-
- ),
+ icon:

,
bgColor: '#026466',
},
whatsapp: {
shareUrl: 'https://api.whatsapp.com/send?text={title}%20{url}',
- icon: (
-
- ),
+ icon:

,
bgColor: '#25D366',
},
telegram: {
shareUrl: 'https://t.me/share/url?url={url}&text={title}',
- icon: (
-
- ),
+ icon:

,
bgColor: '#0088cc',
},
}
diff --git a/src/assets/chevron.svg b/src/assets/chevron.svg
new file mode 100644
index 00000000..fb6f4454
--- /dev/null
+++ b/src/assets/chevron.svg
@@ -0,0 +1,8 @@
+
\ No newline at end of file
diff --git a/src/assets/fist.svg b/src/assets/fist.svg
new file mode 100644
index 00000000..f079abbe
--- /dev/null
+++ b/src/assets/fist.svg
@@ -0,0 +1,8 @@
+
\ No newline at end of file
diff --git a/src/assets/layer.svg b/src/assets/layer.svg
new file mode 100644
index 00000000..a8f5494c
--- /dev/null
+++ b/src/assets/layer.svg
@@ -0,0 +1,13 @@
+
\ No newline at end of file
diff --git a/src/assets/markdown.svg b/src/assets/markdown.svg
new file mode 100644
index 00000000..cd6c28cc
--- /dev/null
+++ b/src/assets/markdown.svg
@@ -0,0 +1,12 @@
+
\ No newline at end of file
diff --git a/src/assets/plus.svg b/src/assets/plus.svg
new file mode 100644
index 00000000..ae77e510
--- /dev/null
+++ b/src/assets/plus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/share/clipboard.svg b/src/assets/share/clipboard.svg
new file mode 100644
index 00000000..75551887
--- /dev/null
+++ b/src/assets/share/clipboard.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/share/facebook.svg b/src/assets/share/facebook.svg
new file mode 100644
index 00000000..f0e46bb1
--- /dev/null
+++ b/src/assets/share/facebook.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/assets/share/linkedin.svg b/src/assets/share/linkedin.svg
new file mode 100644
index 00000000..35382bde
--- /dev/null
+++ b/src/assets/share/linkedin.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/src/assets/share/telegram.svg b/src/assets/share/telegram.svg
new file mode 100644
index 00000000..5926a3fd
--- /dev/null
+++ b/src/assets/share/telegram.svg
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/src/assets/share/twitter.svg b/src/assets/share/twitter.svg
new file mode 100644
index 00000000..16c2fe70
--- /dev/null
+++ b/src/assets/share/twitter.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/assets/share/whatsapp.svg b/src/assets/share/whatsapp.svg
new file mode 100644
index 00000000..0579784e
--- /dev/null
+++ b/src/assets/share/whatsapp.svg
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/src/assets/share/xing.svg b/src/assets/share/xing.svg
new file mode 100644
index 00000000..2fcc6565
--- /dev/null
+++ b/src/assets/share/xing.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/assets/target.svg b/src/assets/target.svg
new file mode 100644
index 00000000..711e071b
--- /dev/null
+++ b/src/assets/target.svg
@@ -0,0 +1,8 @@
+
\ No newline at end of file
diff --git a/src/assets/targetDot.svg b/src/assets/targetDot.svg
new file mode 100644
index 00000000..9ded1a69
--- /dev/null
+++ b/src/assets/targetDot.svg
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/src/assets/user.svg b/src/assets/user.svg
new file mode 100644
index 00000000..4a0573ec
--- /dev/null
+++ b/src/assets/user.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/types/SVG.d.ts b/src/types/SVG.d.ts
new file mode 100644
index 00000000..13d53bd9
--- /dev/null
+++ b/src/types/SVG.d.ts
@@ -0,0 +1,7 @@
+declare module '*.svg' {
+ import type { FunctionComponent, SVGProps } from 'react'
+
+ export const ReactComponent: FunctionComponent
>
+ const src: string
+ export default src
+}
diff --git a/tsconfig.json b/tsconfig.json
index 2a66fedf..ff453fb4 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -20,6 +20,7 @@
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"paths": {
+ "#assets/*": ["./src/assets/*"],
"#components/*": ["./src/Components/*"],
"#utils/*": ["./src/Utils/*"],
"#types/*": ["./src/types/*"],
diff --git a/vite.config.ts b/vite.config.ts
index 415f25db..fd583db2 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,9 +1,10 @@
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'
+import svgr from 'vite-plugin-svgr'
import { configDefaults } from 'vitest/config'
export default defineConfig({
- plugins: [react()],
+ plugins: [react(), svgr()],
test: {
globals: true,
environment: 'happy-dom',
@@ -14,8 +15,8 @@ export default defineConfig({
exclude: [...configDefaults.exclude],
thresholds: {
lines: 0,
- functions: 65,
- branches: 66,
+ functions: 61,
+ branches: 62,
statements: 0,
},
},