diff --git a/package-lock.json b/package-lock.json index f2a89b78..6e7e4d8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,6 +40,7 @@ "dayjs": "^1.11.10", "postcss": "^8.4.33", "tailwindcss": "^3.4.1", + "unplugin-vue-components": "^28.7.0", "vue-axios": "^3.5.2" } }, @@ -1985,6 +1986,12 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "node_modules/confbox": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", + "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "dev": true + }, "node_modules/constant-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", @@ -2520,6 +2527,12 @@ "node": ">=0.10.0" } }, + "node_modules/exsolve": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.5.tgz", + "integrity": "sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==", + "dev": true + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3137,6 +3150,23 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/local-pkg": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz", + "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", + "dev": true, + "dependencies": { + "mlly": "^1.7.4", + "pkg-types": "^2.0.1", + "quansync": "^0.2.8" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -3308,6 +3338,35 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mlly": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "dev": true, + "dependencies": { + "acorn": "^8.14.0", + "pathe": "^2.0.1", + "pkg-types": "^1.3.0", + "ufo": "^1.5.4" + } + }, + "node_modules/mlly/node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true + }, + "node_modules/mlly/node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -3575,6 +3634,12 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -3628,6 +3693,17 @@ "node": ">= 6" } }, + "node_modules/pkg-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.0.tgz", + "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==", + "dev": true, + "dependencies": { + "confbox": "^0.2.1", + "exsolve": "^1.0.1", + "pathe": "^2.0.3" + } + }, "node_modules/postcss": { "version": "8.5.4", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz", @@ -3829,6 +3905,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/quansync": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.10.tgz", + "integrity": "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ] + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -4458,6 +4550,48 @@ "node": ">=0.8" } }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4548,6 +4682,101 @@ "typescript": ">=4.8.4 <5.9.0" } }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "dev": true + }, + "node_modules/unplugin": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.5.tgz", + "integrity": "sha512-RyWSb5AHmGtjjNQ6gIlA67sHOsWpsbWpwDokLwTcejVdOjEkJZh7QKu14J00gDDVSh8kGH4KYC/TNBceXFZhtw==", + "dev": true, + "dependencies": { + "acorn": "^8.14.1", + "picomatch": "^4.0.2", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unplugin-utils": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.2.4.tgz", + "integrity": "sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==", + "dev": true, + "dependencies": { + "pathe": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/unplugin-utils/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/unplugin-vue-components": { + "version": "28.7.0", + "resolved": "https://registry.npmjs.org/unplugin-vue-components/-/unplugin-vue-components-28.7.0.tgz", + "integrity": "sha512-3SuWAHlTjOiZckqRBGXRdN/k6IMmKyt2Ch5/+DKwYaT321H0ItdZDvW4r8/YkEKQpN9TN3F/SZ0W342gQROC3Q==", + "dev": true, + "dependencies": { + "chokidar": "^3.6.0", + "debug": "^4.4.1", + "local-pkg": "^1.1.1", + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "tinyglobby": "^0.2.14", + "unplugin": "^2.3.4", + "unplugin-utils": "^0.2.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@babel/parser": "^7.15.8", + "@nuxt/kit": "^3.2.2", + "vue": "2 || 3" + }, + "peerDependenciesMeta": { + "@babel/parser": { + "optional": true + }, + "@nuxt/kit": { + "optional": true + } + } + }, + "node_modules/unplugin/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", @@ -4792,6 +5021,12 @@ "vue": "^3.0.1" } }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 65339ff3..9603b006 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "dayjs": "^1.11.10", "postcss": "^8.4.33", "tailwindcss": "^3.4.1", + "unplugin-vue-components": "^28.7.0", "vue-axios": "^3.5.2" }, "dependencies": { diff --git a/resources/js/app.js b/resources/js/app.js index 9996fb63..dfdfdb3e 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -1,16 +1,15 @@ -import {createApp, h, defineAsyncComponent} from 'vue'; -import {Head, createInertiaApp, Link as ILink} from '@inertiajs/vue3'; +import { createApp, h, defineAsyncComponent } from 'vue'; +import { Head, createInertiaApp, Link as ILink } from '@inertiajs/vue3'; import axios from 'axios'; import VueAxios from 'vue-axios'; -import {Plugin as FloatingVue, options as FloatingVueOptions} from './lib/floatingVue.js'; -import {createPinia, PiniaVuePlugin} from 'pinia'; +import { Plugin as FloatingVue, options as FloatingVueOptions } from './lib/floatingVue.js'; +import { createPinia, PiniaVuePlugin } from 'pinia'; import Echo from './lib/echo.js'; -import requireModules from './lib/requireModules.js'; import AppLayout from './layouts/AppLayout.vue'; import hasModule from './mixins/hasModule.js'; import hasFlash from './mixins/hasFlash.js'; -import {Toast, options as toastOptions, interceptor as toastInterceptor} from './lib/toast.js'; +import { Toast, options as toastOptions, interceptor as toastInterceptor } from './lib/toast.js'; // ---------------------------------- Assets ----------------------------------- import '../css/app.css'; @@ -35,8 +34,8 @@ createInertiaApp({ return page; }, - setup({el, App, props, plugin}) { - var app = createApp({pinia, render: () => h(App, props)}) + setup({ el, App, props, plugin }) { + var app = createApp({ pinia, render: () => h(App, props) }) .use(plugin) .use(FloatingVue, FloatingVueOptions) .use(Toast, toastOptions) @@ -47,9 +46,6 @@ createInertiaApp({ .mixin(hasModule) .mixin(hasFlash); - requireModules(import.meta.glob('./components/form/*.vue'), app, 'f'); - requireModules(import.meta.glob('./components/ui/*.vue'), app, 'ui'); - requireModules(import.meta.glob('./components/page/*.vue', {eager: true}), app, 'page'); app.component( 'FSinglefile', defineAsyncComponent(() => import('!/medialibrary-helper/assets/components/SingleFile.vue')) diff --git a/resources/js/components/components.d.ts b/resources/js/components/components.d.ts new file mode 100644 index 00000000..569cf765 --- /dev/null +++ b/resources/js/components/components.d.ts @@ -0,0 +1,57 @@ +/* eslint-disable */ +// @ts-nocheck +// Generated by unplugin-vue-components +// Read more: https://github.com/vuejs/core/pull/3399 +// biome-ignore lint: disable +export {} + +/* prettier-ignore */ +declare module 'vue' { + export interface GlobalComponents { + FCheckboxesLabel: typeof import('@/components/form/CheckboxesLabel.vue')['default'] + FEditor: typeof import('@/components/form/Editor.vue')['default'] + FHint: typeof import('@/components/form/Hint.vue')['default'] + FLabel: typeof import('@/components/form/Label.vue')['default'] + FMemberFilter: typeof import('@/components/form/MemberFilter.vue')['default'] + FMultipleselect: typeof import('@/components/form/Multipleselect.vue')['default'] + FSaveButton: typeof import('@/components/form/SaveButton.vue')['default'] + FSelect: typeof import('@/components/form/Select.vue')['default'] + FSwitch: typeof import('@/components/form/Switch.vue')['default'] + FText: typeof import('@/components/form/Text.vue')['default'] + FTextarea: typeof import('@/components/form/Textarea.vue')['default'] + PageFilter: typeof import('@/components/page/Filter.vue')['default'] + PageFullHeading: typeof import('@/components/page/FullHeading.vue')['default'] + PageFullHeadingBanner: typeof import('@/components/page/FullHeadingBanner.vue')['default'] + PageFullLayout: typeof import('@/components/page/FullLayout.vue')['default'] + PageHeader: typeof import('@/components/page/Header.vue')['default'] + PageLayout: typeof import('@/components/page/Layout.vue')['default'] + PageSearchModal: typeof import('@/components/page/SearchModal.vue')['default'] + PageTitle: typeof import('@/components/page/Title.vue')['default'] + PageToolbarButton: typeof import('@/components/page/ToolbarButton.vue')['default'] + UiActionButton: typeof import('@/components/ui/ActionButton.vue')['default'] + UiAgeGroups: typeof import('@/components/ui/AgeGroups.vue')['default'] + UiBool: typeof import('@/components/ui/Bool.vue')['default'] + UiBooleanDisplay: typeof import('@/components/ui/BooleanDisplay.vue')['default'] + UiBox: typeof import('@/components/ui/Box.vue')['default'] + UiButton: typeof import('@/components/ui/Button.vue')['default'] + UiFilterSidebar: typeof import('@/components/ui/FilterSidebar.vue')['default'] + UiIconButton: typeof import('@/components/ui/IconButton.vue')['default'] + UiLabel: typeof import('@/components/ui/Label.vue')['default'] + UiLoading: typeof import('@/components/ui/Loading.vue')['default'] + UiMenulist: typeof import('@/components/ui/Menulist.vue')['default'] + UiNote: typeof import('@/components/ui/Note.vue')['default'] + UiPagination: typeof import('@/components/ui/Pagination.vue')['default'] + UiPopup: typeof import('@/components/ui/Popup.vue')['default'] + UiRemoteResource: typeof import('@/components/ui/RemoteResource.vue')['default'] + UiRemoteSelector: typeof import('@/components/ui/RemoteSelector.vue')['default'] + UiSearchPagination: typeof import('@/components/ui/SearchPagination.vue')['default'] + UiSearchResult: typeof import('@/components/ui/SearchResult.vue')['default'] + UiSidebar: typeof import('@/components/ui/Sidebar.vue')['default'] + UiSpinner: typeof import('@/components/ui/Spinner.vue')['default'] + UiSprite: typeof import('@/components/ui/Sprite.vue')['default'] + UiTableToggleButton: typeof import('@/components/ui/TableToggleButton.vue')['default'] + UiTabs: typeof import('@/components/ui/Tabs.vue')['default'] + UiTextDisplay: typeof import('@/components/ui/TextDisplay.vue')['default'] + UiTh: typeof import('@/components/ui/Th.vue')['default'] + } +} diff --git a/resources/js/lib/requireModules.js b/resources/js/lib/requireModules.js deleted file mode 100644 index 1424accb..00000000 --- a/resources/js/lib/requireModules.js +++ /dev/null @@ -1,10 +0,0 @@ -import {paramCase} from 'change-case'; -import {defineAsyncComponent} from 'vue'; - -export default function (context, app, prefix) { - for (const file in context) { - let componentName = paramCase(`${prefix}${file.replace(/^.*\/(.*?)\.vue$/g, '$1')}`); - - app.component(componentName, typeof context[file] === 'function' ? defineAsyncComponent(context[file]) : context[file].default); - } -} diff --git a/tsconfig.json b/tsconfig.json index c609b540..0046706b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -54,6 +54,10 @@ "forceConsistentCasingInFileNames": true, // See "skipLibCheck": true, - "types": ["vite/client"] - } + "types": ["vite/client"], + "paths": { + "@/*": ["./resources/js/*"] + } + }, + "include": ["**/*", "resources/js/components/components.d.ts"] } diff --git a/vite.config.js b/vite.config.js index c7d9e4c1..7aea33ff 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,10 +1,40 @@ -import {defineConfig} from 'vite'; +import { defineConfig } from 'vite'; import laravel from 'laravel-vite-plugin'; import vue from '@vitejs/plugin-vue'; import path from 'path'; +import Components from 'unplugin-vue-components/vite' export default defineConfig({ plugins: [ + Components({ + globs: [], + directives: false, + directoryAsNamespace: false, + types: [], + dts: 'resources/js/components/components.d.ts', + resolvers: [ + (componentName) => { + if (componentName === 'FMultiplefiles') { + return; + } + if (componentName === 'FSinglefile') { + return; + } + if (componentName.startsWith('Ui')) { + let singleComponentName = componentName.replace(/^Ui/, ''); + return { name: 'default', from: `@/components/ui/${singleComponentName}.vue` }; + } + if (componentName.startsWith('F')) { + let singleComponentName = componentName.replace(/^F/, ''); + return { name: 'default', from: `@/components/form/${singleComponentName}.vue` }; + } + if (componentName.startsWith('Page')) { + let singleComponentName = componentName.replace(/^Page/, ''); + return { name: 'default', from: `@/components/page/${singleComponentName}.vue` }; + } + }, + ] + }), laravel(['resources/js/app.js']), vue({ template: {