diff --git a/.gitignore b/.gitignore index 7f08db7..cc0913e 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ yarn-error.log /.idea /.vscode auth.json +.npmrc diff --git a/package-lock.json b/package-lock.json index 5b6b4e5..52f8570 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "devDependencies": { "@babel/core": "^7.29.0", "@babel/types": "^7.29.0", + "@cyhnkckali/vue3-color-picker": "^2.1.7", "@erbelion/vite-plugin-laravel-purgecss": "^0.2.3", "@fortawesome/fontawesome-svg-core": "^6.5.1", "@fortawesome/free-brands-svg-icons": "^6.5.1", @@ -31,6 +32,7 @@ "axios": "^1.5.1", "bootstrap": "^5.3.2", "chart.js": "^2.0.0", + "colorjs.io": "^0.6.1", "cropperjs": "^1.6.1", "eslint": "^8.23.0", "eslint-import-resolver-alias": "^1.1.2", @@ -799,6 +801,15 @@ "postcss-selector-parser": "^6.0.13" } }, + "node_modules/@cyhnkckali/vue3-color-picker": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@cyhnkckali/vue3-color-picker/-/vue3-color-picker-2.1.7.tgz", + "integrity": "sha512-Vw4IM4aKHbJkNwuLsyVdfLm727uIkazpbFjHFOwsj03J2uZqy4TKwmX+83zHIXp2+ELCXFNULXgbETiFUzS+Eg==", + "dev": true, + "peerDependencies": { + "vue": "^3.3.8" + } + }, "node_modules/@erbelion/vite-plugin-laravel-purgecss": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/@erbelion/vite-plugin-laravel-purgecss/-/vite-plugin-laravel-purgecss-0.2.6.tgz", @@ -3760,6 +3771,17 @@ "dev": true, "license": "MIT" }, + "node_modules/colorjs.io": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.6.1.tgz", + "integrity": "sha512-8lyR2wHzuIykCpqHKgluGsqQi5iDm3/a2IgP2GBZrasn2sBRkE4NOGsglZxWLs/jZQoNkmA/KM/8NV16rLUdBg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/color" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", diff --git a/package.json b/package.json index 1604e68..8796285 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "devDependencies": { "@babel/core": "^7.29.0", "@babel/types": "^7.29.0", + "@cyhnkckali/vue3-color-picker": "^2.1.7", "@erbelion/vite-plugin-laravel-purgecss": "^0.2.3", "@fortawesome/fontawesome-svg-core": "^6.5.1", "@fortawesome/free-brands-svg-icons": "^6.5.1", @@ -40,6 +41,7 @@ "axios": "^1.5.1", "bootstrap": "^5.3.2", "chart.js": "^2.0.0", + "colorjs.io": "^0.6.1", "cropperjs": "^1.6.1", "eslint": "^8.23.0", "eslint-import-resolver-alias": "^1.1.2", diff --git a/resources/ts/bo/components/QrCodeComponent.vue b/resources/ts/bo/components/QrCodeComponent.vue index cb97d03..58054ae 100644 --- a/resources/ts/bo/components/QrCodeComponent.vue +++ b/resources/ts/bo/components/QrCodeComponent.vue @@ -97,16 +97,36 @@ id="margin" > - - +
+
+
+ + +
+
+
+ +
+
@@ -368,6 +388,8 @@ import type { import trans from "../../modules/trans"; import { defineComponent } from "vue"; import ImageInputComponent from "../../bo/components/ImageInputComponent.vue"; +import {Vue3ColorPicker} from "@cyhnkckali/vue3-color-picker"; +import "@cyhnkckali/vue3-color-picker/dist/style.css"; export default defineComponent({ name: "QrCodeComponent", @@ -396,9 +418,11 @@ export default defineComponent({ this.imageLoaded = true; this.qrCode = new QRCodeStyling(this.options); this.qrCode.append(this.$refs.div as HTMLElement); + this.isTransparent = this.options.backgroundOptions.color === "transparent"; }, components: { - ImageInputComponent + ImageInputComponent, + Vue3ColorPicker }, methods: { download() { @@ -412,6 +436,18 @@ export default defineComponent({ this.qrCode.update(this.options); } }, + changeColor(color: string) { + if (!this.isTransparent) { + this.options.backgroundOptions.color = color; + } + }, + toggleTransparency() { + if (this.isTransparent) { + this.options.backgroundOptions.color = "transparent"; + } else { + this.options.backgroundOptions.color = this.pickerColor; + } + } }, props: { id: { @@ -465,6 +501,8 @@ export default defineComponent({ }, extension: FileExtension, qrCode: QRCodeStyling, + isTransparent: boolean, + pickerColor: string, } { return { baseUrl: "", @@ -507,7 +545,9 @@ export default defineComponent({ } }, extension: "png", - qrCode: new QRCodeStyling() + qrCode: new QRCodeStyling(), + isTransparent: false, + pickerColor: "#ffffff", }; }, watch: { @@ -554,6 +594,13 @@ export default defineComponent({ }); this.qrCode.update(this.options); }, + isTransparent(newVal) { + if (newVal) { + this.options.backgroundOptions.color = "transparent"; + } else { + this.options.backgroundOptions.color = this.pickerColor; + } + }, "options.data"() { this.qrCode.update(this.options); }, @@ -622,4 +669,8 @@ export default defineComponent({ } } +#qr-code { + // Apply a color to keep the dots visible when the background is transparent. + background-color: #aaa; +} diff --git a/resources/ts/utilities/sass-safelist.ts b/resources/ts/utilities/sass-safelist.ts index 486731c..7cb120d 100644 --- a/resources/ts/utilities/sass-safelist.ts +++ b/resources/ts/utilities/sass-safelist.ts @@ -6,5 +6,7 @@ const sassSafelist: UserDefinedSafelist = [ /^bs-popover/, /^popover/, /^modal-/, /^bg-/, /^accordion-/, // Vue /-(leave|enter|appear)(|-(to|from|active))$/, /^(?!(|.*?:)cursor-move).+-move$/, /^router-link(|-exact)-active$/, /data-v-.*/, + // Color Picker + /^ck-cp-/, /^cp-/, /^picker-hue-/, /^colour-/ ]; export { sassSafelist };