From 356705fc319e686a0bef40589f873bff7b621e32 Mon Sep 17 00:00:00 2001 From: pa Date: Mon, 5 Jan 2026 20:16:16 +0900 Subject: [PATCH] init shadcn-vue --- components.json | 20 ++ package-lock.json | 299 ++++++++++++++++-- package.json | 9 +- src/app.css | 8 +- src/components/ui/button/Button.vue | 24 ++ src/components/ui/button/index.js | 35 ++ .../ui/dropdown-menu/DropdownMenu.vue | 23 ++ .../DropdownMenuCheckboxItem.vue | 48 +++ .../ui/dropdown-menu/DropdownMenuContent.vue | 66 ++++ .../ui/dropdown-menu/DropdownMenuGroup.vue | 14 + .../ui/dropdown-menu/DropdownMenuItem.vue | 36 +++ .../ui/dropdown-menu/DropdownMenuLabel.vue | 28 ++ .../dropdown-menu/DropdownMenuRadioGroup.vue | 21 ++ .../dropdown-menu/DropdownMenuRadioItem.vue | 49 +++ .../dropdown-menu/DropdownMenuSeparator.vue | 21 ++ .../ui/dropdown-menu/DropdownMenuShortcut.vue | 18 ++ .../ui/dropdown-menu/DropdownMenuSub.vue | 21 ++ .../dropdown-menu/DropdownMenuSubContent.vue | 56 ++++ .../dropdown-menu/DropdownMenuSubTrigger.vue | 34 ++ .../ui/dropdown-menu/DropdownMenuTrigger.vue | 20 ++ src/components/ui/dropdown-menu/index.js | 16 + src/components/ui/pagination/Pagination.vue | 33 ++ .../ui/pagination/PaginationContent.vue | 24 ++ .../ui/pagination/PaginationEllipsis.vue | 27 ++ .../ui/pagination/PaginationFirst.vue | 36 +++ .../ui/pagination/PaginationItem.vue | 35 ++ .../ui/pagination/PaginationLast.vue | 36 +++ .../ui/pagination/PaginationNext.vue | 36 +++ .../ui/pagination/PaginationPrevious.vue | 36 +++ src/components/ui/pagination/index.js | 8 + src/components/ui/table/Table.vue | 15 + src/components/ui/table/TableBody.vue | 13 + src/components/ui/table/TableCaption.vue | 13 + src/components/ui/table/TableCell.vue | 20 ++ src/components/ui/table/TableEmpty.vue | 26 ++ src/components/ui/table/TableFooter.vue | 13 + src/components/ui/table/TableHead.vue | 20 ++ src/components/ui/table/TableHeader.vue | 13 + src/components/ui/table/TableRow.vue | 15 + src/components/ui/table/index.js | 9 + src/components/ui/table/utils.js | 7 + src/components/ui/tooltip/Tooltip.vue | 22 ++ src/components/ui/tooltip/TooltipContent.vue | 60 ++++ src/components/ui/tooltip/TooltipProvider.vue | 18 ++ src/components/ui/tooltip/TooltipTrigger.vue | 15 + src/components/ui/tooltip/index.js | 4 + src/lib/utils.js | 6 + .../scss => styles}/animated-emoji.css | 0 src/{assets/scss => styles}/flags.css | 0 src/{assets/scss => styles}/fonts.css | 0 src/styles/globals.css | 123 +++++++ src/{assets/scss => styles}/noty.css | 0 .../themes/_theme.dark_styles.scss | 0 .../scss => styles}/themes/app_legacy.scss | 10 +- .../scss => styles}/themes/theme.amoled.scss | 4 +- .../scss => styles}/themes/theme.dark.scss | 4 +- .../themes/theme.darkblue.scss | 4 +- .../themes/theme.darkvanilla.scss | 0 .../themes/theme.darkvanillaold.scss | 0 .../themes/theme.material3.scss | 0 .../scss => styles}/themes/theme.pink.scss | 0 src/vite.config.js | 5 + src/vr/vr.css | 4 +- src/jsconfig.json => tsconfig.app.json | 11 +- tsconfig.json | 17 + jsconfig.json => tsconfig.node.json | 12 +- 66 files changed, 1567 insertions(+), 53 deletions(-) create mode 100644 components.json create mode 100644 src/components/ui/button/Button.vue create mode 100644 src/components/ui/button/index.js create mode 100644 src/components/ui/dropdown-menu/DropdownMenu.vue create mode 100644 src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue create mode 100644 src/components/ui/dropdown-menu/DropdownMenuContent.vue create mode 100644 src/components/ui/dropdown-menu/DropdownMenuGroup.vue create mode 100644 src/components/ui/dropdown-menu/DropdownMenuItem.vue create mode 100644 src/components/ui/dropdown-menu/DropdownMenuLabel.vue create mode 100644 src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue create mode 100644 src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue create mode 100644 src/components/ui/dropdown-menu/DropdownMenuSeparator.vue create mode 100644 src/components/ui/dropdown-menu/DropdownMenuShortcut.vue create mode 100644 src/components/ui/dropdown-menu/DropdownMenuSub.vue create mode 100644 src/components/ui/dropdown-menu/DropdownMenuSubContent.vue create mode 100644 src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue create mode 100644 src/components/ui/dropdown-menu/DropdownMenuTrigger.vue create mode 100644 src/components/ui/dropdown-menu/index.js create mode 100644 src/components/ui/pagination/Pagination.vue create mode 100644 src/components/ui/pagination/PaginationContent.vue create mode 100644 src/components/ui/pagination/PaginationEllipsis.vue create mode 100644 src/components/ui/pagination/PaginationFirst.vue create mode 100644 src/components/ui/pagination/PaginationItem.vue create mode 100644 src/components/ui/pagination/PaginationLast.vue create mode 100644 src/components/ui/pagination/PaginationNext.vue create mode 100644 src/components/ui/pagination/PaginationPrevious.vue create mode 100644 src/components/ui/pagination/index.js create mode 100644 src/components/ui/table/Table.vue create mode 100644 src/components/ui/table/TableBody.vue create mode 100644 src/components/ui/table/TableCaption.vue create mode 100644 src/components/ui/table/TableCell.vue create mode 100644 src/components/ui/table/TableEmpty.vue create mode 100644 src/components/ui/table/TableFooter.vue create mode 100644 src/components/ui/table/TableHead.vue create mode 100644 src/components/ui/table/TableHeader.vue create mode 100644 src/components/ui/table/TableRow.vue create mode 100644 src/components/ui/table/index.js create mode 100644 src/components/ui/table/utils.js create mode 100644 src/components/ui/tooltip/Tooltip.vue create mode 100644 src/components/ui/tooltip/TooltipContent.vue create mode 100644 src/components/ui/tooltip/TooltipProvider.vue create mode 100644 src/components/ui/tooltip/TooltipTrigger.vue create mode 100644 src/components/ui/tooltip/index.js create mode 100644 src/lib/utils.js rename src/{assets/scss => styles}/animated-emoji.css (100%) rename src/{assets/scss => styles}/flags.css (100%) rename src/{assets/scss => styles}/fonts.css (100%) create mode 100644 src/styles/globals.css rename src/{assets/scss => styles}/noty.css (100%) rename src/{assets/scss => styles}/themes/_theme.dark_styles.scss (100%) rename src/{assets/scss => styles}/themes/app_legacy.scss (98%) rename src/{assets/scss => styles}/themes/theme.amoled.scss (99%) rename src/{assets/scss => styles}/themes/theme.dark.scss (98%) rename src/{assets/scss => styles}/themes/theme.darkblue.scss (98%) rename src/{assets/scss => styles}/themes/theme.darkvanilla.scss (100%) rename src/{assets/scss => styles}/themes/theme.darkvanillaold.scss (100%) rename src/{assets/scss => styles}/themes/theme.material3.scss (100%) rename src/{assets/scss => styles}/themes/theme.pink.scss (100%) rename src/jsconfig.json => tsconfig.app.json (71%) create mode 100644 tsconfig.json rename jsconfig.json => tsconfig.node.json (64%) diff --git a/components.json b/components.json new file mode 100644 index 00000000..2639828c --- /dev/null +++ b/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://shadcn-vue.com/schema.json", + "style": "new-york", + "typescript": false, + "tailwind": { + "config": "", + "css": "src/styles/globals.css", + "baseColor": "zinc", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "composables": "@/composables", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib" + }, + "iconLibrary": "lucide" +} diff --git a/package-lock.json b/package-lock.json index 4eba3d8c..c1b6a9e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,8 +7,14 @@ "name": "VRCX", "license": "MIT", "dependencies": { + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", "hazardous": "^0.3.0", - "node-api-dotnet": "^0.9.18" + "lucide-vue-next": "^0.562.0", + "node-api-dotnet": "^0.9.18", + "reka-ui": "^2.7.0", + "tailwind-merge": "^3.4.0", + "tw-animate-css": "^1.4.0" }, "devDependencies": { "@electron/rebuild": "^4.0.2", @@ -23,6 +29,7 @@ "@sentry/vite-plugin": "^4.6.1", "@sentry/vue": "^10.32.1", "@tailwindcss/vite": "^4.1.18", + "@tanstack/vue-table": "^8.21.3", "@types/jest": "^30.0.0", "@types/node": "^25.0.3", "@vitejs/plugin-vue": "^6.0.3", @@ -227,7 +234,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -237,7 +243,6 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -271,7 +276,6 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.28.5" @@ -587,7 +591,6 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -2317,7 +2320,6 @@ "version": "1.7.3", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", - "dev": true, "license": "MIT", "dependencies": { "@floating-ui/utils": "^0.2.10" @@ -2327,7 +2329,6 @@ "version": "1.7.4", "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", - "dev": true, "license": "MIT", "dependencies": { "@floating-ui/core": "^1.7.3", @@ -2338,9 +2339,45 @@ "version": "0.2.10", "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", - "dev": true, "license": "MIT" }, + "node_modules/@floating-ui/vue": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@floating-ui/vue/-/vue-1.1.9.tgz", + "integrity": "sha512-BfNqNW6KA83Nexspgb9DZuz578R7HT8MZw1CfK9I6Ah4QReNWEJsXWHN+SdmOVLNGmTPDi+fDT535Df5PzMLbQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.7.4", + "@floating-ui/utils": "^0.2.10", + "vue-demi": ">=0.13.0" + } + }, + "node_modules/@floating-ui/vue/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/@fontsource-variable/inter": { "version": "5.2.8", "resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.2.8.tgz", @@ -2450,6 +2487,24 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@internationalized/date": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.10.1.tgz", + "integrity": "sha512-oJrXtQiAXLvT9clCf1K4kxp3eKsQhIaZqxEyowkBcsvZDdZkbWrVmnGknxs5flTD0VGsxrxKgBCZty1EzoiMzA==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@internationalized/number": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.5.tgz", + "integrity": "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, "node_modules/@intlify/core-base": { "version": "11.2.8", "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-11.2.8.tgz", @@ -3840,7 +3895,6 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { @@ -5126,6 +5180,21 @@ "@sinonjs/commons": "^3.0.1" } }, + "node_modules/@swc/helpers": { + "version": "0.5.18", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.18.tgz", + "integrity": "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@swc/helpers/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", @@ -5421,6 +5490,66 @@ "vite": "^5.2.0 || ^6 || ^7" } }, + "node_modules/@tanstack/table-core": { + "version": "8.21.3", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.21.3.tgz", + "integrity": "sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/virtual-core": { + "version": "3.13.14", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.13.14.tgz", + "integrity": "sha512-b5Uvd8J2dc7ICeX9SRb/wkCxWk7pUwN214eEPAQsqrsktSKTCmyLxOQWSMgogBByXclZeAdgZ3k4o0fIYUIBqQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/vue-table": { + "version": "8.21.3", + "resolved": "https://registry.npmjs.org/@tanstack/vue-table/-/vue-table-8.21.3.tgz", + "integrity": "sha512-rusRyd77c5tDPloPskctMyPLFEQUeBzxdQ+2Eow4F7gDPlPOB1UnnhzfpdvqZ8ZyX2rRNGmqNnQWm87OI2OQPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tanstack/table-core": "8.21.3" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "vue": ">=3.2" + } + }, + "node_modules/@tanstack/vue-virtual": { + "version": "3.13.14", + "resolved": "https://registry.npmjs.org/@tanstack/vue-virtual/-/vue-virtual-3.13.14.tgz", + "integrity": "sha512-dLKQCWj0uu6Rc1OsTGiClpH75hyf92MvJ9YALAzWdblwImSFnxfXD0mu8yOI7PlxiDAcDA5Pq0Q47YvADAfyfg==", + "license": "MIT", + "dependencies": { + "@tanstack/virtual-core": "3.13.14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "vue": "^2.7.0 || ^3.0.0" + } + }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -5690,7 +5819,6 @@ "version": "0.0.21", "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz", "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==", - "dev": true, "license": "MIT" }, "node_modules/@types/yargs": { @@ -6032,7 +6160,6 @@ "version": "3.5.26", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.26.tgz", "integrity": "sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.28.5", @@ -6046,7 +6173,6 @@ "version": "3.5.26", "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.26.tgz", "integrity": "sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A==", - "dev": true, "license": "MIT", "dependencies": { "@vue/compiler-core": "3.5.26", @@ -6057,7 +6183,6 @@ "version": "3.5.26", "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.26.tgz", "integrity": "sha512-egp69qDTSEZcf4bGOSsprUr4xI73wfrY5oRs6GSgXFTiHrWj4Y3X5Ydtip9QMqiCMCPVwLglB9GBxXtTadJ3mA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.28.5", @@ -6075,7 +6200,6 @@ "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" @@ -6085,7 +6209,6 @@ "version": "3.5.26", "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.26.tgz", "integrity": "sha512-lZT9/Y0nSIRUPVvapFJEVDbEXruZh2IYHMk2zTtEgJSlP5gVOqeWXH54xDKAaFS4rTnDeDBQUYDtxKyoW9FwDw==", - "dev": true, "license": "MIT", "dependencies": { "@vue/compiler-dom": "3.5.26", @@ -6132,7 +6255,6 @@ "version": "3.5.26", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.26.tgz", "integrity": "sha512-9EnYB1/DIiUYYnzlnUBgwU32NNvLp/nhxLXeWRhHUEeWNTn1ECxX8aGO7RTXeX6PPcxe3LLuNBFoJbV4QZ+CFQ==", - "dev": true, "license": "MIT", "dependencies": { "@vue/shared": "3.5.26" @@ -6142,7 +6264,6 @@ "version": "3.5.26", "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.26.tgz", "integrity": "sha512-xJWM9KH1kd201w5DvMDOwDHYhrdPTrAatn56oB/LRG4plEQeZRQLw0Bpwih9KYoqmzaxF0OKSn6swzYi84e1/Q==", - "dev": true, "license": "MIT", "dependencies": { "@vue/reactivity": "3.5.26", @@ -6153,7 +6274,6 @@ "version": "3.5.26", "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.26.tgz", "integrity": "sha512-XLLd/+4sPC2ZkN/6+V4O4gjJu6kSDbHAChvsyWgm1oGbdSO3efvGYnm25yCjtFm/K7rrSDvSfPDgN1pHgS4VNQ==", - "dev": true, "license": "MIT", "dependencies": { "@vue/reactivity": "3.5.26", @@ -6166,7 +6286,6 @@ "version": "3.5.26", "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.26.tgz", "integrity": "sha512-TYKLXmrwWKSodyVuO1WAubucd+1XlLg4set0YoV+Hu8Lo79mp/YMwWV5mC5FgtsDxX3qo1ONrxFaTP1OQgy1uA==", - "dev": true, "license": "MIT", "dependencies": { "@vue/compiler-ssr": "3.5.26", @@ -6180,7 +6299,6 @@ "version": "3.5.26", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.26.tgz", "integrity": "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==", - "dev": true, "license": "MIT" }, "node_modules/@vueuse/core": { @@ -6634,6 +6752,18 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -7543,6 +7673,18 @@ "node": ">= 0.4" } }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, "node_modules/clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -7691,6 +7833,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -8056,7 +8207,6 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, "license": "MIT" }, "node_modules/dayjs": { @@ -8230,6 +8380,12 @@ "node": ">=0.10.0" } }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "license": "MIT" + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -8935,7 +9091,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.0.tgz", "integrity": "sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -9385,7 +9540,6 @@ "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==", - "dev": true, "license": "MIT" }, "node_modules/esutils": { @@ -13984,6 +14138,15 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-vue-next": { + "version": "0.562.0", + "resolved": "https://registry.npmjs.org/lucide-vue-next/-/lucide-vue-next-0.562.0.tgz", + "integrity": "sha512-LN0BLGKMFulv0lnfK29r14DcngRUhIqdcaL0zXTt2o0oS9odlrjCGaU3/X9hIihOjjN8l8e+Y9G/famcNYaI7Q==", + "license": "ISC", + "peerDependencies": { + "vue": ">=3.0.1" + } + }, "node_modules/magic-string": { "version": "0.30.8", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", @@ -14401,7 +14564,6 @@ "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, "funding": [ { "type": "github", @@ -14811,6 +14973,12 @@ "node": ">=0.10.0" } }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "license": "MIT" + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -15113,7 +15281,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, "license": "ISC" }, "node_modules/picomatch": { @@ -15260,7 +15427,6 @@ "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "dev": true, "funding": [ { "type": "opencollective", @@ -15565,6 +15731,63 @@ "node": ">=0.10.0" } }, + "node_modules/reka-ui": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.7.0.tgz", + "integrity": "sha512-m+XmxQN2xtFzBP3OAdIafKq7C8OETo2fqfxcIIxYmNN2Ch3r5oAf6yEYCIJg5tL/yJU2mHqF70dCCekUkrAnXA==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.6.13", + "@floating-ui/vue": "^1.1.6", + "@internationalized/date": "^3.5.0", + "@internationalized/number": "^3.5.0", + "@tanstack/vue-virtual": "^3.12.0", + "@vueuse/core": "^12.5.0", + "@vueuse/shared": "^12.5.0", + "aria-hidden": "^1.2.4", + "defu": "^6.1.4", + "ohash": "^2.0.11" + }, + "peerDependencies": { + "vue": ">= 3.2.0" + } + }, + "node_modules/reka-ui/node_modules/@vueuse/core": { + "version": "12.8.2", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.8.2.tgz", + "integrity": "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==", + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.21", + "@vueuse/metadata": "12.8.2", + "@vueuse/shared": "12.8.2", + "vue": "^3.5.13" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/reka-ui/node_modules/@vueuse/metadata": { + "version": "12.8.2", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.8.2.tgz", + "integrity": "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/reka-ui/node_modules/@vueuse/shared": { + "version": "12.8.2", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.8.2.tgz", + "integrity": "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==", + "license": "MIT", + "dependencies": { + "vue": "^3.5.13" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/remixicon": { "version": "4.8.0", "resolved": "https://registry.npmjs.org/remixicon/-/remixicon-4.8.0.tgz", @@ -17033,7 +17256,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -17476,6 +17698,16 @@ "url": "https://opencollective.com/synckit" } }, + "node_modules/tailwind-merge": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz", + "integrity": "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, "node_modules/tailwindcss": { "version": "4.1.18", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", @@ -17893,9 +18125,17 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", - "dev": true, "license": "0BSD" }, + "node_modules/tw-animate-css": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz", + "integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -17946,7 +18186,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "peer": true, "bin": { @@ -18400,7 +18640,6 @@ "version": "3.5.26", "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.26.tgz", "integrity": "sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==", - "dev": true, "license": "MIT", "peer": true, "dependencies": { diff --git a/package.json b/package.json index b81ed436..a775cbf2 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "@sentry/vite-plugin": "^4.6.1", "@sentry/vue": "^10.32.1", "@tailwindcss/vite": "^4.1.18", + "@tanstack/vue-table": "^8.21.3", "@types/jest": "^30.0.0", "@types/node": "^25.0.3", "@vitejs/plugin-vue": "^6.0.3", @@ -164,7 +165,13 @@ } }, "dependencies": { + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", "hazardous": "^0.3.0", - "node-api-dotnet": "^0.9.18" + "lucide-vue-next": "^0.562.0", + "node-api-dotnet": "^0.9.18", + "reka-ui": "^2.7.0", + "tailwind-merge": "^3.4.0", + "tw-animate-css": "^1.4.0" } } diff --git a/src/app.css b/src/app.css index e3f93df6..7743e26b 100644 --- a/src/app.css +++ b/src/app.css @@ -15,10 +15,10 @@ @import 'noty/lib/noty.css'; @import 'remixicon/fonts/remixicon.css'; -@import './assets/scss/flags.css'; -@import './assets/scss/animated-emoji.css'; -@import './assets/scss/fonts.css'; -@import './assets/scss/noty.css'; +@import './styles/flags.css'; +@import './styles/animated-emoji.css'; +@import './styles/fonts.css'; +@import './styles/noty.css'; :root { --font-western: diff --git a/src/components/ui/button/Button.vue b/src/components/ui/button/Button.vue new file mode 100644 index 00000000..8abe4776 --- /dev/null +++ b/src/components/ui/button/Button.vue @@ -0,0 +1,24 @@ + + + diff --git a/src/components/ui/button/index.js b/src/components/ui/button/index.js new file mode 100644 index 00000000..bbb3f1f8 --- /dev/null +++ b/src/components/ui/button/index.js @@ -0,0 +1,35 @@ +import { cva } from "class-variance-authority"; + +export { default as Button } from "./Button.vue"; + +export const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + outline: + "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: + "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-9 px-4 py-2 has-[>svg]:px-3", + sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", + lg: "h-10 rounded-md px-6 has-[>svg]:px-4", + icon: "size-9", + "icon-sm": "size-8", + "icon-lg": "size-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + }, +); diff --git a/src/components/ui/dropdown-menu/DropdownMenu.vue b/src/components/ui/dropdown-menu/DropdownMenu.vue new file mode 100644 index 00000000..00bc158f --- /dev/null +++ b/src/components/ui/dropdown-menu/DropdownMenu.vue @@ -0,0 +1,23 @@ + + + diff --git a/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue b/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue new file mode 100644 index 00000000..31aa8638 --- /dev/null +++ b/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue @@ -0,0 +1,48 @@ + + + diff --git a/src/components/ui/dropdown-menu/DropdownMenuContent.vue b/src/components/ui/dropdown-menu/DropdownMenuContent.vue new file mode 100644 index 00000000..e8bb882a --- /dev/null +++ b/src/components/ui/dropdown-menu/DropdownMenuContent.vue @@ -0,0 +1,66 @@ + + + diff --git a/src/components/ui/dropdown-menu/DropdownMenuGroup.vue b/src/components/ui/dropdown-menu/DropdownMenuGroup.vue new file mode 100644 index 00000000..3895eaa4 --- /dev/null +++ b/src/components/ui/dropdown-menu/DropdownMenuGroup.vue @@ -0,0 +1,14 @@ + + + diff --git a/src/components/ui/dropdown-menu/DropdownMenuItem.vue b/src/components/ui/dropdown-menu/DropdownMenuItem.vue new file mode 100644 index 00000000..06746819 --- /dev/null +++ b/src/components/ui/dropdown-menu/DropdownMenuItem.vue @@ -0,0 +1,36 @@ + + + diff --git a/src/components/ui/dropdown-menu/DropdownMenuLabel.vue b/src/components/ui/dropdown-menu/DropdownMenuLabel.vue new file mode 100644 index 00000000..83891183 --- /dev/null +++ b/src/components/ui/dropdown-menu/DropdownMenuLabel.vue @@ -0,0 +1,28 @@ + + + diff --git a/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue b/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue new file mode 100644 index 00000000..a21b0e4b --- /dev/null +++ b/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue @@ -0,0 +1,21 @@ + + + diff --git a/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue b/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue new file mode 100644 index 00000000..b467428d --- /dev/null +++ b/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue @@ -0,0 +1,49 @@ + + + diff --git a/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue b/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue new file mode 100644 index 00000000..1afca359 --- /dev/null +++ b/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue @@ -0,0 +1,21 @@ + + + diff --git a/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue b/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue new file mode 100644 index 00000000..07b92ec2 --- /dev/null +++ b/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/components/ui/dropdown-menu/DropdownMenuSub.vue b/src/components/ui/dropdown-menu/DropdownMenuSub.vue new file mode 100644 index 00000000..4063d3d3 --- /dev/null +++ b/src/components/ui/dropdown-menu/DropdownMenuSub.vue @@ -0,0 +1,21 @@ + + + diff --git a/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue b/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue new file mode 100644 index 00000000..8db0cb66 --- /dev/null +++ b/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue @@ -0,0 +1,56 @@ + + + diff --git a/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue b/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue new file mode 100644 index 00000000..991feeee --- /dev/null +++ b/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue @@ -0,0 +1,34 @@ + + + diff --git a/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue b/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue new file mode 100644 index 00000000..0b693a50 --- /dev/null +++ b/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/components/ui/dropdown-menu/index.js b/src/components/ui/dropdown-menu/index.js new file mode 100644 index 00000000..9e57848a --- /dev/null +++ b/src/components/ui/dropdown-menu/index.js @@ -0,0 +1,16 @@ +export { default as DropdownMenu } from "./DropdownMenu.vue"; + +export { default as DropdownMenuCheckboxItem } from "./DropdownMenuCheckboxItem.vue"; +export { default as DropdownMenuContent } from "./DropdownMenuContent.vue"; +export { default as DropdownMenuGroup } from "./DropdownMenuGroup.vue"; +export { default as DropdownMenuItem } from "./DropdownMenuItem.vue"; +export { default as DropdownMenuLabel } from "./DropdownMenuLabel.vue"; +export { default as DropdownMenuRadioGroup } from "./DropdownMenuRadioGroup.vue"; +export { default as DropdownMenuRadioItem } from "./DropdownMenuRadioItem.vue"; +export { default as DropdownMenuSeparator } from "./DropdownMenuSeparator.vue"; +export { default as DropdownMenuShortcut } from "./DropdownMenuShortcut.vue"; +export { default as DropdownMenuSub } from "./DropdownMenuSub.vue"; +export { default as DropdownMenuSubContent } from "./DropdownMenuSubContent.vue"; +export { default as DropdownMenuSubTrigger } from "./DropdownMenuSubTrigger.vue"; +export { default as DropdownMenuTrigger } from "./DropdownMenuTrigger.vue"; +export { DropdownMenuPortal } from "reka-ui"; diff --git a/src/components/ui/pagination/Pagination.vue b/src/components/ui/pagination/Pagination.vue new file mode 100644 index 00000000..7ac2a36a --- /dev/null +++ b/src/components/ui/pagination/Pagination.vue @@ -0,0 +1,33 @@ + + + diff --git a/src/components/ui/pagination/PaginationContent.vue b/src/components/ui/pagination/PaginationContent.vue new file mode 100644 index 00000000..61f78091 --- /dev/null +++ b/src/components/ui/pagination/PaginationContent.vue @@ -0,0 +1,24 @@ + + + diff --git a/src/components/ui/pagination/PaginationEllipsis.vue b/src/components/ui/pagination/PaginationEllipsis.vue new file mode 100644 index 00000000..48e04a64 --- /dev/null +++ b/src/components/ui/pagination/PaginationEllipsis.vue @@ -0,0 +1,27 @@ + + + diff --git a/src/components/ui/pagination/PaginationFirst.vue b/src/components/ui/pagination/PaginationFirst.vue new file mode 100644 index 00000000..8fe158b2 --- /dev/null +++ b/src/components/ui/pagination/PaginationFirst.vue @@ -0,0 +1,36 @@ + + + diff --git a/src/components/ui/pagination/PaginationItem.vue b/src/components/ui/pagination/PaginationItem.vue new file mode 100644 index 00000000..7a6b6ef3 --- /dev/null +++ b/src/components/ui/pagination/PaginationItem.vue @@ -0,0 +1,35 @@ + + + diff --git a/src/components/ui/pagination/PaginationLast.vue b/src/components/ui/pagination/PaginationLast.vue new file mode 100644 index 00000000..7c67efa1 --- /dev/null +++ b/src/components/ui/pagination/PaginationLast.vue @@ -0,0 +1,36 @@ + + + diff --git a/src/components/ui/pagination/PaginationNext.vue b/src/components/ui/pagination/PaginationNext.vue new file mode 100644 index 00000000..40c1ee60 --- /dev/null +++ b/src/components/ui/pagination/PaginationNext.vue @@ -0,0 +1,36 @@ + + + diff --git a/src/components/ui/pagination/PaginationPrevious.vue b/src/components/ui/pagination/PaginationPrevious.vue new file mode 100644 index 00000000..b682259d --- /dev/null +++ b/src/components/ui/pagination/PaginationPrevious.vue @@ -0,0 +1,36 @@ + + + diff --git a/src/components/ui/pagination/index.js b/src/components/ui/pagination/index.js new file mode 100644 index 00000000..349edff7 --- /dev/null +++ b/src/components/ui/pagination/index.js @@ -0,0 +1,8 @@ +export { default as Pagination } from "./Pagination.vue"; +export { default as PaginationContent } from "./PaginationContent.vue"; +export { default as PaginationEllipsis } from "./PaginationEllipsis.vue"; +export { default as PaginationFirst } from "./PaginationFirst.vue"; +export { default as PaginationItem } from "./PaginationItem.vue"; +export { default as PaginationLast } from "./PaginationLast.vue"; +export { default as PaginationNext } from "./PaginationNext.vue"; +export { default as PaginationPrevious } from "./PaginationPrevious.vue"; diff --git a/src/components/ui/table/Table.vue b/src/components/ui/table/Table.vue new file mode 100644 index 00000000..3f558a2d --- /dev/null +++ b/src/components/ui/table/Table.vue @@ -0,0 +1,15 @@ + + + diff --git a/src/components/ui/table/TableBody.vue b/src/components/ui/table/TableBody.vue new file mode 100644 index 00000000..4de6afed --- /dev/null +++ b/src/components/ui/table/TableBody.vue @@ -0,0 +1,13 @@ + + + diff --git a/src/components/ui/table/TableCaption.vue b/src/components/ui/table/TableCaption.vue new file mode 100644 index 00000000..a76cf856 --- /dev/null +++ b/src/components/ui/table/TableCaption.vue @@ -0,0 +1,13 @@ + + + diff --git a/src/components/ui/table/TableCell.vue b/src/components/ui/table/TableCell.vue new file mode 100644 index 00000000..b47a0da1 --- /dev/null +++ b/src/components/ui/table/TableCell.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/components/ui/table/TableEmpty.vue b/src/components/ui/table/TableEmpty.vue new file mode 100644 index 00000000..1529f2ea --- /dev/null +++ b/src/components/ui/table/TableEmpty.vue @@ -0,0 +1,26 @@ + + + diff --git a/src/components/ui/table/TableFooter.vue b/src/components/ui/table/TableFooter.vue new file mode 100644 index 00000000..a029cec1 --- /dev/null +++ b/src/components/ui/table/TableFooter.vue @@ -0,0 +1,13 @@ + + + diff --git a/src/components/ui/table/TableHead.vue b/src/components/ui/table/TableHead.vue new file mode 100644 index 00000000..ab406134 --- /dev/null +++ b/src/components/ui/table/TableHead.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/components/ui/table/TableHeader.vue b/src/components/ui/table/TableHeader.vue new file mode 100644 index 00000000..826d60e1 --- /dev/null +++ b/src/components/ui/table/TableHeader.vue @@ -0,0 +1,13 @@ + + + diff --git a/src/components/ui/table/TableRow.vue b/src/components/ui/table/TableRow.vue new file mode 100644 index 00000000..4fcc52fa --- /dev/null +++ b/src/components/ui/table/TableRow.vue @@ -0,0 +1,15 @@ + + + diff --git a/src/components/ui/table/index.js b/src/components/ui/table/index.js new file mode 100644 index 00000000..c9712165 --- /dev/null +++ b/src/components/ui/table/index.js @@ -0,0 +1,9 @@ +export { default as Table } from './Table.vue'; +export { default as TableBody } from './TableBody.vue'; +export { default as TableCaption } from './TableCaption.vue'; +export { default as TableCell } from './TableCell.vue'; +export { default as TableEmpty } from './TableEmpty.vue'; +export { default as TableFooter } from './TableFooter.vue'; +export { default as TableHead } from './TableHead.vue'; +export { default as TableHeader } from './TableHeader.vue'; +export { default as TableRow } from './TableRow.vue'; diff --git a/src/components/ui/table/utils.js b/src/components/ui/table/utils.js new file mode 100644 index 00000000..e4c44618 --- /dev/null +++ b/src/components/ui/table/utils.js @@ -0,0 +1,7 @@ +import { isFunction } from '@tanstack/vue-table'; + +export function valueUpdater(updaterOrValue, ref) { + ref.value = isFunction(updaterOrValue) + ? updaterOrValue(ref.value) + : updaterOrValue; +} diff --git a/src/components/ui/tooltip/Tooltip.vue b/src/components/ui/tooltip/Tooltip.vue new file mode 100644 index 00000000..15c361bf --- /dev/null +++ b/src/components/ui/tooltip/Tooltip.vue @@ -0,0 +1,22 @@ + + + diff --git a/src/components/ui/tooltip/TooltipContent.vue b/src/components/ui/tooltip/TooltipContent.vue new file mode 100644 index 00000000..a3df1fa4 --- /dev/null +++ b/src/components/ui/tooltip/TooltipContent.vue @@ -0,0 +1,60 @@ + + + diff --git a/src/components/ui/tooltip/TooltipProvider.vue b/src/components/ui/tooltip/TooltipProvider.vue new file mode 100644 index 00000000..e0e03430 --- /dev/null +++ b/src/components/ui/tooltip/TooltipProvider.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/components/ui/tooltip/TooltipTrigger.vue b/src/components/ui/tooltip/TooltipTrigger.vue new file mode 100644 index 00000000..471be21b --- /dev/null +++ b/src/components/ui/tooltip/TooltipTrigger.vue @@ -0,0 +1,15 @@ + + + diff --git a/src/components/ui/tooltip/index.js b/src/components/ui/tooltip/index.js new file mode 100644 index 00000000..0a8a8786 --- /dev/null +++ b/src/components/ui/tooltip/index.js @@ -0,0 +1,4 @@ +export { default as Tooltip } from "./Tooltip.vue"; +export { default as TooltipContent } from "./TooltipContent.vue"; +export { default as TooltipProvider } from "./TooltipProvider.vue"; +export { default as TooltipTrigger } from "./TooltipTrigger.vue"; diff --git a/src/lib/utils.js b/src/lib/utils.js new file mode 100644 index 00000000..a25ae45d --- /dev/null +++ b/src/lib/utils.js @@ -0,0 +1,6 @@ +import { clsx } from 'clsx'; +import { twMerge } from 'tailwind-merge'; + +export function cn(...inputs) { + return twMerge(clsx(inputs)); +} diff --git a/src/assets/scss/animated-emoji.css b/src/styles/animated-emoji.css similarity index 100% rename from src/assets/scss/animated-emoji.css rename to src/styles/animated-emoji.css diff --git a/src/assets/scss/flags.css b/src/styles/flags.css similarity index 100% rename from src/assets/scss/flags.css rename to src/styles/flags.css diff --git a/src/assets/scss/fonts.css b/src/styles/fonts.css similarity index 100% rename from src/assets/scss/fonts.css rename to src/styles/fonts.css diff --git a/src/styles/globals.css b/src/styles/globals.css new file mode 100644 index 00000000..4a684d7e --- /dev/null +++ b/src/styles/globals.css @@ -0,0 +1,123 @@ +@import 'tailwindcss'; +@import 'tw-animate-css'; + +@custom-variant dark (&:is(.dark *)); + +:root { + --background: oklch(1 0 0); + --foreground: oklch(0.145 0 0); + --card: oklch(1 0 0); + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: oklch(0.205 0 0); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.97 0 0); + --secondary-foreground: oklch(0.205 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --accent: oklch(0.97 0 0); + --accent-foreground: oklch(0.205 0 0); + --destructive: oklch(0.577 0.245 27.325); + --destructive-foreground: oklch(0.577 0.245 27.325); + --border: oklch(0.922 0 0); + --input: oklch(0.922 0 0); + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --radius: 0.625rem; + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.145 0 0); + --sidebar-primary: oklch(0.205 0 0); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.97 0 0); + --sidebar-accent-foreground: oklch(0.205 0 0); + --sidebar-border: oklch(0.922 0 0); + --sidebar-ring: oklch(0.708 0 0); +} + +.dark { + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.145 0 0); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.145 0 0); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.985 0 0); + --primary-foreground: oklch(0.205 0 0); + --secondary: oklch(0.269 0 0); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.269 0 0); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.396 0.141 25.723); + --destructive-foreground: oklch(0.637 0.237 25.331); + --border: oklch(0.269 0 0); + --input: oklch(0.269 0 0); + --ring: oklch(0.439 0 0); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.205 0 0); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.269 0 0); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(0.269 0 0); + --sidebar-ring: oklch(0.439 0 0); +} + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-destructive-foreground: var(--destructive-foreground); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/src/assets/scss/noty.css b/src/styles/noty.css similarity index 100% rename from src/assets/scss/noty.css rename to src/styles/noty.css diff --git a/src/assets/scss/themes/_theme.dark_styles.scss b/src/styles/themes/_theme.dark_styles.scss similarity index 100% rename from src/assets/scss/themes/_theme.dark_styles.scss rename to src/styles/themes/_theme.dark_styles.scss diff --git a/src/assets/scss/themes/app_legacy.scss b/src/styles/themes/app_legacy.scss similarity index 98% rename from src/assets/scss/themes/app_legacy.scss rename to src/styles/themes/app_legacy.scss index 12008bf1..fa105e71 100644 --- a/src/assets/scss/themes/app_legacy.scss +++ b/src/styles/themes/app_legacy.scss @@ -11,12 +11,12 @@ @use '../fonts.css'; @use '../flags.css'; @use '../animated-emoji.css'; -@use 'element-plus/theme-chalk/src/index.scss' as *; +@use 'index' as *; -@use 'element-plus/theme-chalk/src/dark/css-vars.scss'; -@use 'animate.css/animate.min.css'; -@use 'noty/lib/noty.css'; -@use 'remixicon/fonts/remixicon.css'; +@use 'css-vars'; +@use '../../../node_modules/animate.css/animate.min.css'; +@use '../../../node_modules/noty/lib/noty.css'; +@use '../../../node_modules/remixicon/fonts/remixicon.css'; :root { --font-western: diff --git a/src/assets/scss/themes/theme.amoled.scss b/src/styles/themes/theme.amoled.scss similarity index 99% rename from src/assets/scss/themes/theme.amoled.scss rename to src/styles/themes/theme.amoled.scss index b1ed9c78..e6749d84 100644 --- a/src/assets/scss/themes/theme.amoled.scss +++ b/src/styles/themes/theme.amoled.scss @@ -59,7 +59,7 @@ $--box-shadow-base: 0 1px 2px hsla($--theme-hue, $--theme-saturation, 0%, 0.1); $--box-shadow-dark: 0 1px 3px hsla($--theme-hue, $--theme-saturation, 0%, 0.15); $--calendar-selected-background-color: rgba($--theme-primary, 0.1); -@forward 'element-plus/theme-chalk/src/common/var.scss' with ( +@forward 'var' with ( $colors: ( 'white': $--theme-text-1, 'black': $--theme-bg-1, @@ -217,7 +217,7 @@ $--card-background-color: $--theme-bg-4; --group-calendar-badge-normal: #{$--theme-info}; } -@import '_theme.dark_styles'; +@import 'theme.dark_styles'; .el-table tr, .el-table td.el-table__cell, diff --git a/src/assets/scss/themes/theme.dark.scss b/src/styles/themes/theme.dark.scss similarity index 98% rename from src/assets/scss/themes/theme.dark.scss rename to src/styles/themes/theme.dark.scss index 776b1c68..33aa8dd5 100644 --- a/src/assets/scss/themes/theme.dark.scss +++ b/src/styles/themes/theme.dark.scss @@ -56,7 +56,7 @@ $--box-shadow-base: 0 1px 2px hsla($--theme-hue, $--theme-saturation, 0%, 0.1); $--box-shadow-dark: 0 1px 3px hsla($--theme-hue, $--theme-saturation, 0%, 0.15); $--calendar-selected-background-color: rgba($--theme-primary, 0.1); -@forward 'element-plus/theme-chalk/src/common/var.scss' with ( +@forward 'var' with ( $colors: ( 'white': $--theme-text-1, 'black': $--theme-bg-1, @@ -211,7 +211,7 @@ $--card-background-color: $--theme-bg-4; --group-calendar-badge-normal: #{$--color-primary}; } -@import '_theme.dark_styles'; +@import 'theme.dark_styles'; .el-calendar { background-color: $--theme-bg-4 !important; diff --git a/src/assets/scss/themes/theme.darkblue.scss b/src/styles/themes/theme.darkblue.scss similarity index 98% rename from src/assets/scss/themes/theme.darkblue.scss rename to src/styles/themes/theme.darkblue.scss index 52034eb2..12a1d902 100644 --- a/src/assets/scss/themes/theme.darkblue.scss +++ b/src/styles/themes/theme.darkblue.scss @@ -56,7 +56,7 @@ $--box-shadow-base: 0 1px 2px hsla($--theme-hue, $--theme-saturation, 0%, 0.1); $--box-shadow-dark: 0 1px 3px hsla($--theme-hue, $--theme-saturation, 0%, 0.15); $--calendar-selected-background-color: rgba($--theme-primary, 0.1); -@forward 'element-plus/theme-chalk/src/common/var.scss' with ( +@forward 'var' with ( $colors: ( 'white': $--theme-text-1, 'black': $--theme-bg-1, @@ -211,7 +211,7 @@ $--card-background-color: $--theme-bg-4; --group-calendar-badge-normal: #{$--color-primary}; } -@import '_theme.dark_styles'; +@import 'theme.dark_styles'; .el-calendar { background-color: $--theme-bg-4 !important; diff --git a/src/assets/scss/themes/theme.darkvanilla.scss b/src/styles/themes/theme.darkvanilla.scss similarity index 100% rename from src/assets/scss/themes/theme.darkvanilla.scss rename to src/styles/themes/theme.darkvanilla.scss diff --git a/src/assets/scss/themes/theme.darkvanillaold.scss b/src/styles/themes/theme.darkvanillaold.scss similarity index 100% rename from src/assets/scss/themes/theme.darkvanillaold.scss rename to src/styles/themes/theme.darkvanillaold.scss diff --git a/src/assets/scss/themes/theme.material3.scss b/src/styles/themes/theme.material3.scss similarity index 100% rename from src/assets/scss/themes/theme.material3.scss rename to src/styles/themes/theme.material3.scss diff --git a/src/assets/scss/themes/theme.pink.scss b/src/styles/themes/theme.pink.scss similarity index 100% rename from src/assets/scss/themes/theme.pink.scss rename to src/styles/themes/theme.pink.scss diff --git a/src/vite.config.js b/src/vite.config.js index 0cd82c23..99609f9d 100644 --- a/src/vite.config.js +++ b/src/vite.config.js @@ -82,6 +82,11 @@ export default defineConfig(({ mode }) => { }) ) ], + resolve: { + alias: { + '@': resolve(import.meta.dirname, '.') + } + }, css: { transformer: 'lightningcss', lightningcss: { diff --git a/src/vr/vr.css b/src/vr/vr.css index b217802f..23d85c89 100644 --- a/src/vr/vr.css +++ b/src/vr/vr.css @@ -12,8 +12,8 @@ @import 'noty/lib/noty.css'; @import 'remixicon/fonts/remixicon.css'; -@import '../assets/scss/flags.css'; -@import '../assets/scss/fonts.css'; +@import '../styles/flags.css'; +@import '../styles/fonts.css'; /* 마지노선인듯 diff --git a/src/jsconfig.json b/tsconfig.app.json similarity index 71% rename from src/jsconfig.json rename to tsconfig.app.json index 859f3280..b9928e67 100644 --- a/src/jsconfig.json +++ b/tsconfig.app.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "composite": true, "module": "ESNext", "target": "ESNext", "allowJs": true, @@ -13,8 +14,12 @@ "lib": ["esnext", "dom", "dom.iterable"], "types": ["vite/client", "element-plus/global"], "resolveJsonModule": true, - "noEmit": true + "noEmit": true, + "paths": { + "*": ["./*"], + "@/*": ["./src/*"] + } }, - "include": ["**/*"], - "exclude": ["../node_modules", "../build", "vite.config.js", "shared/utils/localizationHelperCLI.js"] + "include": ["src/**/*"], + "exclude": ["node_modules", "build"] } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..82aca16a --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,17 @@ +{ + "files": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.node.json" + } + ], + "compilerOptions": { + "paths": { + "*": ["./*"], + "@/*": ["./src/*"] + } + } +} diff --git a/jsconfig.json b/tsconfig.node.json similarity index 64% rename from jsconfig.json rename to tsconfig.node.json index 6765f276..deb5ef4d 100644 --- a/jsconfig.json +++ b/tsconfig.node.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "composite": true, "module": "ESNext", "target": "ESNext", "allowJs": true, @@ -11,8 +12,15 @@ "forceConsistentCasingInFileNames": true, "lib": ["esnext"], "types": ["node"], - "noEmit": true + "noEmit": true, + "paths": { + "*": ["./*"], + "@/*": ["./src/*"] + } }, - "include": ["src/vite.config.js", "src/shared/utils/localizationHelperCLI.js"], + "include": [ + "src/vite.config.js", + "src/shared/utils/localizationHelperCLI.js" + ], "exclude": ["node_modules", "build"] }