From e9dc3803e487a98d11efa5d4fa4606db8a5c3d8b Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Sat, 1 May 2021 23:38:56 +0300 Subject: [PATCH] Svelte component with API support --- README.md | 2 +- packages/svelte-demo/package-lock.json | 459 ++++++++---------- packages/svelte-demo/package.json | 4 +- packages/svelte-demo/public/global.css | 188 +++++-- packages/svelte-demo/src/App.svelte | 188 ++++--- .../src/demo-components/Checkbox.svelte | 28 ++ .../src/demo-components/Inline.svelte | 33 ++ .../src/demo-components/UsageFull.svelte | 14 + .../demo-components/UsageFullOffline.svelte | 22 + .../src/demo-components/UsageOffline.svelte | 24 + .../{components => samples}/Alignment.svelte | 5 +- .../{components => samples}/ColorStyle.svelte | 6 +- .../src/{components => samples}/Inline.svelte | 2 +- .../src/{components => samples}/Sample.svelte | 3 +- .../src/{components => samples}/Style.svelte | 4 +- .../Transformations.svelte | 5 +- packages/svelte/src/Icon.svelte | 41 +- packages/svelte/src/functions.ts | 439 ++++++++++++++--- packages/svelte/src/iconify.ts | 14 +- packages/svelte/tests/api/10-api-mock.test.js | 40 ++ .../tests/api/20-rendering-from-api.test.js | 153 ++++++ .../tests/api/30-changing-props.test.js | 205 ++++++++ .../tests/api/fixtures/ChangeIcon.svelte | 18 + .../tests/api/fixtures/ChangeProps.svelte | 22 + packages/svelte/tests/api/load.js | 15 + .../svelte/tests/iconify/10-basic.test.js | 32 ++ .../svelte/tests/iconify/10-empty.test.js | 12 + .../tests/iconify/20-attributes.test.js | 79 +++ .../tests/iconify/20-dimensions.test.js | 40 ++ packages/svelte/tests/iconify/20-ids.test.js | 29 ++ .../svelte/tests/iconify/20-inline.test.js | 44 ++ .../tests/iconify/20-transformations.test.js | 159 ++++++ .../svelte/tests/offline/10-empty.test.js | 2 +- 33 files changed, 1845 insertions(+), 486 deletions(-) create mode 100644 packages/svelte-demo/src/demo-components/Checkbox.svelte create mode 100644 packages/svelte-demo/src/demo-components/Inline.svelte create mode 100644 packages/svelte-demo/src/demo-components/UsageFull.svelte create mode 100644 packages/svelte-demo/src/demo-components/UsageFullOffline.svelte create mode 100644 packages/svelte-demo/src/demo-components/UsageOffline.svelte rename packages/svelte-demo/src/{components => samples}/Alignment.svelte (96%) rename packages/svelte-demo/src/{components => samples}/ColorStyle.svelte (77%) rename packages/svelte-demo/src/{components => samples}/Inline.svelte (97%) rename packages/svelte-demo/src/{components => samples}/Sample.svelte (63%) rename packages/svelte-demo/src/{components => samples}/Style.svelte (91%) rename packages/svelte-demo/src/{components => samples}/Transformations.svelte (90%) create mode 100644 packages/svelte/tests/api/10-api-mock.test.js create mode 100644 packages/svelte/tests/api/20-rendering-from-api.test.js create mode 100644 packages/svelte/tests/api/30-changing-props.test.js create mode 100644 packages/svelte/tests/api/fixtures/ChangeIcon.svelte create mode 100644 packages/svelte/tests/api/fixtures/ChangeProps.svelte create mode 100644 packages/svelte/tests/api/load.js create mode 100644 packages/svelte/tests/iconify/10-basic.test.js create mode 100644 packages/svelte/tests/iconify/10-empty.test.js create mode 100644 packages/svelte/tests/iconify/20-attributes.test.js create mode 100644 packages/svelte/tests/iconify/20-dimensions.test.js create mode 100644 packages/svelte/tests/iconify/20-ids.test.js create mode 100644 packages/svelte/tests/iconify/20-inline.test.js create mode 100644 packages/svelte/tests/iconify/20-transformations.test.js diff --git a/README.md b/README.md index 9bd0fb7..97541e7 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ There are several Iconify implementations included in this repository: | [SVG Framework](./packages/iconify/) | HTML | + | + | | [React component](./packages/react/) | React | + | + | | [Vue component](./packages/vue/) | Vue | - | + | -| [Svelte component](./packages/svelte/) | Svelte/Sapper | - | + | +| [Svelte component](./packages/svelte/) | Svelte/Sapper | + | + | Other packages: diff --git a/packages/svelte-demo/package-lock.json b/packages/svelte-demo/package-lock.json index b837deb..267d971 100644 --- a/packages/svelte-demo/package-lock.json +++ b/packages/svelte-demo/package-lock.json @@ -11,8 +11,8 @@ "sirv-cli": "^1.0.8" }, "devDependencies": { - "@iconify-icons/bx": "^1.0.2", - "@iconify-icons/dashicons": "^1.0.0", + "@iconify-icons/mdi-light": "^1.1.0", + "@iconify-icons/uil": "^1.1.1", "@iconify/svelte": "^1.0.3", "@rollup/plugin-commonjs": "^16.0.0", "@rollup/plugin-node-resolve": "^10.0.0", @@ -24,79 +24,53 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "dependencies": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.12.13" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", "dev": true }, "node_modules/@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.14.0", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, - "node_modules/@cyberalien/redundancy": { + "node_modules/@iconify-icons/mdi-light": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@cyberalien/redundancy/-/redundancy-1.1.0.tgz", - "integrity": "sha512-+ZvuwtVXzyxX1CWnP+X5XgDelseU9KSYgmPu3/DSraR7Qyi/vLZwuRRX0sYO24M/gZaChNXRBEK6RHRe3uBndw==", + "resolved": "https://registry.npmjs.org/@iconify-icons/mdi-light/-/mdi-light-1.1.0.tgz", + "integrity": "sha512-pV69tNZO9u0qZFVcy5VFmg7dL+Yq3g8DrkCIMGnW3ukgcYDZG2M2oAKeIxHUCIE/11khAsYlBdrUFglTIcbDxg==", "dev": true }, - "node_modules/@iconify-icons/bx": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@iconify-icons/bx/-/bx-1.1.0.tgz", - "integrity": "sha512-JlCsrgpp4vujb7tDaZtJ/OfeTnsSFyDFSauNO+2ilsHviCb/u3VXbLjdIoDIR5ISGMr0a+W/f0YNOHn3zUqChA==", + "node_modules/@iconify-icons/uil": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@iconify-icons/uil/-/uil-1.1.1.tgz", + "integrity": "sha512-HdSyOZzEPwh2549jpL2YrLkuR4aYRRF47gDRuZcSRRFdgbkmlpGDSSQ1G1PR9E/a3Igg7j9XdIK9HffTFJP0Lg==", "dev": true }, - "node_modules/@iconify-icons/dashicons": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@iconify-icons/dashicons/-/dashicons-1.1.0.tgz", - "integrity": "sha512-l539ceihPtCEm+v5JQjDjkRZ5ULPRJLA1OhSePuqTrBWkWx+H6asXkpM4hOB0cR59ynelsK9htSmrPij/JHnRg==", - "dev": true - }, - "node_modules/@iconify/core": { - "version": "1.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@iconify/core/-/core-1.0.0-rc.3.tgz", - "integrity": "sha512-gCHmASaQbai749xrvvBpJ7eVrnJusLA2Q+aULMGAZkIrU/YRUiXznpfNITozZaIhdOLjzp8CD8s/j2vv5CyNCg==", - "dev": true, - "dependencies": { - "@cyberalien/redundancy": "^1.1.0", - "@iconify/types": "^1.0.5" - } - }, "node_modules/@iconify/svelte": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@iconify/svelte/-/svelte-1.0.3.tgz", - "integrity": "sha512-Exjwm+LDOmueoVRd8hyG7s+8Q/jTh3tFOaaHTy/TCI2/OTkZe02fkHAUeNtlwnr867X6h3dC2ZIt0Ie4epaGhg==", - "dev": true, - "dependencies": { - "@iconify/core": "^1.0.0-rc.2", - "@iconify/types": "^1.0.5" - } - }, - "node_modules/@iconify/types": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@iconify/types/-/types-1.0.6.tgz", - "integrity": "sha512-eG74WPaqjBGnZ3Xy36X4LRDA/ZlhCK6T0zbsAAIYObY2Qija/379iXx+e2wWwEIXS46B62nGaUcuI0MpUnTSrg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@iconify/svelte/-/svelte-1.0.4.tgz", + "integrity": "sha512-Bjr4UMJUsMCra1lpMYIijLZJustalA7FuBldV9B7IsaeKGZ06rcmgeVUYJqrKJ/0bhRg/chcKasLjUlFqWIoMQ==", "dev": true }, "node_modules/@polka/url": { - "version": "1.0.0-next.11", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.11.tgz", - "integrity": "sha512-3NsZsJIA/22P3QUyrEDNA2D133H4j224twJrdipXN38dpnIOzAbUDtOwkcJ5pXmn75w7LSQDjA4tO9dm1XlqlA==" + "version": "1.0.0-next.12", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.12.tgz", + "integrity": "sha512-6RglhutqrGFMO1MNUXp95RBuYIuc8wTnMAV5MUhLmjTOy78ncwOw7RgeQ/HeymkKXRhZd0s2DNrM1rL7unk3MQ==" }, "node_modules/@rollup/plugin-commonjs": { "version": "16.0.0", @@ -169,9 +143,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "14.14.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.13.tgz", - "integrity": "sha512-vbxr0VZ8exFMMAjCW8rJwaya0dMCDyYW2ZRdTyjtrCvJoENMpdUHOT/eTzvgyA5ZnqRZ/sI0NwqAxNHKYokLJQ==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==", "dev": true }, "node_modules/@types/resolve": { @@ -196,9 +170,9 @@ } }, "node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", @@ -208,22 +182,16 @@ "node": ">= 8" } }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "node_modules/binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, "engines": { "node": ">=8" @@ -258,12 +226,15 @@ "dev": true }, "node_modules/builtin-modules": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", - "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", "dev": true, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/chalk": { @@ -281,14 +252,13 @@ } }, "node_modules/chokidar": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", - "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", "dev": true, "dependencies": { "anymatch": "~3.1.1", "braces": "~3.0.2", - "fsevents": "~2.1.2", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", @@ -299,7 +269,7 @@ "node": ">= 8.10.0" }, "optionalDependencies": { - "fsevents": "~2.1.2" + "fsevents": "~2.3.1" } }, "node_modules/color-convert": { @@ -386,9 +356,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "hasInstallScript": true, "optional": true, @@ -434,9 +404,9 @@ } }, "node_modules/glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { "is-glob": "^4.0.1" @@ -495,9 +465,9 @@ } }, "node_modules/is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.3.0.tgz", + "integrity": "sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -601,15 +571,15 @@ } }, "node_modules/livereload": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.1.tgz", - "integrity": "sha512-9g7sua11kkyZNo2hLRCG3LuZZwqexoyEyecSlV8cAsfAVVCZqLzVir6XDqmH0r+Vzgnd5LrdHDMyjtFnJQLAYw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.3.tgz", + "integrity": "sha512-q7Z71n3i4X0R9xthAryBdNGVGAO2R5X+/xXpmKeuPMrteg+W2U8VusTKV3YiJbXZwKsOlFlHe+go6uSNjfxrZw==", "dev": true, "dependencies": { - "chokidar": "^3.3.0", - "livereload-js": "^3.1.0", + "chokidar": "^3.5.0", + "livereload-js": "^3.3.1", "opts": ">= 1.2.0", - "ws": "^6.2.1" + "ws": "^7.4.3" }, "bin": { "livereload": "bin/livereload.js" @@ -619,9 +589,9 @@ } }, "node_modules/livereload-js": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.3.1.tgz", - "integrity": "sha512-CBu1gTEfzVhlOK1WASKAAJ9Qx1fHECTq0SUB67sfxwQssopTyvzqTlgl+c0h9pZ6V+Fzd2rc510ppuNusg9teQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.3.2.tgz", + "integrity": "sha512-w677WnINxFkuixAoUEXOStewzLYGI76XVag+0JWMMEyjJQKs0ibWZMxkTlB96Lm3EjZ7IeOxVziBEbtxVQqQZA==", "dev": true }, "node_modules/local-access": { @@ -648,9 +618,9 @@ "dev": true }, "node_modules/mime": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", - "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", "bin": { "mime": "cli.js" }, @@ -718,9 +688,9 @@ "dev": true }, "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", "dev": true, "engines": { "node": ">=8.6" @@ -757,12 +727,12 @@ "dev": true }, "node_modules/resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "dependencies": { - "is-core-module": "^2.1.0", + "is-core-module": "^2.2.0", "path-parse": "^1.0.6" }, "funding": { @@ -770,13 +740,10 @@ } }, "node_modules/rollup": { - "version": "2.34.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.34.2.tgz", - "integrity": "sha512-mvtQLqu3cNeoctS+kZ09iOPxrc1P1/Bt1z15enuQ5feyKOdM3MJAVFjjsygurDpSWn530xB4AlA83TWIzRstXA==", + "version": "2.46.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.46.0.tgz", + "integrity": "sha512-qPGoUBNl+Z8uNu0z7pD3WPTABWRbcOwIrO/5ccDJzmrtzn0LVf6Lj91+L5CcWhXl6iWf23FQ6m8Jkl2CmN1O7Q==", "dev": true, - "dependencies": { - "fsevents": "~2.1.2" - }, "bin": { "rollup": "dist/bin/rollup" }, @@ -784,7 +751,7 @@ "node": ">=10.0.0" }, "optionalDependencies": { - "fsevents": "~2.1.2" + "fsevents": "~2.3.1" } }, "node_modules/rollup-plugin-livereload": { @@ -893,9 +860,9 @@ } }, "node_modules/sirv": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.10.tgz", - "integrity": "sha512-H5EZCoZaggEUQy8ocKsF7WAToGuZhjJlLvM3XOef46CbdIgbNeQ1p32N1PCuCjkVYwrAVOSMacN6CXXgIzuspg==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.11.tgz", + "integrity": "sha512-SR36i3/LSWja7AJNRBz4fF/Xjpn7lQFI30tZ434dIy+bitLYSP+ZEenHg36i23V2SGEz+kqjksg0uOGZ5LPiqg==", "dependencies": { "@polka/url": "^1.0.0-next.9", "mime": "^2.3.1", @@ -906,9 +873,9 @@ } }, "node_modules/sirv-cli": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/sirv-cli/-/sirv-cli-1.0.10.tgz", - "integrity": "sha512-8mLTRkvzpZXMyUZJ1whf84YHN/mm2r2+j5sU1ZYr5n2jA8VkFItNPk53oysOo+0QxBVp9aUjggkAsQp1d7L3OQ==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/sirv-cli/-/sirv-cli-1.0.11.tgz", + "integrity": "sha512-L8NILoRSBd38VcfFcERYCaVCnWPBLo9G6u/a37UJ8Ysv4DfjizMbFBcM+SswNnndJienhR6qy8KFuAEaeL4g8Q==", "dependencies": { "console-clear": "^1.1.0", "get-port": "^3.2.0", @@ -916,7 +883,7 @@ "local-access": "^1.0.1", "sade": "^1.6.0", "semiver": "^1.0.0", - "sirv": "^1.0.10", + "sirv": "^1.0.11", "tinydate": "^1.0.0" }, "bin": { @@ -973,18 +940,18 @@ } }, "node_modules/svelte": { - "version": "3.31.0", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.31.0.tgz", - "integrity": "sha512-r+n8UJkDqoQm1b+3tA3Lh6mHXKpcfOSOuEuIo5gE2W9wQYi64RYX/qE6CZBDDsP/H4M+N426JwY7XGH4xASvGQ==", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.38.1.tgz", + "integrity": "sha512-N3XLAyfzqrFxwRLevBeW7Dke9ZlHRVGSIed5abo4Drvj+zvd2OyWpFa1x4nQUc8Lnvt4Kcn8/5le1peRDybNqg==", "dev": true, "engines": { "node": ">= 8" } }, "node_modules/terser": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.5.1.tgz", - "integrity": "sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.0.tgz", + "integrity": "sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g==", "dev": true, "dependencies": { "commander": "^2.20.0", @@ -1033,90 +1000,76 @@ "dev": true }, "node_modules/ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", "dev": true, - "dependencies": { - "async-limiter": "~1.0.0" + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } } }, "dependencies": { "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.12.13" } }, "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", "dev": true }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.14.0", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, - "@cyberalien/redundancy": { + "@iconify-icons/mdi-light": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@cyberalien/redundancy/-/redundancy-1.1.0.tgz", - "integrity": "sha512-+ZvuwtVXzyxX1CWnP+X5XgDelseU9KSYgmPu3/DSraR7Qyi/vLZwuRRX0sYO24M/gZaChNXRBEK6RHRe3uBndw==", + "resolved": "https://registry.npmjs.org/@iconify-icons/mdi-light/-/mdi-light-1.1.0.tgz", + "integrity": "sha512-pV69tNZO9u0qZFVcy5VFmg7dL+Yq3g8DrkCIMGnW3ukgcYDZG2M2oAKeIxHUCIE/11khAsYlBdrUFglTIcbDxg==", "dev": true }, - "@iconify-icons/bx": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@iconify-icons/bx/-/bx-1.1.0.tgz", - "integrity": "sha512-JlCsrgpp4vujb7tDaZtJ/OfeTnsSFyDFSauNO+2ilsHviCb/u3VXbLjdIoDIR5ISGMr0a+W/f0YNOHn3zUqChA==", + "@iconify-icons/uil": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@iconify-icons/uil/-/uil-1.1.1.tgz", + "integrity": "sha512-HdSyOZzEPwh2549jpL2YrLkuR4aYRRF47gDRuZcSRRFdgbkmlpGDSSQ1G1PR9E/a3Igg7j9XdIK9HffTFJP0Lg==", "dev": true }, - "@iconify-icons/dashicons": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@iconify-icons/dashicons/-/dashicons-1.1.0.tgz", - "integrity": "sha512-l539ceihPtCEm+v5JQjDjkRZ5ULPRJLA1OhSePuqTrBWkWx+H6asXkpM4hOB0cR59ynelsK9htSmrPij/JHnRg==", - "dev": true - }, - "@iconify/core": { - "version": "1.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@iconify/core/-/core-1.0.0-rc.3.tgz", - "integrity": "sha512-gCHmASaQbai749xrvvBpJ7eVrnJusLA2Q+aULMGAZkIrU/YRUiXznpfNITozZaIhdOLjzp8CD8s/j2vv5CyNCg==", - "dev": true, - "requires": { - "@cyberalien/redundancy": "^1.1.0", - "@iconify/types": "^1.0.5" - } - }, "@iconify/svelte": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@iconify/svelte/-/svelte-1.0.3.tgz", - "integrity": "sha512-Exjwm+LDOmueoVRd8hyG7s+8Q/jTh3tFOaaHTy/TCI2/OTkZe02fkHAUeNtlwnr867X6h3dC2ZIt0Ie4epaGhg==", - "dev": true, - "requires": { - "@iconify/core": "^1.0.0-rc.2", - "@iconify/types": "^1.0.5" - } - }, - "@iconify/types": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@iconify/types/-/types-1.0.6.tgz", - "integrity": "sha512-eG74WPaqjBGnZ3Xy36X4LRDA/ZlhCK6T0zbsAAIYObY2Qija/379iXx+e2wWwEIXS46B62nGaUcuI0MpUnTSrg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@iconify/svelte/-/svelte-1.0.4.tgz", + "integrity": "sha512-Bjr4UMJUsMCra1lpMYIijLZJustalA7FuBldV9B7IsaeKGZ06rcmgeVUYJqrKJ/0bhRg/chcKasLjUlFqWIoMQ==", "dev": true }, "@polka/url": { - "version": "1.0.0-next.11", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.11.tgz", - "integrity": "sha512-3NsZsJIA/22P3QUyrEDNA2D133H4j224twJrdipXN38dpnIOzAbUDtOwkcJ5pXmn75w7LSQDjA4tO9dm1XlqlA==" + "version": "1.0.0-next.12", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.12.tgz", + "integrity": "sha512-6RglhutqrGFMO1MNUXp95RBuYIuc8wTnMAV5MUhLmjTOy78ncwOw7RgeQ/HeymkKXRhZd0s2DNrM1rL7unk3MQ==" }, "@rollup/plugin-commonjs": { "version": "16.0.0", @@ -1173,9 +1126,9 @@ "dev": true }, "@types/node": { - "version": "14.14.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.13.tgz", - "integrity": "sha512-vbxr0VZ8exFMMAjCW8rJwaya0dMCDyYW2ZRdTyjtrCvJoENMpdUHOT/eTzvgyA5ZnqRZ/sI0NwqAxNHKYokLJQ==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==", "dev": true }, "@types/resolve": { @@ -1197,31 +1150,25 @@ } }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "brace-expansion": { @@ -1250,9 +1197,9 @@ "dev": true }, "builtin-modules": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", - "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", "dev": true }, "chalk": { @@ -1267,14 +1214,14 @@ } }, "chokidar": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", - "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", "dev": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", - "fsevents": "~2.1.2", + "fsevents": "~2.3.1", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", @@ -1354,9 +1301,9 @@ "dev": true }, "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, @@ -1386,9 +1333,9 @@ } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -1435,9 +1382,9 @@ } }, "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.3.0.tgz", + "integrity": "sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw==", "dev": true, "requires": { "has": "^1.0.3" @@ -1519,21 +1466,21 @@ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" }, "livereload": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.1.tgz", - "integrity": "sha512-9g7sua11kkyZNo2hLRCG3LuZZwqexoyEyecSlV8cAsfAVVCZqLzVir6XDqmH0r+Vzgnd5LrdHDMyjtFnJQLAYw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.3.tgz", + "integrity": "sha512-q7Z71n3i4X0R9xthAryBdNGVGAO2R5X+/xXpmKeuPMrteg+W2U8VusTKV3YiJbXZwKsOlFlHe+go6uSNjfxrZw==", "dev": true, "requires": { - "chokidar": "^3.3.0", - "livereload-js": "^3.1.0", + "chokidar": "^3.5.0", + "livereload-js": "^3.3.1", "opts": ">= 1.2.0", - "ws": "^6.2.1" + "ws": "^7.4.3" } }, "livereload-js": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.3.1.tgz", - "integrity": "sha512-CBu1gTEfzVhlOK1WASKAAJ9Qx1fHECTq0SUB67sfxwQssopTyvzqTlgl+c0h9pZ6V+Fzd2rc510ppuNusg9teQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.3.2.tgz", + "integrity": "sha512-w677WnINxFkuixAoUEXOStewzLYGI76XVag+0JWMMEyjJQKs0ibWZMxkTlB96Lm3EjZ7IeOxVziBEbtxVQqQZA==", "dev": true }, "local-access": { @@ -1557,9 +1504,9 @@ "dev": true }, "mime": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", - "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==" + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==" }, "minimatch": { "version": "3.0.4", @@ -1609,9 +1556,9 @@ "dev": true }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", "dev": true }, "randombytes": { @@ -1639,22 +1586,22 @@ "dev": true }, "resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "requires": { - "is-core-module": "^2.1.0", + "is-core-module": "^2.2.0", "path-parse": "^1.0.6" } }, "rollup": { - "version": "2.34.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.34.2.tgz", - "integrity": "sha512-mvtQLqu3cNeoctS+kZ09iOPxrc1P1/Bt1z15enuQ5feyKOdM3MJAVFjjsygurDpSWn530xB4AlA83TWIzRstXA==", + "version": "2.46.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.46.0.tgz", + "integrity": "sha512-qPGoUBNl+Z8uNu0z7pD3WPTABWRbcOwIrO/5ccDJzmrtzn0LVf6Lj91+L5CcWhXl6iWf23FQ6m8Jkl2CmN1O7Q==", "dev": true, "requires": { - "fsevents": "~2.1.2" + "fsevents": "~2.3.1" } }, "rollup-plugin-livereload": { @@ -1735,9 +1682,9 @@ } }, "sirv": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.10.tgz", - "integrity": "sha512-H5EZCoZaggEUQy8ocKsF7WAToGuZhjJlLvM3XOef46CbdIgbNeQ1p32N1PCuCjkVYwrAVOSMacN6CXXgIzuspg==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.11.tgz", + "integrity": "sha512-SR36i3/LSWja7AJNRBz4fF/Xjpn7lQFI30tZ434dIy+bitLYSP+ZEenHg36i23V2SGEz+kqjksg0uOGZ5LPiqg==", "requires": { "@polka/url": "^1.0.0-next.9", "mime": "^2.3.1", @@ -1745,9 +1692,9 @@ } }, "sirv-cli": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/sirv-cli/-/sirv-cli-1.0.10.tgz", - "integrity": "sha512-8mLTRkvzpZXMyUZJ1whf84YHN/mm2r2+j5sU1ZYr5n2jA8VkFItNPk53oysOo+0QxBVp9aUjggkAsQp1d7L3OQ==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/sirv-cli/-/sirv-cli-1.0.11.tgz", + "integrity": "sha512-L8NILoRSBd38VcfFcERYCaVCnWPBLo9G6u/a37UJ8Ysv4DfjizMbFBcM+SswNnndJienhR6qy8KFuAEaeL4g8Q==", "requires": { "console-clear": "^1.1.0", "get-port": "^3.2.0", @@ -1755,7 +1702,7 @@ "local-access": "^1.0.1", "sade": "^1.6.0", "semiver": "^1.0.0", - "sirv": "^1.0.10", + "sirv": "^1.0.11", "tinydate": "^1.0.0" } }, @@ -1799,15 +1746,15 @@ } }, "svelte": { - "version": "3.31.0", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.31.0.tgz", - "integrity": "sha512-r+n8UJkDqoQm1b+3tA3Lh6mHXKpcfOSOuEuIo5gE2W9wQYi64RYX/qE6CZBDDsP/H4M+N426JwY7XGH4xASvGQ==", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.38.1.tgz", + "integrity": "sha512-N3XLAyfzqrFxwRLevBeW7Dke9ZlHRVGSIed5abo4Drvj+zvd2OyWpFa1x4nQUc8Lnvt4Kcn8/5le1peRDybNqg==", "dev": true }, "terser": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.5.1.tgz", - "integrity": "sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.0.tgz", + "integrity": "sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g==", "dev": true, "requires": { "commander": "^2.20.0", @@ -1841,13 +1788,11 @@ "dev": true }, "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } + "requires": {} } } } diff --git a/packages/svelte-demo/package.json b/packages/svelte-demo/package.json index 79f2ecc..bf0a8d2 100644 --- a/packages/svelte-demo/package.json +++ b/packages/svelte-demo/package.json @@ -8,8 +8,8 @@ "start": "sirv public" }, "devDependencies": { - "@iconify-icons/bx": "^1.0.2", - "@iconify-icons/dashicons": "^1.0.0", + "@iconify-icons/mdi-light": "^1.1.0", + "@iconify-icons/uil": "^1.1.1", "@iconify/svelte": "^1.0.3", "@rollup/plugin-commonjs": "^16.0.0", "@rollup/plugin-node-resolve": "^10.0.0", diff --git a/packages/svelte-demo/public/global.css b/packages/svelte-demo/public/global.css index ec905f5..718c03d 100644 --- a/packages/svelte-demo/public/global.css +++ b/packages/svelte-demo/public/global.css @@ -1,66 +1,162 @@ -html, body { +main { + font-family: Helvetica, Arial, sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-align: left; + color: #2c3e50; + font-size: 16px; + line-height: 1.5; +} + +/* Sections */ +section { + border-bottom: 1px dotted #ccc; + padding: 16px; +} +section:last-child { + border-bottom-width: 0; +} +section:after { + content: ' '; + display: table; + clear: both; +} +h1, +h2 { + margin: 0 0 16px; + padding: 0; + font-size: 24px; + font-weight: normal; +} +h2 { + margin: 16px 0; + font-size: 20px; +} +h1 + h2 { + margin-top: -8px; +} +p { + margin: 12px 0 4px; + padding: 0; +} + +/* Tests */ +.test-row { + font-size: 16px; + line-height: 1.5; +} +.test-row-icons { + padding-right: 4px; +} +.test-row-icons > svg { + color: #afafaf; + display: none; +} +.test-row-icons > svg.visible { + display: inline-block; +} +.test-row-icons > svg.success { + color: #327335; +} +.test-row-icons > svg.failed { + color: #ba3329; +} + +/* 24px icon */ +.icon-24 svg { + font-size: 24px; + line-height: 1; + vertical-align: -0.25em; +} + +/* Alert demo */ +.alert { position: relative; - width: 100%; - height: 100%; + margin: 8px; + padding: 16px; + padding-left: 48px; + background: #ba3329; + color: #fff; + border-radius: 5px; + float: left; } -body { - color: #333; - margin: 0; - padding: 8px; - box-sizing: border-box; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; +.alert + div { + clear: both; } -a { - color: rgb(0,100,200); +.alert svg { + position: absolute; + left: 12px; + top: 50%; + font-size: 24px; + line-height: 1em; + margin: -0.5em 0 0; +} + +/* Checkbox component */ +.checkbox-container { + margin: 8px 0; +} + +.checkbox { + cursor: pointer; + /* color: #1769aa; */ + color: #626262; text-decoration: none; } - -a:hover { +.checkbox:hover { + color: #ba3329; text-decoration: underline; } -a:visited { - color: rgb(0,80,160); +.checkbox svg { + margin-right: 4px; + color: #afafaf; + font-size: 24px; + line-height: 1em; + vertical-align: -0.25em; +} +.checkbox--checked svg { + color: #327335; +} +.checkbox:hover svg { + color: inherit; } -label { - display: block; +.checkbox-container small { + margin-left: 4px; + opacity: 0.7; } -input, button, select, textarea { - font-family: inherit; - font-size: inherit; - padding: 0.4em; - margin: 0 0 0.5em 0; - box-sizing: border-box; - border: 1px solid #ccc; - border-radius: 2px; +/* Inline demo */ +.inline-demo svg { + color: #06a; + margin: 0 8px; + position: relative; + z-index: 2; + background: #fff; } - -input:disabled { - color: #ccc; +.inline-demo div { + position: relative; + font-size: 16px; + line-height: 1.5; } - -input[type="range"] { +.inline-demo div:before, +.inline-demo div:after { + content: ''; + position: absolute; + left: 0; + right: 0; height: 0; + border-top: 1px dashed #506874; + opacity: 0.5; + z-index: -1; } - -button { - color: #333; - background-color: #f4f4f4; - outline: none; +.inline-demo div:before { + bottom: 5px; } - -button:disabled { - color: #999; -} - -button:not(:disabled):active { - background-color: #ddd; -} - -button:focus { - border-color: #666; +.inline-demo div:after { + bottom: 7px; + border-top-color: #ba3329; } diff --git a/packages/svelte-demo/src/App.svelte b/packages/svelte-demo/src/App.svelte index bcbfbfb..0490c7f 100644 --- a/packages/svelte-demo/src/App.svelte +++ b/packages/svelte-demo/src/App.svelte @@ -1,123 +1,97 @@ - -
+ + + +
-

Usage

+

Checkbox

- Empty icon: - -
-
- Empty icon with placeholder: - 😿 -
-
- Simple icon: - -
-
- Icon refenced by name: - -
-
- - Important notice with alert icon! + +
-
-

Example file (components/Sample.svelte)

- -
- - - - - - -
-

Tests

-

Testing replacing ids in icon: (default handler) (custom handler)

-
diff --git a/packages/svelte-demo/src/demo-components/Checkbox.svelte b/packages/svelte-demo/src/demo-components/Checkbox.svelte new file mode 100644 index 0000000..0f10698 --- /dev/null +++ b/packages/svelte-demo/src/demo-components/Checkbox.svelte @@ -0,0 +1,28 @@ + + +
+ {text} + {hint} +
\ No newline at end of file diff --git a/packages/svelte-demo/src/demo-components/Inline.svelte b/packages/svelte-demo/src/demo-components/Inline.svelte new file mode 100644 index 0000000..1084a1f --- /dev/null +++ b/packages/svelte-demo/src/demo-components/Inline.svelte @@ -0,0 +1,33 @@ + + +
+

Inline demo

+
+ Block icon (behaving like image): + + +
+
+ Inline icon (behaving line text / icon font): + + +
+
+ Using "vertical-align: 0" to override inline attribute: + + + + +
+
\ No newline at end of file diff --git a/packages/svelte-demo/src/demo-components/UsageFull.svelte b/packages/svelte-demo/src/demo-components/UsageFull.svelte new file mode 100644 index 0000000..3a36094 --- /dev/null +++ b/packages/svelte-demo/src/demo-components/UsageFull.svelte @@ -0,0 +1,14 @@ + + +
+

Usage (full module)

+
+ Icon referenced by name: +
+
+ + Important notice with alert icon! +
+
\ No newline at end of file diff --git a/packages/svelte-demo/src/demo-components/UsageFullOffline.svelte b/packages/svelte-demo/src/demo-components/UsageFullOffline.svelte new file mode 100644 index 0000000..6a98cf3 --- /dev/null +++ b/packages/svelte-demo/src/demo-components/UsageFullOffline.svelte @@ -0,0 +1,22 @@ + + +
+

Usage (full module, offline mode)

+
+ Icon referenced by name: +
+
+ Icon referenced by object: +
+
+ 2 icons imported from icon set: +
+
+ + Important notice with alert icon! +
+
\ No newline at end of file diff --git a/packages/svelte-demo/src/demo-components/UsageOffline.svelte b/packages/svelte-demo/src/demo-components/UsageOffline.svelte new file mode 100644 index 0000000..d3875df --- /dev/null +++ b/packages/svelte-demo/src/demo-components/UsageOffline.svelte @@ -0,0 +1,24 @@ + + +
+

Usage (offline module)

+
+ Icon referenced by name: +
+
+ Icon referenced by object: +
+
+ 2 icons imported from icon set: + + +
+
+ + Important notice with alert icon! +
+
\ No newline at end of file diff --git a/packages/svelte-demo/src/components/Alignment.svelte b/packages/svelte-demo/src/samples/Alignment.svelte similarity index 96% rename from packages/svelte-demo/src/components/Alignment.svelte rename to packages/svelte-demo/src/samples/Alignment.svelte index 20c1bd2..ca20e48 100644 --- a/packages/svelte-demo/src/components/Alignment.svelte +++ b/packages/svelte-demo/src/samples/Alignment.svelte @@ -1,6 +1,7 @@
-

Alignment (components/Alignment.svelte)

+

Alignment (samples/Alignment.svelte)

Icon with correct width/heigh ratio:

diff --git a/packages/svelte-demo/src/components/ColorStyle.svelte b/packages/svelte-demo/src/samples/ColorStyle.svelte similarity index 77% rename from packages/svelte-demo/src/components/ColorStyle.svelte rename to packages/svelte-demo/src/samples/ColorStyle.svelte index 7b45840..bc7d0f1 100644 --- a/packages/svelte-demo/src/components/ColorStyle.svelte +++ b/packages/svelte-demo/src/samples/ColorStyle.svelte @@ -1,12 +1,12 @@
-

Color and style (components/ColorStyle.svelte)

+

Color and style (samples/ColorStyle.svelte)

Icon with color (red): diff --git a/packages/svelte-demo/src/components/Inline.svelte b/packages/svelte-demo/src/samples/Inline.svelte similarity index 97% rename from packages/svelte-demo/src/components/Inline.svelte rename to packages/svelte-demo/src/samples/Inline.svelte index fa3d272..2910647 100644 --- a/packages/svelte-demo/src/components/Inline.svelte +++ b/packages/svelte-demo/src/samples/Inline.svelte @@ -47,7 +47,7 @@
-

Inline (components/Inline.svelte)

+

Inline (samples/Inline.svelte)

Block icon (behaving like image): diff --git a/packages/svelte-demo/src/components/Sample.svelte b/packages/svelte-demo/src/samples/Sample.svelte similarity index 63% rename from packages/svelte-demo/src/components/Sample.svelte rename to packages/svelte-demo/src/samples/Sample.svelte index 72f9bc3..557df30 100644 --- a/packages/svelte-demo/src/components/Sample.svelte +++ b/packages/svelte-demo/src/samples/Sample.svelte @@ -1,6 +1,7 @@ diff --git a/packages/svelte-demo/src/components/Style.svelte b/packages/svelte-demo/src/samples/Style.svelte similarity index 91% rename from packages/svelte-demo/src/components/Style.svelte rename to packages/svelte-demo/src/samples/Style.svelte index be68a5c..45dc9e0 100644 --- a/packages/svelte-demo/src/components/Style.svelte +++ b/packages/svelte-demo/src/samples/Style.svelte @@ -1,7 +1,7 @@ @@ -17,7 +17,7 @@
-

Style (components/Style.svelte)

+

Style (samples/Style.svelte)

Default icon: diff --git a/packages/svelte-demo/src/components/Transformations.svelte b/packages/svelte-demo/src/samples/Transformations.svelte similarity index 90% rename from packages/svelte-demo/src/components/Transformations.svelte rename to packages/svelte-demo/src/samples/Transformations.svelte index 7ee07b3..1d3b91c 100644 --- a/packages/svelte-demo/src/components/Transformations.svelte +++ b/packages/svelte-demo/src/samples/Transformations.svelte @@ -1,6 +1,7 @@
-

Transformations (components/Transformations.svelte)

+

Transformations (samples/Transformations.svelte)

Default icon: diff --git a/packages/svelte/src/Icon.svelte b/packages/svelte/src/Icon.svelte index b9899ad..7d5b6b6 100644 --- a/packages/svelte/src/Icon.svelte +++ b/packages/svelte/src/Icon.svelte @@ -1,12 +1,49 @@ {#if data === null} diff --git a/packages/svelte/src/functions.ts b/packages/svelte/src/functions.ts index d3937d4..d60df74 100644 --- a/packages/svelte/src/functions.ts +++ b/packages/svelte/src/functions.ts @@ -1,68 +1,391 @@ -import type { IconifyIcon, IconifyJSON } from '@iconify/types'; -import { fullIcon } from '@iconify/core/lib/icon'; -import { parseIconSet } from '@iconify/core/lib/icon/icon-set'; +import type { IconifyJSON } from '@iconify/types'; + +// Core +import type { IconifyIconName } from '@iconify/core/lib/icon/name'; +import type { + IconifyIconSize, + IconifyHorizontalIconAlignment, + IconifyVerticalIconAlignment, +} from '@iconify/core/lib/customisations'; +import { + IconifyStorageFunctions, + storageFunctions, + getIconData, + allowSimpleNames, +} from '@iconify/core/lib/storage/functions'; +import { + IconifyBuilderFunctions, + builderFunctions, +} from '@iconify/core/lib/builder/functions'; +import { fullIcon, IconifyIcon } from '@iconify/core/lib/icon'; + +// Modules +import { coreModules } from '@iconify/core/lib/modules'; + +// API +import { API, IconifyAPIInternalStorage } from '@iconify/core/lib/api/'; +import { + IconifyAPIFunctions, + IconifyAPIInternalFunctions, + APIFunctions, + APIInternalFunctions, +} from '@iconify/core/lib/api/functions'; +import { + setAPIModule, + IconifyAPIModule, + IconifyAPISendQuery, + IconifyAPIPrepareQuery, + GetIconifyAPIModule, +} from '@iconify/core/lib/api/modules'; +import { getAPIModule as getJSONPAPIModule } from '@iconify/core/lib/api/modules/jsonp'; +import { + getAPIModule as getFetchAPIModule, + setFetch, +} from '@iconify/core/lib/api/modules/fetch'; +import { + setAPIConfig, + PartialIconifyAPIConfig, + IconifyAPIConfig, + getAPIConfig, + GetAPIConfig, +} from '@iconify/core/lib/api/config'; +import type { + IconifyIconLoaderCallback, + IconifyIconLoaderAbort, +} from '@iconify/core/lib/interfaces/loader'; + +// Cache +import { storeCache, loadCache } from '@iconify/core/lib/browser-storage'; +import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions'; +import type { + IconifyBrowserCacheType, + IconifyBrowserCacheFunctions, +} from '@iconify/core/lib/browser-storage/functions'; + +// Properties +import type { + IconProps, + IconifyIconCustomisations, + IconifyIconProps, +} from './props'; + +// Render SVG import { render } from './render'; import type { RenderResult } from './render'; -import type { IconProps } from './props'; /** - * Storage for icons referred by name + * Export required types */ -const storage: Record> = Object.create(null); +// Function sets +export { + IconifyStorageFunctions, + IconifyBuilderFunctions, + IconifyBrowserCacheFunctions, + IconifyAPIFunctions, + IconifyAPIInternalFunctions, +}; + +// JSON stuff +export { IconifyIcon, IconifyJSON, IconifyIconName }; + +// Customisations +export { + IconifyIconCustomisations, + IconifyIconSize, + IconifyHorizontalIconAlignment, + IconifyVerticalIconAlignment, + IconifyIconProps, + IconProps, +}; + +// API +export { + IconifyAPIConfig, + IconifyIconLoaderCallback, + IconifyIconLoaderAbort, + IconifyAPIInternalStorage, + IconifyAPIModule, + GetAPIConfig, + IconifyAPIPrepareQuery, + IconifyAPISendQuery, + PartialIconifyAPIConfig, +}; + +/* Browser cache */ +export { IconifyBrowserCacheType }; + +/** + * Enable and disable browser cache + */ +export const enableCache = (storage: IconifyBrowserCacheType) => + toggleBrowserCache(storage, true); + +export const disableCache = (storage: IconifyBrowserCacheType) => + toggleBrowserCache(storage, false); + +/* Storage functions */ +/** + * Check if icon exists + */ +export const iconExists = storageFunctions.iconExists; + +/** + * Get icon data + */ +export const getIcon = storageFunctions.getIcon; + +/** + * List available icons + */ +export const listIcons = storageFunctions.listIcons; + +/** + * Add one icon + */ +export const addIcon = storageFunctions.addIcon; + +/** + * Add icon set + */ +export const addCollection = storageFunctions.addCollection; + +/* Builder functions */ +/** + * Calculate icon size + */ +export const calculateSize = builderFunctions.calculateSize; + +/** + * Replace unique ids in content + */ +export const replaceIDs = builderFunctions.replaceIDs; + +/* API functions */ +/** + * Load icons + */ +export const loadIcons = APIFunctions.loadIcons; + +/** + * Add API provider + */ +export const addAPIProvider = APIFunctions.addAPIProvider; + +/** + * Export internal functions that can be used by third party implementations + */ +export const _api = APIInternalFunctions; + +/** + * Initialise stuff + */ +// Enable short names +allowSimpleNames(true); + +// Set API +coreModules.api = API; + +// Use Fetch API by default +let getAPIModule: GetIconifyAPIModule = getFetchAPIModule; +try { + if (typeof document !== 'undefined' && typeof window !== 'undefined') { + // If window and document exist, attempt to load whatever module is available, otherwise use Fetch API + getAPIModule = + typeof fetch === 'function' && typeof Promise === 'function' + ? getFetchAPIModule + : getJSONPAPIModule; + } +} catch (err) { + // +} +setAPIModule('', getAPIModule(getAPIConfig)); + +/** + * Function to enable node-fetch for getting icons on server side + */ +export function setNodeFetch(nodeFetch: typeof fetch) { + setFetch(nodeFetch); + if (getAPIModule !== getFetchAPIModule) { + getAPIModule = getFetchAPIModule; + setAPIModule('', getAPIModule(getAPIConfig)); + } +} + +/** + * Browser stuff + */ +if (typeof document !== 'undefined' && typeof window !== 'undefined') { + // Set cache and load existing cache + coreModules.cache = storeCache; + loadCache(); + + const _window = window; + + // Load icons from global "IconifyPreload" + interface WindowWithIconifyPreload { + IconifyPreload: IconifyJSON[] | IconifyJSON; + } + if ( + ((_window as unknown) as WindowWithIconifyPreload).IconifyPreload !== + void 0 + ) { + const preload = ((_window as unknown) as WindowWithIconifyPreload) + .IconifyPreload; + const err = 'Invalid IconifyPreload syntax.'; + if (typeof preload === 'object' && preload !== null) { + (preload instanceof Array ? preload : [preload]).forEach((item) => { + try { + if ( + // Check if item is an object and not null/array + typeof item !== 'object' || + item === null || + item instanceof Array || + // Check for 'icons' and 'prefix' + typeof item.icons !== 'object' || + typeof item.prefix !== 'string' || + // Add icon set + !addCollection(item) + ) { + console.error(err); + } + } catch (e) { + console.error(err); + } + }); + } + } + + // Set API from global "IconifyProviders" + interface WindowWithIconifyProviders { + IconifyProviders: Record; + } + if ( + ((_window as unknown) as WindowWithIconifyProviders) + .IconifyProviders !== void 0 + ) { + const providers = ((_window as unknown) as WindowWithIconifyProviders) + .IconifyProviders; + if (typeof providers === 'object' && providers !== null) { + for (let key in providers) { + const err = 'IconifyProviders[' + key + '] is invalid.'; + try { + const value = providers[key]; + if ( + typeof value !== 'object' || + !value || + value.resources === void 0 + ) { + continue; + } + if (!setAPIConfig(key, value)) { + console.error(err); + } + } catch (e) { + console.error(err); + } + } + } + } +} + +/* + +. + +. + +. + +. + +. + +. + +*/ + +/** + * Function to get icon status + */ +interface IconLoadingState { + name: string; + abort: IconifyIconLoaderAbort; +} + +type IconComponentData = Required | null; + +interface IconState { + // Last icon name + name: string; + + // Loading status + loading: IconLoadingState | null; +} + +type IconStateCallback = () => void; + +/** + * Check if component needs to be updated + */ +export function checkIconState( + icon: string | IconifyIcon, + state: IconState, + callback: IconStateCallback +): IconComponentData { + // Abort loading icon + function abortLoading() { + if (state.loading) { + state.loading.abort(); + state.loading = null; + } + } + + // Icon is an object + if ( + typeof icon === 'object' && + icon !== null && + typeof icon.body === 'string' + ) { + // Stop loading + state.name = ''; + abortLoading(); + return fullIcon(icon); + } + + // Invalid icon? + if (typeof icon !== 'string') { + abortLoading(); + return null; + } + + // Load icon + const data = getIconData(icon); + if (data === null) { + // Icon needs to be loaded + if (!state.loading || state.loading.name !== icon) { + // New icon to load + abortLoading(); + state.name = ''; + state.loading = { + name: icon, + abort: API.loadIcons([icon], callback), + }; + } + return null; + } + + // Icon data is available + state.name = icon; + abortLoading(); + return data; +} /** * Generate icon */ -export function generateIcon(props: IconProps): RenderResult | null { - // Split properties - const icon = - typeof props.icon === 'string' - ? storage[props.icon] - : typeof props.icon === 'object' - ? fullIcon(props.icon) - : null; - - // Validate icon object - if ( - icon === null || - typeof icon !== 'object' || - typeof icon.body !== 'string' - ) { - return null; - } - - return render(icon, props); -} - -/** - * Add icon to storage, allowing to call it by name - * - * @param name - * @param data - */ -export function addIcon(name: string, data: IconifyIcon): void { - storage[name] = fullIcon(data); -} - -/** - * Add collection to storage, allowing to call icons by name - * - * @param data Icon set - * @param prefix Optional prefix to add to icon names, true (default) if prefix from icon set should be used. - */ -export function addCollection( - data: IconifyJSON, - prefix?: string | boolean -): void { - const iconPrefix: string = - typeof prefix === 'string' - ? prefix - : prefix !== false && typeof data.prefix === 'string' - ? data.prefix + ':' - : ''; - parseIconSet(data, (name, icon) => { - if (icon !== null) { - storage[iconPrefix + name] = icon; - } - }); +export function generateIcon( + icon: IconComponentData, + props: IconProps +): RenderResult | null { + return icon ? render(icon, props) : null; } diff --git a/packages/svelte/src/iconify.ts b/packages/svelte/src/iconify.ts index 73c0bfc..22c321a 100644 --- a/packages/svelte/src/iconify.ts +++ b/packages/svelte/src/iconify.ts @@ -14,4 +14,16 @@ export type { IconifyIconCustomisations, IconProps } from './props'; export { default as Icon } from './Icon.svelte'; // Functions -export { addIcon, addCollection } from './functions'; +export { enableCache, disableCache } from './functions'; + +export { + iconExists, + getIcon, + listIcons, + addIcon, + addCollection, +} from './functions'; + +export { calculateSize, replaceIDs } from './functions'; + +export { loadIcons, addAPIProvider, _api, setNodeFetch } from './functions'; diff --git a/packages/svelte/tests/api/10-api-mock.test.js b/packages/svelte/tests/api/10-api-mock.test.js new file mode 100644 index 0000000..b7baf8c --- /dev/null +++ b/packages/svelte/tests/api/10-api-mock.test.js @@ -0,0 +1,40 @@ +import { loadIcons, iconExists } from '../../dist/iconify'; +import { mockAPIData } from '@iconify/core/lib/api/modules/mock'; +import { provider, nextPrefix } from './load'; + +describe('Testing fake API', () => { + test('using fake API to load icon', (done) => { + const prefix = nextPrefix(); + const name = 'mock-test'; + const iconName = `@${provider}:${prefix}:${name}`; + mockAPIData({ + provider, + prefix, + response: { + prefix, + icons: { + [name]: { + body: '', + }, + }, + }, + }); + + // Check if icon has been loaded + expect(iconExists(iconName)).toEqual(false); + + // Load icon + loadIcons([iconName], (loaded, missing, pending) => { + expect(loaded).toMatchObject([ + { + provider, + prefix, + name, + }, + ]); + expect(missing).toMatchObject([]); + expect(pending).toMatchObject([]); + done(); + }); + }); +}); diff --git a/packages/svelte/tests/api/20-rendering-from-api.test.js b/packages/svelte/tests/api/20-rendering-from-api.test.js new file mode 100644 index 0000000..bd44f58 --- /dev/null +++ b/packages/svelte/tests/api/20-rendering-from-api.test.js @@ -0,0 +1,153 @@ +import { render } from '@testing-library/svelte'; +import { Icon, loadIcons, iconExists } from '../../dist/iconify'; +import { mockAPIData } from '@iconify/core/lib/api/modules/mock'; +import { provider, nextPrefix } from './load'; + +const iconData = { + body: + '', + width: 24, + height: 24, +}; + +describe('Rendering icon', () => { + test('rendering icon after loading it', (done) => { + const prefix = nextPrefix(); + const name = 'render-test'; + const iconName = `@${provider}:${prefix}:${name}`; + mockAPIData({ + provider, + prefix, + response: { + prefix, + icons: { + [name]: iconData, + }, + }, + }); + + // Check if icon has been loaded + expect(iconExists(iconName)).toEqual(false); + + // Load icon + loadIcons([iconName], (loaded, missing, pending) => { + // Make sure icon has been loaded + expect(loaded).toMatchObject([ + { + provider, + prefix, + name, + }, + ]); + expect(missing).toMatchObject([]); + expect(pending).toMatchObject([]); + expect(iconExists(iconName)).toEqual(true); + + // Render component + const component = render(Icon, { icon: iconName }); + const node = component.container.querySelector('svg'); + const html = node.parentNode.innerHTML; + + // Check HTML + expect(html).toEqual( + '' + ); + + done(); + }); + }); + + test('rendering icon before loading it', (done) => { + const prefix = nextPrefix(); + const name = 'mock-test'; + const iconName = `@${provider}:${prefix}:${name}`; + mockAPIData({ + provider, + prefix, + response: { + prefix, + icons: { + [name]: iconData, + }, + }, + delay: (next) => { + // Icon should not have loaded yet + expect(iconExists(iconName)).toEqual(false); + + // Send icon data + next(); + + // Test it again + expect(iconExists(iconName)).toEqual(true); + + // Check if state was changed + // Wrapped in double setTimeout() because re-render takes 2 ticks + setTimeout(() => { + setTimeout(() => { + const node = component.container.querySelector('svg'); + const html = node.parentNode.innerHTML; + + // Check HTML + expect(html).toEqual( + '' + ); + + done(); + }, 0); + }, 0); + }, + }); + + // Check if icon has been loaded + expect(iconExists(iconName)).toEqual(false); + + // Render component + const component = render(Icon, { icon: iconName }); + + // Should render empty icon + const html = component.container.innerHTML; + expect(html).toEqual('
'); + }); + + test('missing icon', (done) => { + const prefix = nextPrefix(); + const name = 'missing-icon'; + const iconName = `@${provider}:${prefix}:${name}`; + mockAPIData({ + provider, + prefix, + response: 404, + delay: (next) => { + // Icon should not have loaded yet + expect(iconExists(iconName)).toEqual(false); + + // Send icon data + next(); + + // Test it again + expect(iconExists(iconName)).toEqual(false); + + // Check if state was changed + // Wrapped in double setTimeout() because re-render takes 2 ticks + setTimeout(() => { + setTimeout(() => { + const html = component.container.innerHTML; + expect(html).toEqual('
'); + + done(); + }, 0); + }, 0); + }, + }); + + // Check if icon has been loaded + expect(iconExists(iconName)).toEqual(false); + + // Render component + const component = render(Icon, { icon: iconName }); + + // Should render empty icon + const html = component.container.innerHTML; + expect(html).toEqual('
'); + }); +}); diff --git a/packages/svelte/tests/api/30-changing-props.test.js b/packages/svelte/tests/api/30-changing-props.test.js new file mode 100644 index 0000000..d34e7a2 --- /dev/null +++ b/packages/svelte/tests/api/30-changing-props.test.js @@ -0,0 +1,205 @@ +import { render } from '@testing-library/svelte'; +import { iconExists } from '../../dist/iconify'; +import { mockAPIData } from '@iconify/core/lib/api/modules/mock'; +import { provider, nextPrefix } from './load'; +import ChangeIcon from './fixtures/ChangeIcon.svelte'; +import ChangeProps from './fixtures/ChangeProps.svelte'; + +const iconData = { + body: + '', + width: 24, + height: 24, +}; + +const iconData2 = { + body: + '', + width: 32, + height: 32, +}; + +describe('Rendering icon', () => { + test('changing icon property', (done) => { + const prefix = nextPrefix(); + const name = 'changing-prop'; + const name2 = 'changing-prop2'; + const iconName = `@${provider}:${prefix}:${name}`; + const iconName2 = `@${provider}:${prefix}:${name2}`; + let triggerSwap; + + mockAPIData({ + provider, + prefix, + response: { + prefix, + icons: { + [name]: iconData, + }, + }, + delay: (next) => { + // Fixture callback should have been called + expect(typeof triggerSwap).toEqual('function'); + + // Icon should not have loaded yet + expect(iconExists(iconName)).toEqual(false); + + // Send icon data + next(); + + // Test it again + expect(iconExists(iconName)).toEqual(true); + + // Check if state was changed + // Wrapped in double setTimeout() because re-render takes 2 ticks + setTimeout(() => { + setTimeout(() => { + const node = component.container.querySelector('svg'); + const html = node.parentNode.innerHTML; + + // Check HTML + expect(html).toEqual( + '' + ); + + // Change property + triggerSwap(); + }, 0); + }, 0); + }, + }); + + mockAPIData({ + provider, + prefix, + response: { + prefix, + icons: { + [name2]: iconData2, + }, + }, + delay: (next) => { + // Icon should not have loaded yet + expect(iconExists(iconName2)).toEqual(false); + + // Send icon data + next(); + + // Test it again + expect(iconExists(iconName2)).toEqual(true); + + // Check if state was changed + // Wrapped in double setTimeout() because re-render takes 2 ticks + setTimeout(() => { + setTimeout(() => { + const node = component.container.querySelector('svg'); + const html = node.parentNode.innerHTML; + + // Check HTML + expect(html).toEqual( + '' + ); + + done(); + }, 0); + }, 0); + }, + }); + + // Check if icon has been loaded + expect(iconExists(iconName)).toEqual(false); + + // Render component + const component = render(ChangeIcon, { + icon1: iconName, + icon2: iconName2, + expose: (swap) => { + triggerSwap = swap; + }, + }); + + // Should render empty icon + const html = component.container.innerHTML; + expect(html).toEqual('
'); + }); + + test('changing multiple properties', (done) => { + const prefix = nextPrefix(); + const name = 'multiple-props'; + const iconName = `@${provider}:${prefix}:${name}`; + let triggerSwap; + + mockAPIData({ + provider, + prefix, + response: { + prefix, + icons: { + [name]: iconData, + }, + }, + delay: (next) => { + // Fixture callback should have been called + expect(typeof triggerSwap).toEqual('function'); + + // Icon should not have loaded yet + expect(iconExists(iconName)).toEqual(false); + + // Send icon data + next(); + + // Test it again + expect(iconExists(iconName)).toEqual(true); + + // Check if state was changed + // Wrapped in double setTimeout() because re-render takes 2 ticks + setTimeout(() => { + setTimeout(() => { + const node = component.container.querySelector('svg'); + const html = node.parentNode.innerHTML; + + // Check HTML + expect(html).toEqual( + '' + ); + + // Add horizontal flip and style + triggerSwap(); + + // Wait for component to re-render + setTimeout(() => { + setTimeout(() => { + // Check HTML again + const node = component.container.querySelector( + 'svg' + ); + const html = node.parentNode.innerHTML; + + expect(html).toEqual( + '' + ); + + done(); + }, 0); + }, 0); + }, 0); + }, 0); + }, + }); + + // Check if icon has been loaded + expect(iconExists(iconName)).toEqual(false); + + // Render component + const component = render(ChangeProps, { + icon: iconName, + expose: (swap) => { + triggerSwap = swap; + }, + }); + + // Should render empty icon + const html = component.container.innerHTML; + expect(html).toEqual('
'); + }); +}); diff --git a/packages/svelte/tests/api/fixtures/ChangeIcon.svelte b/packages/svelte/tests/api/fixtures/ChangeIcon.svelte new file mode 100644 index 0000000..895069a --- /dev/null +++ b/packages/svelte/tests/api/fixtures/ChangeIcon.svelte @@ -0,0 +1,18 @@ + + \ No newline at end of file diff --git a/packages/svelte/tests/api/fixtures/ChangeProps.svelte b/packages/svelte/tests/api/fixtures/ChangeProps.svelte new file mode 100644 index 0000000..ee9c242 --- /dev/null +++ b/packages/svelte/tests/api/fixtures/ChangeProps.svelte @@ -0,0 +1,22 @@ + + \ No newline at end of file diff --git a/packages/svelte/tests/api/load.js b/packages/svelte/tests/api/load.js new file mode 100644 index 0000000..215edc7 --- /dev/null +++ b/packages/svelte/tests/api/load.js @@ -0,0 +1,15 @@ +import { _api, addAPIProvider } from '../../dist/iconify'; +import { mockAPIModule } from '@iconify/core/lib/api/modules/mock'; + +// API provider for tests +export const provider = 'mock-api'; + +// Set API module for provider +addAPIProvider(provider, { + resources: ['http://localhost'], +}); +_api.setAPIModule(provider, mockAPIModule); + +// Prefix +let counter = 0; +export const nextPrefix = () => 'mock-' + counter++; diff --git a/packages/svelte/tests/iconify/10-basic.test.js b/packages/svelte/tests/iconify/10-basic.test.js new file mode 100644 index 0000000..07b2e76 --- /dev/null +++ b/packages/svelte/tests/iconify/10-basic.test.js @@ -0,0 +1,32 @@ +import { render } from '@testing-library/svelte'; +import { Icon } from '../../dist/iconify'; + +const iconData = { + body: + '', + width: 24, + height: 24, +}; + +describe('Creating component', () => { + test('basic icon', () => { + const component = render(Icon, { icon: iconData }); + const node = component.container.querySelector('svg'); + const html = node.parentNode.innerHTML; + + // Check HTML + expect(html).toEqual( + '' + ); + + // Make sure getAttribute() works, used in other tests + expect(node.getAttribute('xmlns')).toEqual( + 'http://www.w3.org/2000/svg' + ); + expect(node.getAttribute('aria-hidden')).toEqual('true'); + + // Make sure style exists + const style = node.style; + expect(typeof style).toEqual('object'); + }); +}); diff --git a/packages/svelte/tests/iconify/10-empty.test.js b/packages/svelte/tests/iconify/10-empty.test.js new file mode 100644 index 0000000..d28f6c0 --- /dev/null +++ b/packages/svelte/tests/iconify/10-empty.test.js @@ -0,0 +1,12 @@ +import { render } from '@testing-library/svelte'; +import { Icon } from '../../dist/iconify'; + +describe('Empty icon', () => { + test('basic test', () => { + const component = render(Icon, {}); + const html = component.container.innerHTML; + + // Empty container div + expect(html).toEqual('
'); + }); +}); diff --git a/packages/svelte/tests/iconify/20-attributes.test.js b/packages/svelte/tests/iconify/20-attributes.test.js new file mode 100644 index 0000000..428bdfe --- /dev/null +++ b/packages/svelte/tests/iconify/20-attributes.test.js @@ -0,0 +1,79 @@ +import { render } from '@testing-library/svelte'; +import { Icon } from '../../dist/iconify'; + +const iconData = { + body: + '', + width: 24, + height: 24, +}; + +describe('Padding attributes', () => { + test('title', () => { + const component = render(Icon, { icon: iconData, title: 'Icon!' }); + const node = component.container.querySelector('svg'); + expect(node.getAttribute('title')).toEqual('Icon!'); + }); + + test('aria-hidden', () => { + // dashes, string value + const component = render(Icon, { + 'icon': iconData, + 'aria-hidden': 'false', + }); + const node = component.container.querySelector('svg'); + expect(node.getAttribute('aria-hidden')).toEqual(null); + }); + + test('ariaHidden', () => { + // camelCase, boolean value + const component = render(Icon, { + icon: iconData, + ariaHidden: false, + }); + const node = component.container.querySelector('svg'); + expect(node.getAttribute('aria-hidden')).toEqual(null); + }); + + test('style', () => { + const component = render(Icon, { + icon: iconData, + style: 'vertical-align: 0; color: red;', + }); + const node = component.container.querySelector('svg'); + expect(node.style.verticalAlign).toEqual('0'); + expect(node.style.color).toEqual('red'); + }); + + test('color', () => { + const component = render(Icon, { + icon: iconData, + color: 'red', + }); + const node = component.container.querySelector('svg'); + expect(node.style.color).toEqual('red'); + }); + + test('color with style', () => { + const component = render(Icon, { + icon: iconData, + color: 'red', + style: 'color: green;', + }); + const node = component.container.querySelector('svg'); + expect(node.style.color).toEqual('red'); + }); + + test('attributes that cannot change', () => { + const component = render(Icon, { + icon: iconData, + viewBox: '0 0 0 0', + preserveAspectRatio: 'none', + }); + const node = component.container.querySelector('svg'); + expect(node.getAttribute('viewBox')).toEqual('0 0 24 24'); + expect(node.getAttribute('preserveAspectRatio')).toEqual( + 'xMidYMid meet' + ); + }); +}); diff --git a/packages/svelte/tests/iconify/20-dimensions.test.js b/packages/svelte/tests/iconify/20-dimensions.test.js new file mode 100644 index 0000000..8d0b555 --- /dev/null +++ b/packages/svelte/tests/iconify/20-dimensions.test.js @@ -0,0 +1,40 @@ +import { render } from '@testing-library/svelte'; +import { Icon } from '../../dist/iconify'; + +const iconData = { + body: + '', + width: 24, + height: 24, +}; + +describe('Dimensions', () => { + test('height', () => { + const component = render(Icon, { icon: iconData, height: '48' }); + const node = component.container.querySelector('svg'); + expect(node.getAttribute('height')).toEqual('48'); + expect(node.getAttribute('width')).toEqual('48'); + }); + + test('width and height', () => { + const component = render(Icon, { + icon: iconData, + // Mixing numbers and strings + width: 32, + height: '48', + }); + const node = component.container.querySelector('svg'); + expect(node.getAttribute('height')).toEqual('48'); + expect(node.getAttribute('width')).toEqual('32'); + }); + + test('auto', () => { + const component = render(Icon, { + icon: iconData, + height: 'auto', + }); + const node = component.container.querySelector('svg'); + expect(node.getAttribute('height')).toEqual('24'); + expect(node.getAttribute('width')).toEqual('24'); + }); +}); diff --git a/packages/svelte/tests/iconify/20-ids.test.js b/packages/svelte/tests/iconify/20-ids.test.js new file mode 100644 index 0000000..c0dfb87 --- /dev/null +++ b/packages/svelte/tests/iconify/20-ids.test.js @@ -0,0 +1,29 @@ +import { render } from '@testing-library/svelte'; +import { Icon } from '../../dist/iconify'; + +const iconDataWithID = { + body: + '', + width: 128, + height: 128, +}; + +describe('Replacing IDs', () => { + test('default behavior', () => { + const component = render(Icon, { icon: iconDataWithID }); + const node = component.container.querySelector('svg'); + + // Check that default id doesn't exist + const path = node.getElementById('ssvg-id-1st-place-medala'); + expect(path).toBeNull(); + }); + + test('custom generator', () => { + const component = render(Icon, { icon: iconDataWithID, id: 'test' }); + const node = component.container.querySelector('svg'); + + // Check that ID 'testa' exists + const path = node.getElementById('test-0'); + expect(path).toBeTruthy(); + }); +}); diff --git a/packages/svelte/tests/iconify/20-inline.test.js b/packages/svelte/tests/iconify/20-inline.test.js new file mode 100644 index 0000000..bb740c6 --- /dev/null +++ b/packages/svelte/tests/iconify/20-inline.test.js @@ -0,0 +1,44 @@ +import { render } from '@testing-library/svelte'; +import { Icon } from '../../dist/iconify'; + +const iconData = { + body: + '', + width: 24, + height: 24, +}; + +describe('Inline attribute', () => { + test('boolean true', () => { + const component = render(Icon, { icon: iconData, inline: true }); + const node = component.container.querySelector('svg'); + const style = node.style; + + expect(style.verticalAlign).toEqual('-0.125em'); + }); + + test('string true', () => { + const component = render(Icon, { icon: iconData, inline: 'true' }); + const node = component.container.querySelector('svg'); + const style = node.style; + + expect(style.verticalAlign).toEqual('-0.125em'); + }); + + test('false', () => { + const component = render(Icon, { icon: iconData, inline: false }); + const node = component.container.querySelector('svg'); + const style = node.style; + + expect(style.verticalAlign).toEqual(''); + }); + + test('false string', () => { + // "false" = true + const component = render(Icon, { icon: iconData, inline: 'false' }); + const node = component.container.querySelector('svg'); + const style = node.style; + + expect(style.verticalAlign).toEqual('-0.125em'); + }); +}); diff --git a/packages/svelte/tests/iconify/20-transformations.test.js b/packages/svelte/tests/iconify/20-transformations.test.js new file mode 100644 index 0000000..0b7d503 --- /dev/null +++ b/packages/svelte/tests/iconify/20-transformations.test.js @@ -0,0 +1,159 @@ +import { render } from '@testing-library/svelte'; +import { Icon } from '../../dist/iconify'; + +const iconData = { + body: + '', + width: 24, + height: 32, +}; + +describe('Rotation', () => { + test('number', () => { + const component = render(Icon, { icon: iconData, rotate: 1 }); + const node = component.container.querySelector('svg'); + + // Find first child node + const child = node.childNodes[0]; + expect(child.tagName).toEqual('g'); + expect(child.getAttribute('transform')).toEqual('rotate(90 16 16)'); + }); + + test('string', () => { + const component = render(Icon, { icon: iconData, rotate: '180deg' }); + const node = component.container.querySelector('svg'); + + // Find first child node + const child = node.childNodes[0]; + expect(child.tagName).toEqual('g'); + expect(child.getAttribute('transform')).toEqual('rotate(180 12 16)'); + }); +}); + +describe('Flip', () => { + test('boolean', () => { + const component = render(Icon, { icon: iconData, hFlip: true }); + const node = component.container.querySelector('svg'); + + // Find first child node + const child = node.childNodes[0]; + expect(child.tagName).toEqual('g'); + expect(child.getAttribute('transform')).toEqual( + 'translate(24 0) scale(-1 1)' + ); + }); + + test('string', () => { + const component = render(Icon, { icon: iconData, flip: 'vertical' }); + const node = component.container.querySelector('svg'); + + // Find first child node + const child = node.childNodes[0]; + expect(child.tagName).toEqual('g'); + expect(child.getAttribute('transform')).toEqual( + 'translate(0 32) scale(1 -1)' + ); + }); + + test('string and boolean', () => { + const component = render(Icon, { + icon: iconData, + flip: 'horizontal', + vFlip: true, + }); + const node = component.container.querySelector('svg'); + + // Find first child node + const child = node.childNodes[0]; + expect(child.tagName).toEqual('g'); + // horizontal + vertical = 180deg rotation + expect(child.getAttribute('transform')).toEqual('rotate(180 12 16)'); + }); + + test('string for boolean attribute', () => { + const component = render(Icon, { + icon: iconData, + hFlip: 'true', + }); + const node = component.container.querySelector('svg'); + + // Find first child node + const child = node.childNodes[0]; + expect(child.tagName).toEqual('g'); + expect(child.getAttribute('transform')).toEqual( + 'translate(24 0) scale(-1 1)' + ); + }); + + test('shorthand and boolean', () => { + // 'flip' is processed after 'hFlip', overwriting value + const component = render(Icon, { + icon: iconData, + flip: 'horizontal', + hFlip: false, + }); + const node = component.container.querySelector('svg'); + + // Find first child node + const child = node.childNodes[0]; + expect(child.tagName).toEqual('g'); + expect(child.getAttribute('transform')).toEqual( + 'translate(24 0) scale(-1 1)' + ); + }); + + test('shorthand and boolean as string', () => { + // 'flip' is processed after 'hFlip', overwriting value + const component = render(Icon, { + icon: iconData, + flip: 'vertical', + hFlip: true, + }); + const node = component.container.querySelector('svg'); + + // Find first child node + const child = node.childNodes[0]; + expect(child.tagName).toEqual('g'); + expect(child.getAttribute('transform')).toEqual('rotate(180 12 16)'); + }); + + test('wrong case', () => { + // 'flip' is processed after 'hFlip', overwriting value + const component = render(Icon, { + icon: iconData, + vflip: true, + }); + const node = component.container.querySelector('svg'); + + // Find first child node + const child = node.childNodes[0]; + expect(child.tagName).toEqual('path'); + }); +}); + +describe('Alignment and slice', () => { + test('vAlign and slice', () => { + const component = render(Icon, { + icon: iconData, + vAlign: 'top', + slice: true, + }); + const node = component.container.querySelector('svg'); + + expect(node.getAttribute('preserveAspectRatio')).toEqual( + 'xMidYMin slice' + ); + }); + + test('string', () => { + const component = render(Icon, { + icon: iconData, + align: 'left bottom', + }); + const node = component.container.querySelector('svg'); + + expect(node.getAttribute('preserveAspectRatio')).toEqual( + 'xMinYMax meet' + ); + }); +}); diff --git a/packages/svelte/tests/offline/10-empty.test.js b/packages/svelte/tests/offline/10-empty.test.js index 5f6ea91..d28f6c0 100644 --- a/packages/svelte/tests/offline/10-empty.test.js +++ b/packages/svelte/tests/offline/10-empty.test.js @@ -1,5 +1,5 @@ import { render } from '@testing-library/svelte'; -import { Icon } from '../../dist/offline'; +import { Icon } from '../../dist/iconify'; describe('Empty icon', () => { test('basic test', () => {