also looking at this
chore(deps): update dependency react to 19.2.7
#2137
222 files
+16350
-1825
Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.
| @@ -1,19 +0,0 @@ | ||
| 1 | /* eslint-disable */ | |
| 2 | // @ts-nocheck | |
| 3 | // Generated by unplugin-vue-components | |
| 4 | // Read more: https://github.com/vuejs/core/pull/3399 | |
| 5 | // biome-ignore lint: disable | |
| 6 | export {} | |
| 7 | ||
| 8 | /* prettier-ignore */ | |
| 9 | declare module 'vue' { | |
| 10 | export interface GlobalComponents { | |
| 11 | BarcodeDemo: typeof import('./theme/components/BarcodeDemo.vue')['default'] | |
| 12 | Home: typeof import('./theme/components/Home.vue')['default'] | |
| 13 | HomeContributors: typeof import('./theme/components/HomeContributors.vue')['default'] | |
| 14 | HomeSponsors: typeof import('./theme/components/HomeSponsors.vue')['default'] | |
| 15 | HomeTeam: typeof import('./theme/components/HomeTeam.vue')['default'] | |
| 16 | QRCodeDemo: typeof import('./theme/components/QRCodeDemo.vue')['default'] | |
| 17 | TeamMember: typeof import('./theme/components/TeamMember.vue')['default'] | |
| 18 | } | |
| 19 | } | |
| @@ -1,201 +0,0 @@ | ||
| 1 | import type { HeadConfig } from 'vitepress' | |
| 2 | import { transformerTwoslash } from '@shikijs/vitepress-twoslash' | |
| 3 | import { withPwa } from '@vite-pwa/vitepress' | |
| 4 | import { defineConfig } from 'vitepress' | |
| 5 | import vite from './vite.config' | |
| 6 | ||
| 7 | // https://vitepress.dev/reference/site-config | |
| 8 | ||
| 9 | const analyticsHead: HeadConfig[] = [ | |
| 10 | [ | |
| 11 | 'script', | |
| 12 | { | |
| 13 | 'src': 'https://cdn.usefathom.com/script.js', | |
| 14 | 'data-site': 'PFISGDDM', | |
| 15 | 'defer': '', | |
| 16 | }, | |
| 17 | ], | |
| 18 | ] | |
| 19 | ||
| 20 | const nav = [ | |
| 21 | { text: 'News', link: 'https://stacksjs.org/news' }, | |
| 22 | { | |
| 23 | text: 'Changelog', | |
| 24 | link: 'https://github.com/stacksjs/qrx/blob/main/CHANGELOG.md', | |
| 25 | }, | |
| 26 | // { text: 'Blog', link: 'https://updates.ow3.org' }, | |
| 27 | { | |
| 28 | text: 'Resources', | |
| 29 | items: [ | |
| 30 | { text: 'Team', link: '/team' }, | |
| 31 | { text: 'Showcase', link: '/showcase' }, | |
| 32 | { text: 'Sponsors', link: '/sponsors' }, | |
| 33 | { text: 'Partners', link: '/partners' }, | |
| 34 | { text: 'Postcardware', link: '/postcardware' }, | |
| 35 | { text: 'Stargazers', link: '/stargazers' }, | |
| 36 | { text: 'License', link: '/license' }, | |
| 37 | { | |
| 38 | items: [ | |
| 39 | { | |
| 40 | text: 'Awesome Stacks', | |
| 41 | link: 'https://github.com/stacksjs/awesome-stacks', | |
| 42 | }, | |
| 43 | { | |
| 44 | text: 'Contributing', | |
| 45 | link: 'https://github.com/stacksjs/stacks/blob/main/.github/CONTRIBUTING.md', | |
| 46 | }, | |
| 47 | ], | |
| 48 | }, | |
| 49 | ], | |
| 50 | }, | |
| 51 | ] | |
| 52 | ||
| 53 | const sidebar = [ | |
| 54 | { | |
| 55 | text: 'Get Started', | |
| 56 | items: [ | |
| 57 | { text: 'Intro', link: '/intro' }, | |
| 58 | { text: 'Install', link: '/install' }, | |
| 59 | { text: 'Usage', link: '/usage' }, | |
| 60 | { text: 'Config', link: '/config' }, | |
| 61 | { text: 'Demo', link: '/demo' }, | |
| 62 | ], | |
| 63 | }, | |
| 64 | { | |
| 65 | text: 'API', | |
| 66 | items: [ | |
| 67 | { | |
| 68 | text: 'Barcodes', | |
| 69 | link: '/api/barcode', | |
| 70 | collapsed: false, | |
| 71 | items: [ | |
| 72 | { | |
| 73 | text: 'CODE128', | |
| 74 | link: '/api/barcode/CODE128', | |
| 75 | }, | |
| 76 | { text: 'CODE39', link: '/api/barcode/CODE39' }, | |
| 77 | { | |
| 78 | text: 'EAN / UPC', | |
| 79 | link: '/api/barcode/EAN/', | |
| 80 | items: [ | |
| 81 | { text: 'EAN-13', link: '/api/barcode/EAN/EAN-13' }, | |
| 82 | { text: 'EAN-8', link: '/api/barcode/EAN/EAN-8' }, | |
| 83 | { text: 'EAN-5', link: '/api/barcode/EAN/EAN-5' }, | |
| 84 | { text: 'EAN-2', link: '/api/barcode/EAN/EAN-2' }, | |
| 85 | { text: 'UPC-A', link: '/api/barcode/EAN/UPC-A' }, | |
| 86 | { text: 'UPC-E', link: '/api/barcode/EAN/UPC-E' }, | |
| 87 | ], | |
| 88 | }, | |
| 89 | { text: 'ITF-14', link: '/api/barcode/ITF-14' }, | |
| 90 | { | |
| 91 | text: 'MSI', | |
| 92 | link: '/api/barcode/MSI/', | |
| 93 | items: [ | |
| 94 | { text: 'MSI10', link: '/api/barcode/MSI/MSI10' }, | |
| 95 | { text: 'MSI11', link: '/api/barcode/MSI/MSI11' }, | |
| 96 | { text: 'MSI1010', link: '/api/barcode/MSI/MSI1010' }, | |
| 97 | { text: 'MSI1110', link: '/api/barcode/MSI/MSI1110' }, | |
| 98 | ], | |
| 99 | }, | |
| 100 | { text: 'Pharmacode', link: '/api/barcode/Pharmacode' }, | |
| 101 | { text: 'Codabar', link: '/api/barcode/Codabar' }, | |
| 102 | ], | |
| 103 | }, | |
| 104 | { text: 'QR Codes', link: '/api/qr-code' }, | |
| 105 | ], | |
| 106 | }, | |
| 107 | { text: 'Showcase', link: '/showcase' }, | |
| 108 | ] | |
| 109 | const description = 'TypeScript QR & Barcode generating & reading. Lightweight & powerful.' | |
| 110 | const title = 'qrx | QR & Barcode generating & reading. Lightweight & powerful.' | |
| 111 | ||
| 112 | export default withPwa( | |
| 113 | defineConfig({ | |
| 114 | lang: 'en-US', | |
| 115 | title: 'qrx', | |
| 116 | description, | |
| 117 | metaChunk: true, | |
| 118 | cleanUrls: true, | |
| 119 | lastUpdated: true, | |
| 120 | ||
| 121 | head: [ | |
| 122 | ['link', { rel: 'icon', type: 'image/svg+xml', href: './images/logo-mini.svg' }], | |
| 123 | ['link', { rel: 'icon', type: 'image/png', href: './images/logo.png' }], | |
| 124 | ['meta', { name: 'theme-color', content: '#0A0ABC' }], | |
| 125 | ['meta', { name: 'title', content: title }], | |
| 126 | ['meta', { name: 'description', content: description }], | |
| 127 | ['meta', { name: 'author', content: 'Stacks.js, Inc.' }], | |
| 128 | ['meta', { | |
| 129 | name: 'tags', | |
| 130 | content: 'qrx, typescript, qrcode, barcode, qr, bar, code, generate, read, lightweight, powerful, scanner, reader, decoder, encoder, stacksjs, stacks', | |
| 131 | }], | |
| 132 | ||
| 133 | ['meta', { property: 'og:type', content: 'website' }], | |
| 134 | ['meta', { property: 'og:locale', content: 'en' }], | |
| 135 | ['meta', { property: 'og:title', content: title }], | |
| 136 | ['meta', { property: 'og:description', content: description }], | |
| 137 | ||
| 138 | ['meta', { property: 'og:site_name', content: 'qrx' }], | |
| 139 | ['meta', { property: 'og:image', content: 'https://ts-quick-reaction.netlify.app/images/og-image.png' }], | |
| 140 | ['meta', { property: 'og:url', content: 'https://ts-quick-reaction.netlify.app/' }], | |
| 141 | // ['script', { 'src': 'https://cdn.usefathom.com/script.js', 'data-site': '', 'data-spa': 'auto', 'defer': '' }], | |
| 142 | ...analyticsHead, | |
| 143 | ], | |
| 144 | ||
| 145 | themeConfig: { | |
| 146 | search: { | |
| 147 | provider: 'local', | |
| 148 | }, | |
| 149 | logo: { | |
| 150 | light: './images/logo-transparent.svg', | |
| 151 | dark: './images/logo-white-transparent.svg', | |
| 152 | }, | |
| 153 | ||
| 154 | nav, | |
| 155 | sidebar, | |
| 156 | ||
| 157 | editLink: { | |
| 158 | pattern: 'https://github.com/stacksjs/stacks/edit/main/docs/docs/:path', | |
| 159 | text: 'Edit this page on GitHub', | |
| 160 | }, | |
| 161 | ||
| 162 | footer: { | |
| 163 | message: 'Released under the MIT License.', | |
| 164 | copyright: 'Copyright © 2025-present Stacks.js, Inc.', | |
| 165 | }, | |
| 166 | ||
| 167 | socialLinks: [ | |
| 168 | { icon: 'twitter', link: 'https://twitter.com/stacksjs' }, | |
| 169 | { icon: 'bluesky', link: 'https://bsky.app/profile/chrisbreuer.dev' }, | |
| 170 | { icon: 'github', link: 'https://github.com/stacksjs/qrx' }, | |
| 171 | { icon: 'discord', link: 'https://discord.gg/stacksjs' }, | |
| 172 | ], | |
| 173 | ||
| 174 | // algolia: services.algolia, | |
| 175 | ||
| 176 | // carbonAds: { | |
| 177 | // code: '', | |
| 178 | // placement: '', | |
| 179 | // }, | |
| 180 | }, | |
| 181 | ||
| 182 | pwa: { | |
| 183 | manifest: { | |
| 184 | theme_color: '#0A0ABC', | |
| 185 | }, | |
| 186 | }, | |
| 187 | ||
| 188 | markdown: { | |
| 189 | theme: { | |
| 190 | light: 'github-light', | |
| 191 | dark: 'github-dark', | |
| 192 | }, | |
| 193 | ||
| 194 | codeTransformers: [ | |
| 195 | transformerTwoslash(), | |
| 196 | ], | |
| 197 | }, | |
| 198 | ||
| 199 | vite, | |
| 200 | }), | |
| 201 | ) | |
| @@ -1,123 +0,0 @@ | ||
| 1 | /// <reference types="vite/client" /> | |
| 2 | ||
| 3 | /// <reference lib="webworker" /> | |
| 4 | ||
| 5 | import { CacheableResponsePlugin } from 'workbox-cacheable-response' | |
| 6 | import { ExpirationPlugin } from 'workbox-expiration' | |
| 7 | import { cleanupOutdatedCaches, createHandlerBoundToURL, precacheAndRoute } from 'workbox-precaching' | |
| 8 | import { NavigationRoute, registerRoute } from 'workbox-routing' | |
| 9 | import { NetworkFirst, NetworkOnly, StaleWhileRevalidate } from 'workbox-strategies' | |
| 10 | ||
| 11 | declare let self: ServiceWorkerGlobalScope | |
| 12 | ||
| 13 | const entries = self.__WB_MANIFEST | |
| 14 | ||
| 15 | // self.__WB_MANIFEST is the default injection point | |
| 16 | precacheAndRoute(entries) | |
| 17 | ||
| 18 | // clean old assets | |
| 19 | cleanupOutdatedCaches() | |
| 20 | ||
| 21 | let allowlist: undefined | RegExp[] | |
| 22 | if (import.meta.env.DEV) | |
| 23 | allowlist = [/^\/$/] | |
| 24 | ||
| 25 | if (import.meta.env.PROD) { | |
| 26 | const swPath = self.location.pathname.lastIndexOf('/') | |
| 27 | const base = swPath === 0 ? '/' : self.location.pathname.slice(0, swPath + 1) | |
| 28 | function escapeStringRegexp(value: string) { | |
| 29 | // Escape characters with special meaning either inside or outside character sets. | |
| 30 | // Use a simple backslash escape when it’s always valid, and a `\xnn` escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar. | |
| 31 | return value | |
| 32 | .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') | |
| 33 | .replace(/-/g, '\\x2d') | |
| 34 | } | |
| 35 | allowlist = entries.filter((page) => { | |
| 36 | return typeof page === 'string' | |
| 37 | ? page.endsWith('.html') | |
| 38 | : page.url.endsWith('.html') | |
| 39 | }).map((page) => { | |
| 40 | const url = typeof page === 'string' ? page : page.url | |
| 41 | const regex = url === 'index.html' | |
| 42 | ? escapeStringRegexp(base) | |
| 43 | : escapeStringRegexp(`${base}${url.replace(/\.html$/, '')}`) | |
| 44 | return new RegExp(`^${regex}(\\.html)?$`) | |
| 45 | }) | |
| 46 | registerRoute( | |
| 47 | ({ request, sameOrigin }) => { | |
| 48 | return sameOrigin && request.mode === 'navigate' | |
| 49 | }, | |
| 50 | new NetworkOnly({ | |
| 51 | plugins: [{ | |
| 52 | /* this callback will be called when the fetch call fails */ | |
| 53 | handlerDidError: async () => Response.redirect('404', 302), | |
| 54 | /* this callback will prevent caching the response */ | |
| 55 | cacheWillUpdate: async () => null, | |
| 56 | }], | |
| 57 | }), | |
| 58 | 'GET', | |
| 59 | ) | |
| 60 | // googleapis | |
| 61 | registerRoute( | |
| 62 | /^https:\/\/fonts\.googleapis\.com\/.*/i, | |
| 63 | new NetworkFirst({ | |
| 64 | cacheName: 'google-fonts-cache', | |
| 65 | plugins: [ | |
| 66 | new CacheableResponsePlugin({ statuses: [0, 200] }), | |
| 67 | // we only need a few entries | |
| 68 | new ExpirationPlugin({ | |
| 69 | maxEntries: 10, | |
| 70 | maxAgeSeconds: 60 * 60 * 24 * 365, // <== 365 days | |
| 71 | }), | |
| 72 | ], | |
| 73 | }), | |
| 74 | ) | |
| 75 | // gstatic | |
| 76 | registerRoute( | |
| 77 | /^https:\/\/fonts\.gstatic\.com\/.*/i, | |
| 78 | new StaleWhileRevalidate({ | |
| 79 | cacheName: 'google-fonts-cache', | |
| 80 | plugins: [ | |
| 81 | new CacheableResponsePlugin({ statuses: [0, 200] }), | |
| 82 | // we only need a few entries | |
| 83 | new ExpirationPlugin({ | |
| 84 | maxEntries: 10, | |
| 85 | maxAgeSeconds: 60 * 60 * 24 * 365, // <== 365 days | |
| 86 | }), | |
| 87 | ], | |
| 88 | }), | |
| 89 | ) | |
| 90 | // antfu sponsors | |
| 91 | registerRoute( | |
| 92 | /^https:\/\/cdn\.jsdelivr\.net\/.*/i, | |
| 93 | new NetworkFirst({ | |
| 94 | cacheName: 'jsdelivr-images-cache', | |
| 95 | plugins: [ | |
| 96 | new CacheableResponsePlugin({ statuses: [0, 200] }), | |
| 97 | // we only need a few entries | |
| 98 | new ExpirationPlugin({ | |
| 99 | maxEntries: 10, | |
| 100 | maxAgeSeconds: 60 * 60 * 24 * 7, // <== 7 days | |
| 101 | }), | |
| 102 | ], | |
| 103 | }), | |
| 104 | ) | |
| 105 | } | |
| 106 | ||
| 107 | // to allow work offline | |
| 108 | registerRoute(new NavigationRoute( | |
| 109 | createHandlerBoundToURL('index.html'), | |
| 110 | { allowlist }, | |
| 111 | )) | |
| 112 | ||
| 113 | // Skip-Waiting Service Worker-based solution | |
| 114 | self.addEventListener('activate', async () => { | |
| 115 | // after we've taken over, iterate over all the current clients (windows) | |
| 116 | const clients = await self.clients.matchAll({ type: 'window' }) | |
| 117 | clients.forEach((client) => { | |
| 118 | // ...and refresh each one of them | |
| 119 | client.navigate(client.url) | |
| 120 | }) | |
| 121 | }) | |
| 122 | ||
| 123 | self.skipWaiting() | |
| @@ -1,449 +0,0 @@ | ||
| 1 | <script setup lang="ts"> | |
| 2 | import { barcode } from "ts-qr-codes"; | |
| 3 | import { nextTick, onMounted, ref, watch } from "vue"; | |
| 4 | ||
| 5 | interface BarcodeFormat { | |
| 6 | value: string; | |
| 7 | label: string; | |
| 8 | pattern: RegExp; | |
| 9 | hint: string; | |
| 10 | example: string; | |
| 11 | } | |
| 12 | ||
| 13 | // eslint-disable-next-line no-control-regex | |
| 14 | const patternCode128 = /^[\x00-\x7F\xC8-\xD3]+$/; | |
| 15 | ||
| 16 | const formats: BarcodeFormat[] = [ | |
| 17 | { | |
| 18 | value: "CODE128", | |
| 19 | label: "Code 128", | |
| 20 | pattern: patternCode128, | |
| 21 | hint: "Accepts any ASCII character", | |
| 22 | example: "123ABC", | |
| 23 | }, | |
| 24 | { | |
| 25 | value: "EAN13", | |
| 26 | label: "EAN-13", | |
| 27 | pattern: /^\d{12,13}$/, | |
| 28 | hint: "Must be exactly 12 or 13 digits", | |
| 29 | example: "5901234123457", | |
| 30 | }, | |
| 31 | { | |
| 32 | value: "EAN8", | |
| 33 | label: "EAN-8", | |
| 34 | pattern: /^\d{7,8}$/, | |
| 35 | hint: "Must be exactly 7 or 8 digits", | |
| 36 | example: "96385074", | |
| 37 | }, | |
| 38 | { | |
| 39 | value: "EAN5", | |
| 40 | label: "EAN-5", | |
| 41 | pattern: /^\d{5}$/, | |
| 42 | hint: "Must be exactly 5 digits", | |
| 43 | example: "54495", | |
| 44 | }, | |
| 45 | { | |
| 46 | value: "EAN2", | |
| 47 | label: "EAN-2", | |
| 48 | pattern: /^\d{2}$/, | |
| 49 | hint: "Must be exactly 2 digits", | |
| 50 | example: "53", | |
| 51 | }, | |
| 52 | { | |
| 53 | value: "UPC", | |
| 54 | label: "UPC", | |
| 55 | pattern: /^\d{11,12}$/, | |
| 56 | hint: "Must be exactly 11 or 12 digits", | |
| 57 | example: "123456789012", | |
| 58 | }, | |
| 59 | { | |
| 60 | value: "CODE39", | |
| 61 | label: "Code 39", | |
| 62 | pattern: /^[0-9A-Z\-. $/+%]+$/, | |
| 63 | hint: "Accepts digits, uppercase letters, and special characters: -. $/+%", | |
| 64 | example: "CODE-39", | |
| 65 | }, | |
| 66 | { | |
| 67 | value: "ITF14", | |
| 68 | label: "ITF-14", | |
| 69 | pattern: /^\d{13,14}$/, | |
| 70 | hint: "Must be exactly 13 or 14 digits", | |
| 71 | example: "15400141288763", | |
| 72 | }, | |
| 73 | { | |
| 74 | value: "MSI", | |
| 75 | label: "MSI", | |
| 76 | pattern: /^\d+$/, | |
| 77 | hint: "Accepts only digits", | |
| 78 | example: "123456", | |
| 79 | }, | |
| 80 | { | |
| 81 | value: "MSI10", | |
| 82 | label: "MSI-10", | |
| 83 | pattern: /^\d+$/, | |
| 84 | hint: "Accepts only digits", | |
| 85 | example: "123456", | |
| 86 | }, | |
| 87 | { | |
| 88 | value: "MSI11", | |
| 89 | label: "MSI-11", | |
| 90 | pattern: /^\d+$/, | |
| 91 | hint: "Accepts only digits", | |
| 92 | example: "123456", | |
| 93 | }, | |
| 94 | { | |
| 95 | value: "MSI1010", | |
| 96 | label: "MSI-1010", | |
| 97 | pattern: /^\d+$/, | |
| 98 | hint: "Accepts only digits", | |
| 99 | example: "123456", | |
| 100 | }, | |
| 101 | { | |
| 102 | value: "MSI1110", | |
| 103 | label: "MSI-1110", | |
| 104 | pattern: /^\d+$/, | |
| 105 | hint: "Accepts only digits", | |
| 106 | example: "123456", | |
| 107 | }, | |
| 108 | { | |
| 109 | value: "pharmacode", | |
| 110 | label: "Pharmacode", | |
| 111 | pattern: /^\d+$/, | |
| 112 | hint: "Must be a number between 3 and 131070", | |
| 113 | example: "1234", | |
| 114 | }, | |
| 115 | { | |
| 116 | value: "codabar", | |
| 117 | label: "Codabar", | |
| 118 | pattern: /^[A-D][0-9\-$:/.+]+[A-D]$/, | |
| 119 | hint: "Must start and end with A-D, content can be digits and -$:/.+", | |
| 120 | example: "A12345B", | |
| 121 | }, | |
| 122 | ]; | |
| 123 | ||
| 124 | const error = ref(""); | |
| 125 | const currentFormat = ref(formats[0]); | |
| 126 | const text = ref(formats[0].example); | |
| 127 | const format = ref("CODE128"); | |
| 128 | const width = ref(2); | |
| 129 | const height = ref(100); | |
| 130 | const displayValue = ref(true); | |
| 131 | const fontOptions = ref(""); | |
| 132 | const font = ref("monospace"); | |
| 133 | const textAlign = ref("center"); | |
| 134 | const textPosition = ref("bottom"); | |
| 135 | const textMargin = ref(2); | |
| 136 | const fontSize = ref(20); | |
| 137 | const background = ref("#ffffff"); | |
| 138 | const lineColor = ref("#ffffff"); | |
| 139 | const margin = ref(10); | |
| 140 | ||
| 141 | watch(format, (newFormat) => { | |
| 142 | currentFormat.value = | |
| 143 | formats.find((f) => f.value === newFormat) || formats[0]; | |
| 144 | // Don't automatically change the text when format changes | |
| 145 | }); | |
| 146 | ||
| 147 | const barcodeContainer = ref<HTMLElement | null>(null); | |
| 148 | ||
| 149 | function validateInput(): boolean { | |
| 150 | const format = currentFormat.value; | |
| 151 | if (!format.pattern.test(text.value)) { | |
| 152 | error.value = `Invalid format for ${format.label}. ${format.hint}`; | |
| 153 | return false; | |
| 154 | } | |
| 155 | ||
| 156 | if (format.value === "pharmacode") { | |
| 157 | const num = Number(text.value); | |
| 158 | if (num < 3 || num > 131070) { | |
| 159 | error.value = "Pharmacode must be a number between 3 and 131070"; | |
| 160 | return false; | |
| 161 | } | |
| 162 | } | |
| 163 | ||
| 164 | return true; | |
| 165 | } | |
| 166 | ||
| 167 | function updateBarcode() { | |
| 168 | if (!barcodeContainer.value) return; | |
| 169 | ||
| 170 | error.value = ""; | |
| 171 | ||
| 172 | if (!validateInput()) { | |
| 173 | return; | |
| 174 | } | |
| 175 | ||
| 176 | try { | |
| 177 | // Create SVG element inside container | |
| 178 | const svgElement = document.createElementNS( | |
| 179 | "http://www.w3.org/2000/svg", | |
| 180 | "svg", | |
| 181 | ); | |
| 182 | barcodeContainer.value.innerHTML = ""; | |
| 183 | barcodeContainer.value.appendChild(svgElement); | |
| 184 | ||
| 185 | // Create new barcode | |
| 186 | barcode(svgElement, text.value, { | |
| 187 | format: format.value, | |
| 188 | width: Number(width.value), | |
| 189 | height: Number(height.value), | |
| 190 | displayValue: displayValue.value, | |
| 191 | fontOptions: fontOptions.value, | |
| 192 | font: font.value, | |
| 193 | textAlign: textAlign.value, | |
| 194 | textPosition: textPosition.value, | |
| 195 | textMargin: Number(textMargin.value), | |
| 196 | fontSize: Number(fontSize.value), | |
| 197 | background, | |
| 198 | lineColor: lineColor.value, | |
| 199 | margin: Number(margin.value), | |
| 200 | elementTag: "svg", | |
| 201 | valid: (valid: boolean) => { | |
| 202 | if (!valid) | |
| 203 | error.value = "Invalid barcode input for the selected format"; | |
| 204 | }, | |
| 205 | }); | |
| 206 | } catch (err: any) { | |
| 207 | error.value = err.message || "Error rendering barcode"; | |
| 208 | console.error("Error rendering barcode:", err); | |
| 209 | } | |
| 210 | } | |
| 211 | ||
| 212 | onMounted(() => { | |
| 213 | // Wait for next tick to ensure DOM is ready | |
| 214 | nextTick(() => { | |
| 215 | updateBarcode(); | |
| 216 | }); | |
| 217 | }); | |
| 218 | ||
| 219 | watch( | |
| 220 | [ | |
| 221 | text, | |
| 222 | format, | |
| 223 | width, | |
| 224 | height, | |
| 225 | displayValue, | |
| 226 | fontOptions, | |
| 227 | font, | |
| 228 | textAlign, | |
| 229 | textPosition, | |
| 230 | textMargin, | |
| 231 | fontSize, | |
| 232 | background, | |
| 233 | lineColor, | |
| 234 | margin, | |
| 235 | ], | |
| 236 | () => { | |
| 237 | updateBarcode(); | |
| 238 | }, | |
| 239 | ); | |
| 240 | </script> | |
| 241 | ||
| 242 | <template> | |
| 243 | <div class="barcode-demo"> | |
| 244 | <div class="controls"> | |
| 245 | <div class="control-grid"> | |
| 246 | <!-- Text Input --> | |
| 247 | <div class="input-group full-width"> | |
| 248 | <label for="barcode-text">Text to encode:</label> | |
| 249 | <input | |
| 250 | id="barcode-text" | |
| 251 | v-model="text" | |
| 252 | type="text" | |
| 253 | placeholder="Enter text to encode" | |
| 254 | /> | |
| 255 | </div> | |
| 256 | ||
| 257 | <!-- Format Selection --> | |
| 258 | <div class="input-group"> | |
| 259 | <label for="format">Format:</label> | |
| 260 | <select id="format" v-model="format"> | |
| 261 | <option v-for="fmt in formats" :key="fmt.value" :value="fmt.value"> | |
| 262 | {{ fmt.label }} | |
| 263 | </option> | |
| 264 | </select> | |
| 265 | <div class="format-hint"> | |
| 266 | <p>{{ currentFormat.hint }}</p> | |
| 267 | <p class="example">Example: {{ currentFormat.example }}</p> | |
| 268 | </div> | |
| 269 | </div> | |
| 270 | ||
| 271 | <!-- Display Value Toggle --> | |
| 272 | <div class="input-group checkbox-group"> | |
| 273 | <label> | |
| 274 | <input v-model="displayValue" type="checkbox" /> | |
| 275 | Display Value | |
| 276 | </label> | |
| 277 | </div> | |
| 278 | ||
| 279 | <!-- Width Input --> | |
| 280 | <div class="input-group"> | |
| 281 | <label for="width">Width:</label> | |
| 282 | <input id="width" v-model="width" type="number" min="1" /> | |
| 283 | </div> | |
| 284 | ||
| 285 | <!-- Height Input --> | |
| 286 | <div class="input-group"> | |
| 287 | <label for="height">Height:</label> | |
| 288 | <input id="height" v-model="height" type="number" min="1" /> | |
| 289 | </div> | |
| 290 | ||
| 291 | <!-- Text Position --> | |
| 292 | <div class="input-group"> | |
| 293 | <label for="text-position">Text Position:</label> | |
| 294 | <select id="text-position" v-model="textPosition"> | |
| 295 | <option value="bottom">Bottom</option> | |
| 296 | <option value="top">Top</option> | |
| 297 | </select> | |
| 298 | </div> | |
| 299 | ||
| 300 | <!-- Text Alignment --> | |
| 301 | <div class="input-group"> | |
| 302 | <label for="text-align">Text Alignment:</label> | |
| 303 | <select id="text-align" v-model="textAlign"> | |
| 304 | <option value="center">Center</option> | |
| 305 | <option value="left">Left</option> | |
| 306 | <option value="right">Right</option> | |
| 307 | </select> | |
| 308 | </div> | |
| 309 | ||
| 310 | <!-- Font Size --> | |
| 311 | <div class="input-group"> | |
| 312 | <label for="font-size">Font Size:</label> | |
| 313 | <input id="font-size" v-model="fontSize" type="number" min="1" /> | |
| 314 | </div> | |
| 315 | ||
| 316 | <!-- Margin --> | |
| 317 | <div class="input-group"> | |
| 318 | <label for="margin">Margin:</label> | |
| 319 | <input id="margin" v-model="margin" type="number" min="0" /> | |
| 320 | </div> | |
| 321 | ||
| 322 | <!-- Line Color --> | |
| 323 | <div class="input-group"> | |
| 324 | <label for="line-color">Line Color:</label> | |
| 325 | <input id="line-color" v-model="lineColor" type="color" /> | |
| 326 | </div> | |
| 327 | ||
| 328 | <!-- Background Color --> | |
| 329 | <div class="input-group"> | |
| 330 | <label for="background">Background:</label> | |
| 331 | <input id="background" v-model="background" type="color" /> | |
| 332 | </div> | |
| 333 | </div> | |
| 334 | </div> | |
| 335 | ||
| 336 | <div class="barcode-section"> | |
| 337 | <div v-if="error" class="error-message"> | |
| 338 | {{ error }} | |
| 339 | </div> | |
| 340 | ||
| 341 | <div ref="barcodeContainer" class="barcode-container" /> | |
| 342 | </div> | |
| 343 | </div> | |
| 344 | </template> | |
| 345 | ||
| 346 | <style scoped> | |
| 347 | .barcode-demo { | |
| 348 | padding: 20px; | |
| 349 | max-width: 600px; | |
| 350 | margin: 0 auto; | |
| 351 | } | |
| 352 | ||
| 353 | .controls { | |
| 354 | margin-bottom: 20px; | |
| 355 | } | |
| 356 | ||
| 357 | .control-grid { | |
| 358 | display: grid; | |
| 359 | grid-template-columns: repeat(2, 1fr); | |
| 360 | gap: 15px; | |
| 361 | } | |
| 362 | ||
| 363 | .input-group { | |
| 364 | margin-bottom: 0; | |
| 365 | } | |
| 366 | ||
| 367 | .input-group.full-width { | |
| 368 | grid-column: span 2; | |
| 369 | } | |
| 370 | ||
| 371 | .input-group label { | |
| 372 | display: block; | |
| 373 | margin-bottom: 5px; | |
| 374 | font-weight: 500; | |
| 375 | } | |
| 376 | ||
| 377 | .input-group.checkbox-group { | |
| 378 | display: flex; | |
| 379 | align-items: center; | |
| 380 | padding-top: 24px; | |
| 381 | } | |
| 382 | ||
| 383 | .input-group.checkbox-group label { | |
| 384 | margin-bottom: 0; | |
| 385 | display: flex; | |
| 386 | align-items: center; | |
| 387 | cursor: pointer; | |
| 388 | } | |
| 389 | ||
| 390 | input[type="text"], | |
| 391 | input[type="number"], | |
| 392 | select { | |
| 393 | width: 100%; | |
| 394 | padding: 8px; | |
| 395 | border: 1px solid #ddd; | |
| 396 | border-radius: 4px; | |
| 397 | background-color: white; | |
| 398 | } | |
| 399 | ||
| 400 | input[type="color"] { | |
| 401 | width: 100%; | |
| 402 | padding: 2px; | |
| 403 | border: 1px solid #ddd; | |
| 404 | border-radius: 4px; | |
| 405 | height: 40px; | |
| 406 | background-color: white; | |
| 407 | cursor: pointer; | |
| 408 | } | |
| 409 | ||
| 410 | input[type="checkbox"] { | |
| 411 | margin-right: 8px; | |
| 412 | cursor: pointer; | |
| 413 | } | |
| 414 | ||
| 415 | .barcode-section { | |
| 416 | position: relative; | |
| 417 | } | |
| 418 | ||
| 419 | .format-hint { | |
| 420 | margin-top: 4px; | |
| 421 | font-size: 0.875rem; | |
| 422 | color: #666; | |
| 423 | } | |
| 424 | ||
| 425 | .format-hint .example { | |
| 426 | color: #0066cc; | |
| 427 | margin-top: 2px; | |
| 428 | font-family: monospace; | |
| 429 | } | |
| 430 | ||
| 431 | .error-message { | |
| 432 | color: #dc2626; | |
| 433 | margin-bottom: 15px; | |
| 434 | padding: 8px; | |
| 435 | border: 1px solid #dc2626; | |
| 436 | border-radius: 4px; | |
| 437 | background-color: #fef2f2; | |
| 438 | } | |
| 439 | ||
| 440 | .barcode-container { | |
| 441 | display: flex; | |
| 442 | justify-content: center; | |
| 443 | align-items: center; | |
| 444 | min-height: 256px; | |
| 445 | padding: 20px; | |
| 446 | border: 1px solid #ddd; | |
| 447 | border-radius: 4px; | |
| 448 | } | |
| 449 | </style> | |
| @@ -1,20 +0,0 @@ | ||
| 1 | <script setup lang="ts"> | |
| 2 | import { contributors } from './contributors' | |
| 3 | </script> | |
| 4 | ||
| 5 | <template> | |
| 6 | <div class="vp-doc"> | |
| 7 | <h2 pb-2 pt-5 font-normal op50> | |
| 8 | Contributors | |
| 9 | </h2> | |
| 10 | </div> | |
| 11 | ||
| 12 | <div max-w-200 p-10 text-center text-lg leading-7> | |
| 13 | <div flex="~ wrap gap-1" justify-center> | |
| 14 | <a v-for="{ name, avatar } of contributors" :key="name" :href="`https://github.com/${name}`" m-0 rel="noopener noreferrer" :aria-label="`${name} on GitHub`"> | |
| 15 | <img loading="lazy" :src="avatar" width="40" height="40" h-10 min-h-10 min-w-10 w-10 rounded-full :alt="`${name}'s avatar`"> | |
| 16 | </a> | |
| 17 | </div> | |
| 18 | <br> | |
| 19 | </div> | |
| 20 | </template> | |
| @@ -1,19 +0,0 @@ | ||
| 1 | <template> | |
| 2 | <div class="vp-doc"> | |
| 3 | <h2 pb-2 pt-5 font-normal op50> | |
| 4 | Stacks Sponsors | |
| 5 | </h2> | |
| 6 | </div> | |
| 7 | ||
| 8 | <p id="sponsor" class="mt-5 text-center"> | |
| 9 | <a href="https://github.com/sponsors/chrisbbreuer"> | |
| 10 | <img src="https://cdn.jsdelivr.net/gh/stacksjs/sponsors/sponsorkit/sponsors.svg" class="m-auto"> | |
| 11 | </a> | |
| 12 | </p> | |
| 13 | ||
| 14 | <p class="mt-5 text-center"> | |
| 15 | <a href="https://github.com/sponsors/chrisbbreuer" class="text-xs italic"> | |
| 16 | Click here to become a sponsor. | |
| 17 | </a> | |
| 18 | </p> | |
| 19 | </template> | |
| @@ -1,20 +0,0 @@ | ||
| 1 | <script setup lang="ts"> | |
| 2 | import { coreTeamMembers } from './contributors' | |
| 3 | </script> | |
| 4 | ||
| 5 | <template> | |
| 6 | <div class="vp-doc"> | |
| 7 | <h2 pb-2 pt-5 font-normal op50> | |
| 8 | Meet The Team | |
| 9 | </h2> | |
| 10 | </div> | |
| 11 | ||
| 12 | <div grid="~ cols-2 lg:cols-4 gap-x-3 gap-y-20 items-stretch" p-10> | |
| 13 | <TeamMember | |
| 14 | v-for="c of coreTeamMembers" | |
| 15 | :key="c.github" | |
| 16 | :data="c" | |
| 17 | class="flex flex-col items-center text-center p-4 h-full" | |
| 18 | /> | |
| 19 | </div> | |
| 20 | </template> | |
| @@ -1,117 +0,0 @@ | ||
| 1 | <script setup> | |
| 2 | import { QRCode, QRErrorCorrectLevel } from "ts-qr-codes"; | |
| 3 | import { onMounted, ref, watch } from "vue"; | |
| 4 | ||
| 5 | const text = ref("Hello World!"); | |
| 6 | const errorLevel = ref(QRErrorCorrectLevel.H); | |
| 7 | const useSVG = ref(true); | |
| 8 | const qrContainer = ref(null); | |
| 9 | let qrCode = null; | |
| 10 | ||
| 11 | function updateQRCode() { | |
| 12 | if (!qrContainer.value) return; | |
| 13 | ||
| 14 | if (qrCode) { | |
| 15 | qrCode.clear(); | |
| 16 | } | |
| 17 | ||
| 18 | qrCode = new QRCode(qrContainer.value, { | |
| 19 | text: text.value, | |
| 20 | width: 256, | |
| 21 | height: 256, | |
| 22 | colorDark: "#000000", | |
| 23 | colorLight: "#ffffff", | |
| 24 | correctLevel: Number.parseInt(errorLevel.value), | |
| 25 | useSVG: useSVG.value, | |
| 26 | }); | |
| 27 | } | |
| 28 | ||
| 29 | onMounted(() => { | |
| 30 | updateQRCode(); | |
| 31 | }); | |
| 32 | ||
| 33 | watch([text, errorLevel, useSVG], () => { | |
| 34 | updateQRCode(); | |
| 35 | }); | |
| 36 | </script> | |
| 37 | ||
| 38 | <template> | |
| 39 | <div class="qr-demo"> | |
| 40 | <div class="controls"> | |
| 41 | <div class="input-group"> | |
| 42 | <label for="qr-text">Text to encode:</label> | |
| 43 | <input | |
| 44 | id="qr-text" | |
| 45 | v-model="text" | |
| 46 | type="text" | |
| 47 | placeholder="Enter text to encode" | |
| 48 | /> | |
| 49 | </div> | |
| 50 | ||
| 51 | <div class="input-group"> | |
| 52 | <label for="error-level">Error Correction:</label> | |
| 53 | <select id="error-level" v-model="errorLevel"> | |
| 54 | <option value="1">Level L (7%)</option> | |
| 55 | <option value="0">Level M (15%)</option> | |
| 56 | <option value="3">Level Q (25%)</option> | |
| 57 | <option value="2">Level H (30%)</option> | |
| 58 | </select> | |
| 59 | </div> | |
| 60 | ||
| 61 | <div class="input-group"> | |
| 62 | <label> | |
| 63 | <input v-model="useSVG" type="checkbox" /> | |
| 64 | Use SVG Renderer | |
| 65 | </label> | |
| 66 | </div> | |
| 67 | </div> | |
| 68 | ||
| 69 | <div ref="qrContainer" class="qr-container" /> | |
| 70 | </div> | |
| 71 | </template> | |
| 72 | ||
| 73 | <style scoped> | |
| 74 | .qr-demo { | |
| 75 | padding: 20px; | |
| 76 | max-width: 600px; | |
| 77 | margin: 0 auto; | |
| 78 | } | |
| 79 | ||
| 80 | .controls { | |
| 81 | margin-bottom: 20px; | |
| 82 | } | |
| 83 | ||
| 84 | .input-group { | |
| 85 | margin-bottom: 15px; | |
| 86 | } | |
| 87 | ||
| 88 | .input-group label { | |
| 89 | display: block; | |
| 90 | margin-bottom: 5px; | |
| 91 | font-weight: 500; | |
| 92 | } | |
| 93 | ||
| 94 | input[type="text"] { | |
| 95 | width: 100%; | |
| 96 | padding: 8px; | |
| 97 | border: 1px solid #ddd; | |
| 98 | border-radius: 4px; | |
| 99 | } | |
| 100 | ||
| 101 | select { | |
| 102 | padding: 8px; | |
| 103 | border: 1px solid #ddd; | |
| 104 | border-radius: 4px; | |
| 105 | background-color: white; | |
| 106 | } | |
| 107 | ||
| 108 | .qr-container { | |
| 109 | display: flex; | |
| 110 | justify-content: center; | |
| 111 | align-items: center; | |
| 112 | min-height: 256px; | |
| 113 | padding: 20px; | |
| 114 | border: 1px solid #ddd; | |
| 115 | border-radius: 4px; | |
| 116 | } | |
| 117 | </style> | |
| @@ -1,42 +0,0 @@ | ||
| 1 | <script setup lang="ts"> | |
| 2 | import type { CoreTeam } from './contributors' | |
| 3 | ||
| 4 | defineProps<{ | |
| 5 | data: CoreTeam | |
| 6 | }>() | |
| 7 | </script> | |
| 8 | ||
| 9 | <template> | |
| 10 | <div text-center> | |
| 11 | <img | |
| 12 | loading="lazy" | |
| 13 | width="100" height="100" m-auto h-25 min-h-25 min-w-25 w-25 rounded-full | |
| 14 | :src="data.avatar" | |
| 15 | :alt="`${data.name}'s avatar`" | |
| 16 | > | |
| 17 | <div mb-1 mt-2 text-xl> | |
| 18 | {{ data.name }} | |
| 19 | </div> | |
| 20 | <div h-80px op60 v-html="data.description" /> | |
| 21 | ||
| 22 | <div flex="~ inline gap-2" py2 text-2xl> | |
| 23 | <a | |
| 24 | class="i-carbon-logo-github mya inline-block text-current op30 transition duration-200 hover:op100" | |
| 25 | :href="`https://github.com/${data.github}`" | |
| 26 | target="_blank" | |
| 27 | rel="noopener noreferrer" | |
| 28 | :aria-label="`${data.name} on GitHub`" | |
| 29 | /> | |
| 30 | ||
| 31 | <a | |
| 32 | v-if="data.sponsors" | |
| 33 | class="i-carbon-favorite-filled mya inline-block text-current op30 transition duration-200 hover:op100" | |
| 34 | :href="`https://github.com/sponsors/${data.github}`" | |
| 35 | target="_blank" | |
| 36 | rel="noopener noreferrer" | |
| 37 | :title="`Sponsor ${data.name}`" | |
| 38 | :aria-label="`Sponsor ${data.name}`" | |
| 39 | /> | |
| 40 | </div> | |
| 41 | </div> | |
| 42 | </template> | |
| @@ -1,85 +0,0 @@ | ||
| 1 | import contributors from './contributors.json' | |
| 2 | ||
| 3 | export interface Contributor { | |
| 4 | name: string | |
| 5 | avatar: string | |
| 6 | } | |
| 7 | ||
| 8 | export interface CoreTeam { | |
| 9 | avatar: string | |
| 10 | name: string | |
| 11 | github: string | |
| 12 | twitter?: string | |
| 13 | bluesky?: string | |
| 14 | sponsors?: boolean | |
| 15 | description: string | |
| 16 | packages?: string[] | |
| 17 | functions?: string[] | |
| 18 | } | |
| 19 | ||
| 20 | const contributorsAvatars: Record<string, string> = {} | |
| 21 | ||
| 22 | function getAvatarUrl(name: string) { | |
| 23 | return `https://avatars.githubusercontent.com/${name}?v=4` | |
| 24 | } | |
| 25 | ||
| 26 | const contributorList = (Object.keys(contributors) as string[]).reduce((acc, name) => { | |
| 27 | contributorsAvatars[name] = getAvatarUrl(name) | |
| 28 | ||
| 29 | if (contributors[name]) { | |
| 30 | acc.push({ name, avatar: contributorsAvatars[name] }) | |
| 31 | } | |
| 32 | ||
| 33 | return acc | |
| 34 | }, [] as Contributor[]) | |
| 35 | ||
| 36 | const coreTeamMembers: CoreTeam[] = [ | |
| 37 | { | |
| 38 | avatar: contributorsAvatars.chrisbbreuer || 'default-avatar.png', | |
| 39 | name: 'Chris Breuer', | |
| 40 | github: 'chrisbbreuer', | |
| 41 | twitter: 'chrisbbreuer', | |
| 42 | bluesky: 'chrisbreuer.dev', | |
| 43 | sponsors: true, | |
| 44 | description: 'Open sourceror.<br>Core Stacks team.<br>Working at Stacks.js', | |
| 45 | packages: ['core'], | |
| 46 | functions: ['cloud', 'backend', 'frontend', 'ci/cd'], | |
| 47 | }, | |
| 48 | { | |
| 49 | avatar: contributorsAvatars.glennmichael123 || 'default-avatar.png', | |
| 50 | name: 'Glenn', | |
| 51 | github: 'glennmichael123', | |
| 52 | twitter: 'glennmichael123', | |
| 53 | sponsors: false, | |
| 54 | packages: ['core'], | |
| 55 | functions: ['backend', 'frontend', 'desktop'], | |
| 56 | description: 'Open sourceror.<br>Core Stacks team.<br>Working at Stacks.js', | |
| 57 | }, | |
| 58 | ||
| 59 | { | |
| 60 | avatar: contributorsAvatars['cab-mikee'] || 'default-avatar.png', | |
| 61 | name: 'Mike', | |
| 62 | github: 'cab-mikee', | |
| 63 | twitter: 'cab-mikee', | |
| 64 | sponsors: false, | |
| 65 | description: 'Open sourceror.<br>Core Stacks team.<br>Working at Stacks.js', | |
| 66 | packages: ['core'], | |
| 67 | functions: ['backend', 'frontend'], | |
| 68 | }, | |
| 69 | ||
| 70 | { | |
| 71 | avatar: contributorsAvatars.konkonam || 'default-avatar.png', | |
| 72 | name: 'Zoltan', | |
| 73 | github: 'konkonam', | |
| 74 | sponsors: true, | |
| 75 | description: 'Open sourceror.<br>Core Stacks team.', | |
| 76 | packages: ['core'], | |
| 77 | functions: ['backend', 'frontend', 'desktop'], | |
| 78 | }, | |
| 79 | ] | |
| 80 | .sort((pre, cur) => { | |
| 81 | const contribute = Object.keys(contributors) | |
| 82 | return contribute.findIndex(name => name === pre.github) - contribute.findIndex(name => name === cur.github) | |
| 83 | }) | |
| 84 | ||
| 85 | export { contributorList as contributors, coreTeamMembers } | |
| @@ -1,24 +0,0 @@ | ||
| 1 | import type { Theme } from 'vitepress' | |
| 2 | import TwoSlashFloatingVue from '@shikijs/vitepress-twoslash/client' | |
| 3 | import DefaultTheme from 'vitepress/theme' | |
| 4 | import { h } from 'vue' | |
| 5 | ||
| 6 | import 'uno.css' | |
| 7 | ||
| 8 | import './styles/main.css' | |
| 9 | import './styles/vars.css' | |
| 10 | import './styles/overrides.css' | |
| 11 | ||
| 12 | export default { | |
| 13 | ...DefaultTheme, | |
| 14 | ||
| 15 | enhanceApp(ctx: any) { | |
| 16 | ctx.app.use(TwoSlashFloatingVue) | |
| 17 | }, | |
| 18 | ||
| 19 | Layout: () => { | |
| 20 | return h(DefaultTheme.Layout, null, { | |
| 21 | // https://vitepress.dev/guide/extending-default-theme#layout-slots | |
| 22 | }) | |
| 23 | }, | |
| 24 | } satisfies Theme | |
| @@ -1,31 +0,0 @@ | ||
| 1 | html.dark { | |
| 2 | color-scheme: dark; | |
| 3 | } | |
| 4 | ||
| 5 | .vp-doc h2 { | |
| 6 | border-top: 0; | |
| 7 | margin-top: 10px; | |
| 8 | } | |
| 9 | ||
| 10 | .VPMenuLink .link { | |
| 11 | line-height: 28px !important; | |
| 12 | } | |
| 13 | ||
| 14 | .VPSidebarGroup .link { | |
| 15 | padding: 3px 0 !important; | |
| 16 | } | |
| 17 | ||
| 18 | .vp-doc a:has(> code) { | |
| 19 | text-decoration: none; | |
| 20 | color: var(--vp-c-brand-1); | |
| 21 | } | |
| 22 | ||
| 23 | .vp-doc a:has(> code):hover { | |
| 24 | text-decoration: underline; | |
| 25 | } | |
| 26 | ||
| 27 | #app a:focus-visible, | |
| 28 | #app button:focus-visible, | |
| 29 | #app input[type='checkbox']:focus-visible { | |
| 30 | --at-apply: outline-1 outline-primary ring-2 ring-primary; | |
| 31 | } | |
| @@ -1,104 +0,0 @@ | ||
| 1 | /** | |
| 2 | * Colors | |
| 3 | * -------------------------------------------------------------------------- */ | |
| 4 | ||
| 5 | :root { | |
| 6 | --vp-c-brand-1: #2563eb; | |
| 7 | --vp-c-brand-2: #1e40af; | |
| 8 | --vp-c-brand-3: #172554; | |
| 9 | --vp-c-brand-soft: #2563eb50; | |
| 10 | ||
| 11 | --vp-c-text-dark-1: #ffffff; /* Adding this to ensure light text */ | |
| 12 | ||
| 13 | --vp-c-text-code: #4a72bf; | |
| 14 | ||
| 15 | --vp-code-block-bg: rgba(125, 125, 125, 0.04); | |
| 16 | --vp-code-copy-code-bg: rgba(125, 125, 125, 0.1); | |
| 17 | --vp-code-copy-code-hover-bg: rgba(125, 125, 125, 0.2); | |
| 18 | ||
| 19 | --vp-c-disabled-bg: rgba(125, 125, 125, 0.2); | |
| 20 | --vp-c-text-light-2: rgba(56 56 56 / 70%); | |
| 21 | --vp-c-text-dark-2: rgba(56 56 56 / 70%); | |
| 22 | ||
| 23 | --vp-custom-block-info-bg: transparent; | |
| 24 | --vp-custom-block-tip-bg: transparent; | |
| 25 | ||
| 26 | --vp-custom-block-warning-bg: #d9a40605; | |
| 27 | --vp-custom-block-warning-text: #d9a406; | |
| 28 | --vp-custom-block-warning-border: #d9a40630; | |
| 29 | ||
| 30 | --vp-custom-block-tip-bg: #2563eb05; | |
| 31 | --vp-custom-block-tip-text: #2563eb; | |
| 32 | --vp-custom-block-tip-border: #2563eb30; | |
| 33 | ||
| 34 | --vp-code-color: #4a72bf; | |
| 35 | } | |
| 36 | ||
| 37 | .dark { | |
| 38 | --vp-code-block-bg: var(--vp-c-bg-alt); | |
| 39 | --vp-c-text-code: #93c5fd; | |
| 40 | --vp-c-text-dark-2: rgba(235, 235, 235, 0.6); | |
| 41 | } | |
| 42 | ||
| 43 | /** | |
| 44 | * Component: Code | |
| 45 | * -------------------------------------------------------------------------- */ | |
| 46 | ||
| 47 | :root { | |
| 48 | --vp-code-line-highlight-color: rgba(125, 125, 125, 0.2); | |
| 49 | } | |
| 50 | ||
| 51 | .dark { | |
| 52 | --vp-code-line-highlight-color: rgba(0, 0, 0, 0.5); | |
| 53 | } | |
| 54 | ||
| 55 | /** | |
| 56 | * Component: Button | |
| 57 | * -------------------------------------------------------------------------- */ | |
| 58 | ||
| 59 | :root { | |
| 60 | --vp-button-brand-border: var(--vp-c-brand-1); | |
| 61 | --vp-button-brand-text: var(--vp-c-text-dark-1); | |
| 62 | --vp-button-brand-bg: var(--vp-c-brand-1); | |
| 63 | --vp-button-brand-hover-border: var(--vp-c-brand-2); | |
| 64 | --vp-button-brand-hover-text: var(--vp-c-text-dark-1); | |
| 65 | --vp-button-brand-hover-bg: var(--vp-c-brand-2); | |
| 66 | --vp-button-brand-active-border: var(--vp-c-brand-2); | |
| 67 | --vp-button-brand-active-text: var(--vp-c-text-dark-1); | |
| 68 | --vp-button-brand-active-bg: var(--vp-c-brand-2); | |
| 69 | } | |
| 70 | ||
| 71 | /** | |
| 72 | * Component: Home | |
| 73 | * -------------------------------------------------------------------------- */ | |
| 74 | ||
| 75 | :root { | |
| 76 | --vp-home-hero-name-color: transparent; | |
| 77 | --vp-home-hero-name-background: -webkit-linear-gradient( | |
| 78 | 120deg, | |
| 79 | #1e40af, | |
| 80 | #2563eb | |
| 81 | ); | |
| 82 | --vp-home-hero-image-background-image: linear-gradient(-45deg, #1e40af 50%, #2563eb 50%); | |
| 83 | --vp-home-hero-image-filter: blur(30px); | |
| 84 | } | |
| 85 | ||
| 86 | @media (min-width: 640px) { | |
| 87 | :root { | |
| 88 | --vp-home-hero-image-filter: blur(56px); | |
| 89 | } | |
| 90 | } | |
| 91 | ||
| 92 | @media (min-width: 960px) { | |
| 93 | :root { | |
| 94 | --vp-home-hero-image-filter: blur(60px); | |
| 95 | } | |
| 96 | } | |
| 97 | ||
| 98 | /** | |
| 99 | * Component: Algolia | |
| 100 | * -------------------------------------------------------------------------- */ | |
| 101 | ||
| 102 | /* .DocSearch { | |
| 103 | --docsearch-primary-color: var(--vp-c-brand) !important; | |
| 104 | } */ | |
| @@ -1,40 +0,0 @@ | ||
| 1 | import { | |
| 2 | defineConfig, | |
| 3 | presetAttributify, | |
| 4 | presetIcons, | |
| 5 | presetUno, | |
| 6 | transformerDirectives, | |
| 7 | transformerVariantGroup, | |
| 8 | } from 'unocss' | |
| 9 | ||
| 10 | export default defineConfig({ | |
| 11 | shortcuts: { | |
| 12 | 'border-main': 'border-$vp-c-divider', | |
| 13 | 'bg-main': 'bg-gray-400', | |
| 14 | 'bg-base': 'bg-white dark:bg-hex-1a1a1a', | |
| 15 | }, | |
| 16 | ||
| 17 | presets: [ | |
| 18 | presetUno(), | |
| 19 | presetAttributify(), | |
| 20 | presetIcons({ | |
| 21 | scale: 1.2, | |
| 22 | warn: true, | |
| 23 | }), | |
| 24 | ], | |
| 25 | ||
| 26 | theme: { | |
| 27 | colors: { | |
| 28 | primary: '#3eaf7c', | |
| 29 | }, | |
| 30 | ||
| 31 | fontFamily: { | |
| 32 | mono: 'var(--vp-font-family-mono)', | |
| 33 | }, | |
| 34 | }, | |
| 35 | ||
| 36 | transformers: [ | |
| 37 | transformerDirectives(), | |
| 38 | transformerVariantGroup(), | |
| 39 | ], | |
| 40 | }) | |
| @@ -1,60 +0,0 @@ | ||
| 1 | import { resolve } from "node:path"; | |
| 2 | // import Inspect from 'vite-plugin-inspect' | |
| 3 | import UnoCSS from "unocss/vite"; | |
| 4 | import IconsResolver from "unplugin-icons/resolver"; | |
| 5 | import Icons from "unplugin-icons/vite"; | |
| 6 | import Components from "unplugin-vue-components/vite"; | |
| 7 | import { defineConfig } from "vite"; | |
| 8 | ||
| 9 | export default defineConfig({ | |
| 10 | build: { | |
| 11 | assetsDir: "assets", | |
| 12 | rollupOptions: { | |
| 13 | output: { | |
| 14 | assetFileNames: "assets/[name].[hash][extname]", | |
| 15 | }, | |
| 16 | }, | |
| 17 | }, | |
| 18 | ||
| 19 | resolve: { | |
| 20 | alias: { | |
| 21 | "ts-qr-codes": resolve(__dirname, "../../packages/qrx/src/index.ts"), | |
| 22 | }, | |
| 23 | dedupe: ["vue", "@vue/runtime-core"], | |
| 24 | }, | |
| 25 | ||
| 26 | plugins: [ | |
| 27 | // custom | |
| 28 | // MarkdownTransform(), | |
| 29 | // Contributors(contributions), | |
| 30 | ||
| 31 | // plugins | |
| 32 | Components({ | |
| 33 | dirs: resolve(__dirname, "theme/components"), | |
| 34 | include: [/\.vue$/, /\.vue\?vue/, /\.md$/], | |
| 35 | resolvers: [ | |
| 36 | IconsResolver({ | |
| 37 | componentPrefix: "", | |
| 38 | }), | |
| 39 | ], | |
| 40 | dts: resolve(__dirname, "components.d.ts"), | |
| 41 | transformer: "vue3", | |
| 42 | }), | |
| 43 | ||
| 44 | Icons({ | |
| 45 | compiler: "vue3", | |
| 46 | defaultStyle: "display: inline-block", | |
| 47 | }), | |
| 48 | ||
| 49 | UnoCSS(resolve(__dirname, "unocss.config.ts")), | |
| 50 | ||
| 51 | // Inspect(), | |
| 52 | ], | |
| 53 | ||
| 54 | optimizeDeps: { | |
| 55 | exclude: [ | |
| 56 | // 'vue', | |
| 57 | "body-scroll-lock", | |
| 58 | ], | |
| 59 | }, | |
| 60 | }); | |