Compare commits
No commits in common. "1.0.0" and "main" have entirely different histories.
213
package-lock.json
generated
213
package-lock.json
generated
@ -1,9 +1,37 @@
|
|||||||
{
|
{
|
||||||
"name": "@jdbernard/vue-common",
|
"name": "@jdbernard/vue-common",
|
||||||
"version": "1.0.0",
|
"version": "1.0.7",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@babel/helper-string-parser": {
|
||||||
|
"version": "7.19.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
|
||||||
|
"integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@babel/helper-validator-identifier": {
|
||||||
|
"version": "7.19.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
|
||||||
|
"integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@babel/parser": {
|
||||||
|
"version": "7.21.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.1.tgz",
|
||||||
|
"integrity": "sha512-JzhBFpkuhBNYUY7qs+wTzNmyCWUHEaAFpQQD2YfU1rPL38/L43Wvid0fFkiOCnHvsGncRZgEPyGnltABLcVDTg=="
|
||||||
|
},
|
||||||
|
"@babel/types": {
|
||||||
|
"version": "7.21.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.0.tgz",
|
||||||
|
"integrity": "sha512-uR7NWq2VNFnDi7EYqiRz2Jv/VQIu38tu64Zy8TX2nQFQ6etJ9V/Rr2msW8BS132mum2rL645qpDrLtAJtVpuow==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@babel/helper-string-parser": "^7.19.4",
|
||||||
|
"@babel/helper-validator-identifier": "^7.19.1",
|
||||||
|
"to-fast-properties": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@jdbernard/logging": {
|
"@jdbernard/logging": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@jdbernard/logging/-/logging-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@jdbernard/logging/-/logging-1.1.3.tgz",
|
||||||
@ -12,6 +40,105 @@
|
|||||||
"axios": "^0.19.2"
|
"axios": "^0.19.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@vue/compiler-core": {
|
||||||
|
"version": "3.2.47",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz",
|
||||||
|
"integrity": "sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/parser": "^7.16.4",
|
||||||
|
"@vue/shared": "3.2.47",
|
||||||
|
"estree-walker": "^2.0.2",
|
||||||
|
"source-map": "^0.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@vue/compiler-dom": {
|
||||||
|
"version": "3.2.47",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz",
|
||||||
|
"integrity": "sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==",
|
||||||
|
"requires": {
|
||||||
|
"@vue/compiler-core": "3.2.47",
|
||||||
|
"@vue/shared": "3.2.47"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@vue/compiler-sfc": {
|
||||||
|
"version": "3.2.47",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz",
|
||||||
|
"integrity": "sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/parser": "^7.16.4",
|
||||||
|
"@vue/compiler-core": "3.2.47",
|
||||||
|
"@vue/compiler-dom": "3.2.47",
|
||||||
|
"@vue/compiler-ssr": "3.2.47",
|
||||||
|
"@vue/reactivity-transform": "3.2.47",
|
||||||
|
"@vue/shared": "3.2.47",
|
||||||
|
"estree-walker": "^2.0.2",
|
||||||
|
"magic-string": "^0.25.7",
|
||||||
|
"postcss": "^8.1.10",
|
||||||
|
"source-map": "^0.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@vue/compiler-ssr": {
|
||||||
|
"version": "3.2.47",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz",
|
||||||
|
"integrity": "sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==",
|
||||||
|
"requires": {
|
||||||
|
"@vue/compiler-dom": "3.2.47",
|
||||||
|
"@vue/shared": "3.2.47"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@vue/reactivity": {
|
||||||
|
"version": "3.2.47",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.47.tgz",
|
||||||
|
"integrity": "sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==",
|
||||||
|
"requires": {
|
||||||
|
"@vue/shared": "3.2.47"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@vue/reactivity-transform": {
|
||||||
|
"version": "3.2.47",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz",
|
||||||
|
"integrity": "sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/parser": "^7.16.4",
|
||||||
|
"@vue/compiler-core": "3.2.47",
|
||||||
|
"@vue/shared": "3.2.47",
|
||||||
|
"estree-walker": "^2.0.2",
|
||||||
|
"magic-string": "^0.25.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@vue/runtime-core": {
|
||||||
|
"version": "3.2.47",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.47.tgz",
|
||||||
|
"integrity": "sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==",
|
||||||
|
"requires": {
|
||||||
|
"@vue/reactivity": "3.2.47",
|
||||||
|
"@vue/shared": "3.2.47"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@vue/runtime-dom": {
|
||||||
|
"version": "3.2.47",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz",
|
||||||
|
"integrity": "sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==",
|
||||||
|
"requires": {
|
||||||
|
"@vue/runtime-core": "3.2.47",
|
||||||
|
"@vue/shared": "3.2.47",
|
||||||
|
"csstype": "^2.6.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@vue/server-renderer": {
|
||||||
|
"version": "3.2.47",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.47.tgz",
|
||||||
|
"integrity": "sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==",
|
||||||
|
"requires": {
|
||||||
|
"@vue/compiler-ssr": "3.2.47",
|
||||||
|
"@vue/shared": "3.2.47"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@vue/shared": {
|
||||||
|
"version": "3.2.47",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz",
|
||||||
|
"integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ=="
|
||||||
|
},
|
||||||
"axios": {
|
"axios": {
|
||||||
"version": "0.19.2",
|
"version": "0.19.2",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
|
||||||
@ -20,6 +147,11 @@
|
|||||||
"follow-redirects": "1.5.10"
|
"follow-redirects": "1.5.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"csstype": {
|
||||||
|
"version": "2.6.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz",
|
||||||
|
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
|
||||||
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||||
@ -28,6 +160,11 @@
|
|||||||
"ms": "2.0.0"
|
"ms": "2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"estree-walker": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
||||||
|
},
|
||||||
"follow-redirects": {
|
"follow-redirects": {
|
||||||
"version": "1.5.10",
|
"version": "1.5.10",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||||
@ -36,16 +173,82 @@
|
|||||||
"debug": "=3.1.0"
|
"debug": "=3.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"magic-string": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
|
||||||
|
"requires": {
|
||||||
|
"sourcemap-codec": "^1.4.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mitt": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ=="
|
||||||
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||||
},
|
},
|
||||||
"typescript": {
|
"nanoid": {
|
||||||
"version": "4.5.5",
|
"version": "3.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
|
||||||
"integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
|
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw=="
|
||||||
|
},
|
||||||
|
"picocolors": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
|
||||||
|
},
|
||||||
|
"postcss": {
|
||||||
|
"version": "8.4.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz",
|
||||||
|
"integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
|
||||||
|
"requires": {
|
||||||
|
"nanoid": "^3.3.4",
|
||||||
|
"picocolors": "^1.0.0",
|
||||||
|
"source-map-js": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"source-map": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||||
|
},
|
||||||
|
"source-map-js": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
|
||||||
|
},
|
||||||
|
"sourcemap-codec": {
|
||||||
|
"version": "1.4.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
|
||||||
|
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="
|
||||||
|
},
|
||||||
|
"to-fast-properties": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
|
||||||
"dev": true
|
"dev": true
|
||||||
|
},
|
||||||
|
"typescript": {
|
||||||
|
"version": "4.9.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
|
||||||
|
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"vue": {
|
||||||
|
"version": "3.2.47",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue/-/vue-3.2.47.tgz",
|
||||||
|
"integrity": "sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==",
|
||||||
|
"requires": {
|
||||||
|
"@vue/compiler-dom": "3.2.47",
|
||||||
|
"@vue/compiler-sfc": "3.2.47",
|
||||||
|
"@vue/runtime-dom": "3.2.47",
|
||||||
|
"@vue/server-renderer": "3.2.47",
|
||||||
|
"@vue/shared": "3.2.47"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
package.json
21
package.json
@ -1,15 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@jdbernard/vue-common",
|
"name": "@jdbernard/vue-common",
|
||||||
"version": "1.0.0",
|
"version": "1.0.7",
|
||||||
"description": "Extra stuff I always use when building Vue applications.",
|
"description": "Extra stuff I always use when building Vue applications.",
|
||||||
"main": "dist/index.js",
|
"main": "index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "index.d.ts",
|
||||||
"files": [
|
|
||||||
"/dist"
|
|
||||||
],
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc --build tsconfig.json",
|
"build": "tsc --build tsconfig.json && cp -r src/components dist/.",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"do-publish": "npm run build && cp package.json dist/. && (cd dist && npm publish)"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -24,9 +22,12 @@
|
|||||||
"author": "Jonathan Bernard <jonathan@jdbernard.com>",
|
"author": "Jonathan Bernard <jonathan@jdbernard.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^4.5.5"
|
"@babel/types": "^7.21.0",
|
||||||
|
"typescript": "^4.9.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jdbernard/logging": "^1.1.3"
|
"@jdbernard/logging": "^1.1.3",
|
||||||
|
"mitt": "^3.0.0",
|
||||||
|
"vue": "^3.2.47"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
src/components/FaIcon.vue
Normal file
21
src/components/FaIcon.vue
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<span class="fa-icon"><FontAwesomeIcon :icon="icon" :spin="spin" /> </span>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'FaIcon',
|
||||||
|
components: { FontAwesomeIcon },
|
||||||
|
props: { icon: String, spin: Boolean },
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.fa-icon {
|
||||||
|
display: inline-block;
|
||||||
|
height: 1em;
|
||||||
|
text-align: center;
|
||||||
|
width: 1.2em;
|
||||||
|
}
|
||||||
|
</style>
|
33
src/components/FaIconButton.vue
Normal file
33
src/components/FaIconButton.vue
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<button class="fa-icon"><FontAwesomeIcon :icon="icon" :spin="spin" /></button>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'FaIcon',
|
||||||
|
components: { FontAwesomeIcon },
|
||||||
|
props: { icon: String, spin: Boolean },
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.fa-icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
border-radius: 1em;
|
||||||
|
height: 2em;
|
||||||
|
width: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-icon.inline {
|
||||||
|
background: none;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--color-accent-fg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
180
src/components/Toaster.vue
Normal file
180
src/components/Toaster.vue
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
<template>
|
||||||
|
<transition-group name="toast-messages" id="toast-container" tag="ul">
|
||||||
|
<li v-for="msg in messages" :key="msg.id" :class="msg.type">
|
||||||
|
<div class="icon" @click="dismissMessage(msg.id)">
|
||||||
|
<fa-icon :icon="iconForMsg(msg)"></fa-icon>
|
||||||
|
</div>
|
||||||
|
<div class="message">
|
||||||
|
{{ msg.message }}
|
||||||
|
<div v-if="msg.detail" class="detail">{{ msg.detail }}</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</transition-group>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, onMounted, onUnmounted, ref, Ref } from 'vue';
|
||||||
|
|
||||||
|
import { ToastMessage, toastBus } from '../toast.service';
|
||||||
|
|
||||||
|
interface ToastMessageWithTypeAndId extends ToastMessage {
|
||||||
|
type: 'info' | 'error' | 'success';
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'ToasterComponent',
|
||||||
|
setup: function ToasterComponent() {
|
||||||
|
const lastId = ref(0);
|
||||||
|
const messages: Ref<ToastMessageWithTypeAndId[]> = ref([]);
|
||||||
|
|
||||||
|
function dismissMessage(msgId: number) {
|
||||||
|
messages.value = messages.value.filter((m) => m.id !== msgId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleToast(
|
||||||
|
type: 'info' | 'error' | 'success',
|
||||||
|
m: ToastMessage
|
||||||
|
): void {
|
||||||
|
const msgWithId = { ...m, type, id: lastId.value++ };
|
||||||
|
messages.value.push(msgWithId);
|
||||||
|
|
||||||
|
if (m.duration != 'manual') {
|
||||||
|
setTimeout(() => {
|
||||||
|
dismissMessage(msgWithId.id);
|
||||||
|
}, m.duration ?? 10 * 1000); //default 10 seconds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
toastBus.on('info', (m) => handleToast('info', m));
|
||||||
|
toastBus.on('success', (m) => handleToast('success', m));
|
||||||
|
toastBus.on('error', (m) => handleToast('error', m));
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
toastBus.all.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
function iconForMsg(m: ToastMessageWithTypeAndId): string {
|
||||||
|
if (m.icon) return m.icon;
|
||||||
|
switch (m.type) {
|
||||||
|
default:
|
||||||
|
case 'info':
|
||||||
|
return 'info-circle';
|
||||||
|
case 'error':
|
||||||
|
return 'exclamation-triangle';
|
||||||
|
case 'success':
|
||||||
|
return 'check-circle';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { dismissMessage, iconForMsg, messages };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss" src="./Toaster.scss">
|
||||||
|
#toast-container {
|
||||||
|
list-style: none;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
li {
|
||||||
|
transition: opacity 1s, transform 1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast-messages-enter, .toast-messages-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(1em);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//@include forSize(notMobile) {
|
||||||
|
#toast-container {
|
||||||
|
position: fixed;
|
||||||
|
top: 2em;
|
||||||
|
right: 2em;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: stretch;
|
||||||
|
|
||||||
|
background-color: white;
|
||||||
|
background-color: var(--color-bg);
|
||||||
|
border-radius: 4px;
|
||||||
|
border: solid 2px;
|
||||||
|
box-shadow: 0 4px 4px rgba(0, 0, 0, 0.2);
|
||||||
|
box-shadow: 0 4px 4px var(--color-shadow);
|
||||||
|
margin-bottom: 1em;
|
||||||
|
opacity: 0.95;
|
||||||
|
width: 23em;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 1.5em;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 2em;
|
||||||
|
min-height: 2em;
|
||||||
|
|
||||||
|
.fa-icon {
|
||||||
|
color: white;
|
||||||
|
color: var(--color-bg);
|
||||||
|
height: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 0.5em;
|
||||||
|
flex: 1 1;
|
||||||
|
|
||||||
|
.detail {
|
||||||
|
font-size: 16px;
|
||||||
|
font-size: var(--font-size-small);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.info {
|
||||||
|
border-color: #787AC9;
|
||||||
|
border-color: var(--color-accent-fg);
|
||||||
|
color: #333;
|
||||||
|
color: var(--color-fg);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
background-color: #787AC9;
|
||||||
|
background-color: var(--color-accent-fg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.success {
|
||||||
|
border-color: #467A43;
|
||||||
|
border-color: var(--color-success-fg);
|
||||||
|
color: #333;
|
||||||
|
color: var(--color-fg);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
background-color: #467A43;
|
||||||
|
background-color: var(--color-success-fg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
border-color: #AC190E;
|
||||||
|
border-color: var(--color-error-fg);
|
||||||
|
color: #333;
|
||||||
|
color: var(--color-fg);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
background-color: #AC190E;
|
||||||
|
background-color: var(--color-error-fg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
</style>
|
@ -1,3 +1,4 @@
|
|||||||
export * from './state';
|
export * from './state';
|
||||||
export * from './util';
|
export * from './util';
|
||||||
export * from './sorting';
|
export * from './sorting';
|
||||||
|
export { default as defaultDependencyInjector, DependencyInjector } from './injector';
|
||||||
|
17
src/injector.ts
Normal file
17
src/injector.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { InjectionKey } from 'vue';
|
||||||
|
|
||||||
|
export class DependencyInjector {
|
||||||
|
// TODO: can we type this better?
|
||||||
|
// eslint-disable-next-line
|
||||||
|
private deps = new Map<InjectionKey<any>, any>();
|
||||||
|
|
||||||
|
public provide<T>(key: InjectionKey<T>, dep: T): void {
|
||||||
|
this.deps.set(key, dep);
|
||||||
|
}
|
||||||
|
|
||||||
|
public inject<T>(key: InjectionKey<T>): T | undefined {
|
||||||
|
return this.deps.get(key) as T;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new DependencyInjector();
|
16
src/toast.service.ts
Normal file
16
src/toast.service.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import mitt from 'mitt';
|
||||||
|
|
||||||
|
export interface ToastMessage {
|
||||||
|
detail?: string;
|
||||||
|
duration?: number | 'manual';
|
||||||
|
icon?: string;
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToastEvents = {
|
||||||
|
info: ToastMessage;
|
||||||
|
error: ToastMessage;
|
||||||
|
success: ToastMessage;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const toastBus = mitt<ToastEvents>();
|
Loading…
x
Reference in New Issue
Block a user