vuetify-nuxt-module 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +106 -93
- package/configuration.d.ts +6 -6
- package/dist/module.d.ts +2 -3
- package/dist/module.json +1 -1
- package/dist/module.mjs +32 -28
- package/dist/runtime/plugins/i18n.d.ts +20 -0
- package/dist/runtime/plugins/i18n.mjs +136 -0
- package/dist/runtime/plugins/vuetify-i18n.mts +9 -0
- package/dist/runtime/{templates/plugin.mts → plugins/vuetify.mts} +30 -30
- package/package.json +16 -7
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2023-PRESENT Joaquín Sánchez <https://github.com/userquin>
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023-PRESENT Joaquín Sánchez <https://github.com/userquin>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,93 +1,106 @@
|
|
|
1
|
-
<p align='center'>
|
|
2
|
-
<img src='./hero.svg' alt="vuetify-nuxt-module - Zero-config Nuxt module for Vuetify"><br>
|
|
3
|
-
Zero-config Nuxt module for Vuetify
|
|
4
|
-
</p>
|
|
5
|
-
|
|
6
|
-
<p align='center'>
|
|
7
|
-
<a href='https://www.npmjs.com/package/vuetify-nuxt-module' target="__blank">
|
|
8
|
-
<img src='https://img.shields.io/npm/v/vuetify-nuxt-module?color=33A6B8&label=' alt="NPM version">
|
|
9
|
-
</a>
|
|
10
|
-
<a href="https://www.npmjs.com/package/vuetify-nuxt-module" target="__blank">
|
|
11
|
-
<img alt="NPM Downloads" src="https://img.shields.io/npm/dm/vuetify-nuxt-module?color=476582&label=">
|
|
12
|
-
</a>
|
|
13
|
-
<!--
|
|
14
|
-
<a href="https://vite-pwa-org.netlify.app/frameworks/nuxt" target="__blank">
|
|
15
|
-
<img src="https://img.shields.io/static/v1?label=&message=docs%20%26%20guides&color=2e859c" alt="Docs & Guides">
|
|
16
|
-
</a>
|
|
17
|
-
-->
|
|
18
|
-
<br>
|
|
19
|
-
<a href="https://github.com/userquin/vuetify-nuxt-module" target="__blank">
|
|
20
|
-
<img alt="GitHub stars" src="https://img.shields.io/github/stars/userquin/vuetify-nuxt-module?style=social">
|
|
21
|
-
</a>
|
|
22
|
-
</p>
|
|
23
|
-
|
|
24
|
-
<br>
|
|
25
|
-
|
|
26
|
-
## 🚀 Features
|
|
27
|
-
|
|
28
|
-
- 📖 [**Documentation & guides**](README.md#-features) (WIP)
|
|
29
|
-
- 👌 **Zero-Config**: sensible built-in default [Vuetify](https://vuetifyjs.com/) configuration for common use cases
|
|
30
|
-
- 🔩 **Extensible**: expose the ability to customize the Vuetify configuration via [Nuxt Plugin Hooks](https://nuxt.com/docs/guide/going-further/hooks#usage-with-plugins)
|
|
31
|
-
- ⚡ **Fully tree shakable**: by default, only the needed Vuetify components are imported
|
|
32
|
-
- 🛠️ **Versatile**: custom Vuetify [directives](https://vuetifyjs.com/en/getting-started/installation/#manual-steps) and [labs components](https://vuetifyjs.com/en/labs/introduction/) registration
|
|
33
|
-
- ✨ **Configurable styles**: configure your variables using [Vuetify SASS Variables](https://vuetifyjs.com/en/features/sass-variables/)
|
|
34
|
-
- 💥 **SSR**: automatic SSR detection and configuration
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
yarn
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
pnpm
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
1
|
+
<p align='center'>
|
|
2
|
+
<img src='./hero.svg' alt="vuetify-nuxt-module - Zero-config Nuxt module for Vuetify"><br>
|
|
3
|
+
Zero-config Nuxt module for Vuetify
|
|
4
|
+
</p>
|
|
5
|
+
|
|
6
|
+
<p align='center'>
|
|
7
|
+
<a href='https://www.npmjs.com/package/vuetify-nuxt-module' target="__blank">
|
|
8
|
+
<img src='https://img.shields.io/npm/v/vuetify-nuxt-module?color=33A6B8&label=' alt="NPM version">
|
|
9
|
+
</a>
|
|
10
|
+
<a href="https://www.npmjs.com/package/vuetify-nuxt-module" target="__blank">
|
|
11
|
+
<img alt="NPM Downloads" src="https://img.shields.io/npm/dm/vuetify-nuxt-module?color=476582&label=">
|
|
12
|
+
</a>
|
|
13
|
+
<!--
|
|
14
|
+
<a href="https://vite-pwa-org.netlify.app/frameworks/nuxt" target="__blank">
|
|
15
|
+
<img src="https://img.shields.io/static/v1?label=&message=docs%20%26%20guides&color=2e859c" alt="Docs & Guides">
|
|
16
|
+
</a>
|
|
17
|
+
-->
|
|
18
|
+
<br>
|
|
19
|
+
<a href="https://github.com/userquin/vuetify-nuxt-module" target="__blank">
|
|
20
|
+
<img alt="GitHub stars" src="https://img.shields.io/github/stars/userquin/vuetify-nuxt-module?style=social">
|
|
21
|
+
</a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
<br>
|
|
25
|
+
|
|
26
|
+
## 🚀 Features
|
|
27
|
+
|
|
28
|
+
- 📖 [**Documentation & guides**](README.md#-features) (WIP)
|
|
29
|
+
- 👌 **Zero-Config**: sensible built-in default [Vuetify](https://vuetifyjs.com/) configuration for common use cases
|
|
30
|
+
- 🔩 **Extensible**: expose the ability to customize the Vuetify configuration via [Nuxt Plugin Hooks](https://nuxt.com/docs/guide/going-further/hooks#usage-with-plugins)
|
|
31
|
+
- ⚡ **Fully tree shakable**: by default, only the needed Vuetify components are imported
|
|
32
|
+
- 🛠️ **Versatile**: custom Vuetify [directives](https://vuetifyjs.com/en/getting-started/installation/#manual-steps) and [labs components](https://vuetifyjs.com/en/labs/introduction/) registration
|
|
33
|
+
- ✨ **Configurable styles**: configure your variables using [Vuetify SASS Variables](https://vuetifyjs.com/en/features/sass-variables/)
|
|
34
|
+
- 💥 **SSR**: automatic SSR detection and configuration
|
|
35
|
+
- 🌍 **I18n ready**: install [@nuxtjs/i18n](https://v8.i18n.nuxtjs.org/) Nuxt module, and you're ready to use Vuetify [internationalization](https://vuetifyjs.com/en/features/internationalization/) features
|
|
36
|
+
- 🦾 **Type Strong**: written in [TypeScript](https://www.typescriptlang.org/)
|
|
37
|
+
|
|
38
|
+
## 📦 Install
|
|
39
|
+
|
|
40
|
+
> Requires Vite, will not work with Webpack
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm i vuetify-nuxt-module -D
|
|
44
|
+
|
|
45
|
+
# yarn
|
|
46
|
+
yarn add vuetify-nuxt-module -D
|
|
47
|
+
|
|
48
|
+
# pnpm
|
|
49
|
+
pnpm add vuetify-nuxt-module -D
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## 🦄 Usage
|
|
53
|
+
|
|
54
|
+
> `vuetify-nuxt-module` is strongly opinionated and has a built-in default configuration out of the box. You can use it without any configuration, and it will work for most use cases.
|
|
55
|
+
|
|
56
|
+
Add `vuetify-nuxt-module` module to `nuxt.config.ts` and configure it:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
// nuxt.config.ts
|
|
60
|
+
import { defineNuxtConfig } from 'nuxt/config'
|
|
61
|
+
|
|
62
|
+
export default defineNuxtConfig({
|
|
63
|
+
modules: [
|
|
64
|
+
'vuetify-nuxt-module'
|
|
65
|
+
],
|
|
66
|
+
vuetify: {
|
|
67
|
+
moduleOptions: {
|
|
68
|
+
/* module specific options */
|
|
69
|
+
},
|
|
70
|
+
vuetifyOptions: {
|
|
71
|
+
/* vuetify options */
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 🌍 I18n support
|
|
78
|
+
|
|
79
|
+
> Requires latest [@nuxtjs/i18n](https://v8.i18n.nuxtjs.org/) Nuxt module: `8.0.0.beta.12`.
|
|
80
|
+
|
|
81
|
+
There is a [bug](https://github.com/nuxt-modules/i18n/pull/2193) in the current version that prevents `@nuxtjs/i18n` module to work properly when using `lazy` i18n files.
|
|
82
|
+
|
|
83
|
+
If you're using `lazy` i18n files per locale, apply [this patch](./patches/@nuxtjs__i18n@8.0.0-beta.12.patch) to your project: check how to apply it when using `pnpm` in the root `package.json` file in this repo: [./package.json#L25-L26](./package.json#L97-L101).
|
|
84
|
+
|
|
85
|
+
You can check the playground folder, you can run it using single or multiple json files per locale:
|
|
86
|
+
- for single file per locale: run from root folder `pnpm install && nr dev:prepare && nr dev`
|
|
87
|
+
- for multiple files per locale: run from root folder `pnpm install && nr dev:prepare:multiple-json && nr dev:multiple-json`
|
|
88
|
+
|
|
89
|
+
<!--
|
|
90
|
+
Read the [📖 documentation](https://vite-pwa-org.netlify.app/frameworks/nuxt) for a complete guide on how to configure and use
|
|
91
|
+
this plugin.
|
|
92
|
+
-->
|
|
93
|
+
|
|
94
|
+
## 👀 Full config
|
|
95
|
+
|
|
96
|
+
**WIP**
|
|
97
|
+
<!--
|
|
98
|
+
Check out the type declaration [src/types.ts](./src/types.ts) and the following links for more details.
|
|
99
|
+
|
|
100
|
+
- [Web app manifests](https://developer.mozilla.org/en-US/docs/Web/Manifest)
|
|
101
|
+
- [Workbox](https://developers.google.com/web/tools/workbox)
|
|
102
|
+
-->
|
|
103
|
+
|
|
104
|
+
## 📄 License
|
|
105
|
+
|
|
106
|
+
[MIT](./LICENSE) License © 2023-PRESENT [Joaquín Sánchez](https://github.com/userquin)
|
package/configuration.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
declare module 'virtual:vuetify-configuration' {
|
|
2
|
-
import type { VuetifyOptions } from 'vuetify';
|
|
3
|
-
|
|
4
|
-
export const isDev: boolean
|
|
5
|
-
export const vuetifyConfiguration: () => VuetifyOptions
|
|
6
|
-
}
|
|
1
|
+
declare module 'virtual:vuetify-configuration' {
|
|
2
|
+
import type { VuetifyOptions } from 'vuetify';
|
|
3
|
+
|
|
4
|
+
export const isDev: boolean
|
|
5
|
+
export const vuetifyConfiguration: () => VuetifyOptions
|
|
6
|
+
}
|
package/dist/module.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as _nuxt_schema from '@nuxt/schema';
|
|
|
2
2
|
import { VuetifyOptions } from 'vuetify';
|
|
3
3
|
|
|
4
4
|
type BooleanOrArrayString = boolean | string[];
|
|
5
|
-
interface VOptions extends Partial<Omit<VuetifyOptions, 'ssr' | 'directives'>> {
|
|
5
|
+
interface VOptions extends Partial<Omit<VuetifyOptions, 'ssr' | 'directives' | 'locale' | 'date'>> {
|
|
6
6
|
/**
|
|
7
7
|
* Include the lab components?
|
|
8
8
|
*
|
|
@@ -28,7 +28,6 @@ interface VOptions extends Partial<Omit<VuetifyOptions, 'ssr' | 'directives'>> {
|
|
|
28
28
|
}
|
|
29
29
|
interface ModuleOptions {
|
|
30
30
|
moduleOptions?: {
|
|
31
|
-
writePlugin?: boolean;
|
|
32
31
|
styles?: true | 'none' | 'expose' | 'sass' | {
|
|
33
32
|
configFile: string;
|
|
34
33
|
};
|
|
@@ -37,7 +36,7 @@ interface ModuleOptions {
|
|
|
37
36
|
}
|
|
38
37
|
declare module '#app' {
|
|
39
38
|
interface RuntimeNuxtHooks {
|
|
40
|
-
'vuetify:configuration': (vuetifyOptions: VuetifyOptions) => void;
|
|
39
|
+
'vuetify:configuration': (isDev: boolean, vuetifyOptions: VuetifyOptions) => Promise<void> | void;
|
|
41
40
|
}
|
|
42
41
|
}
|
|
43
42
|
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { useLogger, defineNuxtModule, createResolver, extendWebpackConfig,
|
|
1
|
+
import { useLogger, defineNuxtModule, createResolver, extendWebpackConfig, addPlugin, hasNuxtModule } from '@nuxt/kit';
|
|
2
2
|
import defu from 'defu';
|
|
3
3
|
import vuetify from 'vite-plugin-vuetify';
|
|
4
4
|
import { utimes } from 'node:fs/promises';
|
|
5
5
|
import { resolveVuetifyBase, normalizePath, writeStyles, cacheDir } from '@vuetify/loader-shared';
|
|
6
|
-
import
|
|
6
|
+
import { isAbsolute, join, relative } from 'pathe';
|
|
7
7
|
import { normalizePath as normalizePath$1 } from 'vite';
|
|
8
8
|
|
|
9
|
-
const version = "0.0.
|
|
9
|
+
const version = "0.0.3";
|
|
10
10
|
|
|
11
11
|
function isSubdir(root, test) {
|
|
12
|
-
const relative =
|
|
13
|
-
return relative && !relative.startsWith("..") && !
|
|
12
|
+
const relative$1 = relative(root, test);
|
|
13
|
+
return relative$1 && !relative$1.startsWith("..") && !isAbsolute(relative$1);
|
|
14
14
|
}
|
|
15
15
|
const styleImportRegexp = /(@use |meta\.load-css\()['"](vuetify(?:\/lib)?(?:\/styles(?:\/main(?:\.sass)?)?)?)['"]/;
|
|
16
16
|
function stylesPlugin(options, logger) {
|
|
@@ -111,14 +111,14 @@ function stylesPlugin(options, logger) {
|
|
|
111
111
|
},
|
|
112
112
|
configResolved(config) {
|
|
113
113
|
if (typeof options.styles === "object") {
|
|
114
|
-
if (
|
|
114
|
+
if (isAbsolute(options.styles.configFile))
|
|
115
115
|
configFile = options.styles.configFile;
|
|
116
116
|
else
|
|
117
|
-
configFile =
|
|
117
|
+
configFile = join(config.root || process.cwd(), options.styles.configFile);
|
|
118
118
|
}
|
|
119
119
|
},
|
|
120
|
-
async resolveId(source, importer, { custom }) {
|
|
121
|
-
if (source === "vuetify/styles" || importer && source.endsWith(".css") && isSubdir(vuetifyBase,
|
|
120
|
+
async resolveId(source, importer, { custom, ssr }) {
|
|
121
|
+
if (source === "vuetify/styles" || importer && source.endsWith(".css") && isSubdir(vuetifyBase, isAbsolute(source) ? source : importer)) {
|
|
122
122
|
if (options.styles === "none") {
|
|
123
123
|
return "/@plugin-vuetify/lib/__void__";
|
|
124
124
|
} else if (options.styles === "sass") {
|
|
@@ -143,14 +143,13 @@ function stylesPlugin(options, logger) {
|
|
|
143
143
|
if (!resolution)
|
|
144
144
|
return null;
|
|
145
145
|
const target = resolution.id.replace(/\.css$/, ".sass");
|
|
146
|
-
const file =
|
|
146
|
+
const file = relative(join(vuetifyBase, "lib"), target);
|
|
147
147
|
const contents = `@use "${normalizePath(configFile)}"
|
|
148
148
|
@use "${normalizePath(target)}"`;
|
|
149
149
|
tempFiles.set(file, contents);
|
|
150
|
-
return `/@plugin-vuetify/lib/${file}`;
|
|
150
|
+
return ssr ? `/@plugin-vuetify/lib/${file}` : `/@fs/plugin-vuetify/lib/${file}`;
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
-
return null;
|
|
154
153
|
},
|
|
155
154
|
async transform(code, id) {
|
|
156
155
|
if (options.styles === "expose" && [".scss", ".sass"].some((v) => id.endsWith(v)) && styleImportRegexp.test(code)) {
|
|
@@ -170,13 +169,17 @@ function stylesPlugin(options, logger) {
|
|
|
170
169
|
const file = /^\/@plugin-vuetify\/lib\/(.*?)(\?.*)?$/.exec(id)[1];
|
|
171
170
|
return tempFiles.get(file);
|
|
172
171
|
}
|
|
172
|
+
if (id.startsWith("/@fs/plugin-vuetify/lib/")) {
|
|
173
|
+
const file = /^\/@fs\/plugin-vuetify\/lib\/(.*?)(\?.*)?$/.exec(id)[1];
|
|
174
|
+
return tempFiles.get(file);
|
|
175
|
+
}
|
|
173
176
|
}
|
|
174
177
|
};
|
|
175
178
|
}
|
|
176
179
|
|
|
177
180
|
function vuetifyConfigurationPlugin(isDev, directives, labComponents, vuetifyAppOptions) {
|
|
178
181
|
const VIRTUAL_VUETIFY_CONFIGURATION = "virtual:vuetify-configuration";
|
|
179
|
-
const RESOLVED_VIRTUAL_VUETIFY_CONFIGURATION =
|
|
182
|
+
const RESOLVED_VIRTUAL_VUETIFY_CONFIGURATION = `/@nuxt-vuetify-configuration/${VIRTUAL_VUETIFY_CONFIGURATION.slice("virtual:".length)}`;
|
|
180
183
|
return {
|
|
181
184
|
name: "vuetify:configuration:nuxt",
|
|
182
185
|
enforce: "pre",
|
|
@@ -187,15 +190,15 @@ function vuetifyConfigurationPlugin(isDev, directives, labComponents, vuetifyApp
|
|
|
187
190
|
async load(id) {
|
|
188
191
|
if (id === RESOLVED_VIRTUAL_VUETIFY_CONFIGURATION) {
|
|
189
192
|
const directivesResult = buildDirectives();
|
|
190
|
-
const
|
|
193
|
+
const labComponentsResult = buildLabComponents();
|
|
191
194
|
return `${directivesResult.imports}
|
|
192
|
-
${
|
|
195
|
+
${labComponentsResult.imports}
|
|
193
196
|
|
|
194
197
|
export const isDev = ${isDev}
|
|
195
198
|
export function vuetifyConfiguration() {
|
|
196
199
|
const options = ${JSON.stringify(vuetifyAppOptions)}
|
|
197
200
|
${directivesResult.expression}
|
|
198
|
-
${
|
|
201
|
+
${labComponentsResult.expression}
|
|
199
202
|
return options
|
|
200
203
|
}
|
|
201
204
|
`;
|
|
@@ -217,7 +220,7 @@ export function vuetifyConfiguration() {
|
|
|
217
220
|
};
|
|
218
221
|
}
|
|
219
222
|
}
|
|
220
|
-
function
|
|
223
|
+
function buildLabComponents() {
|
|
221
224
|
if (!labComponents)
|
|
222
225
|
return { imports: "", expression: "" };
|
|
223
226
|
if (typeof labComponents === "boolean") {
|
|
@@ -244,16 +247,15 @@ const module = defineNuxtModule({
|
|
|
244
247
|
version
|
|
245
248
|
},
|
|
246
249
|
// Default configuration options of the Nuxt module
|
|
247
|
-
defaults: {
|
|
250
|
+
defaults: () => ({
|
|
248
251
|
vuetifyOptions: {
|
|
249
252
|
labComponents: false,
|
|
250
253
|
directives: false
|
|
251
254
|
},
|
|
252
255
|
moduleOptions: {
|
|
253
|
-
writePlugin: true,
|
|
254
256
|
styles: true
|
|
255
257
|
}
|
|
256
|
-
},
|
|
258
|
+
}),
|
|
257
259
|
setup(options, nuxt) {
|
|
258
260
|
var _a;
|
|
259
261
|
const resolver = createResolver(import.meta.url);
|
|
@@ -270,7 +272,7 @@ const module = defineNuxtModule({
|
|
|
270
272
|
const runtimeDir = resolver.resolve("./runtime");
|
|
271
273
|
nuxt.options.build.transpile.push(runtimeDir);
|
|
272
274
|
nuxt.options.build.transpile.push(CONFIG_KEY);
|
|
273
|
-
const { styles = true
|
|
275
|
+
const { styles = true } = moduleOptions ?? {};
|
|
274
276
|
nuxt.options.build.transpile.push(CONFIG_KEY);
|
|
275
277
|
(_a = nuxt.options).css ?? (_a.css = []);
|
|
276
278
|
if (typeof styles === "string" && ["sass", "expose"].includes(styles))
|
|
@@ -285,7 +287,7 @@ const module = defineNuxtModule({
|
|
|
285
287
|
nuxt.hook("vite:extend", ({ config }) => checkVuetifyPlugins(config));
|
|
286
288
|
nuxt.hook("prepare:types", ({ references }) => {
|
|
287
289
|
references.push({ types: "vuetify-nuxt-module/configuration" });
|
|
288
|
-
references.push({ types: "vuetify
|
|
290
|
+
references.push({ types: "vuetify" });
|
|
289
291
|
});
|
|
290
292
|
nuxt.hook("vite:extendConfig", (viteInlineConfig) => {
|
|
291
293
|
viteInlineConfig.plugins = viteInlineConfig.plugins || [];
|
|
@@ -296,7 +298,7 @@ const module = defineNuxtModule({
|
|
|
296
298
|
...Array.isArray(viteInlineConfig.ssr.noExternal) ? viteInlineConfig.ssr.noExternal : [],
|
|
297
299
|
CONFIG_KEY
|
|
298
300
|
];
|
|
299
|
-
const autoImportPlugin = vuetify({ styles, autoImport: true }).find((p) => p && typeof p === "object" && "name" in p && p.name === "vuetify:import");
|
|
301
|
+
const autoImportPlugin = vuetify({ styles: true, autoImport: true }).find((p) => p && typeof p === "object" && "name" in p && p.name === "vuetify:import");
|
|
300
302
|
viteInlineConfig.plugins.push(autoImportPlugin);
|
|
301
303
|
viteInlineConfig.plugins.push(stylesPlugin({ styles }, logger));
|
|
302
304
|
viteInlineConfig.plugins.push(vuetifyConfigurationPlugin(
|
|
@@ -306,12 +308,14 @@ const module = defineNuxtModule({
|
|
|
306
308
|
vuetifyAppOptions
|
|
307
309
|
));
|
|
308
310
|
});
|
|
309
|
-
|
|
310
|
-
src: resolver.resolve(runtimeDir, "
|
|
311
|
-
write: nuxt.options.dev || writePlugin
|
|
312
|
-
}, {
|
|
313
|
-
append: true
|
|
311
|
+
addPlugin({
|
|
312
|
+
src: resolver.resolve(runtimeDir, "plugins/vuetify.mts")
|
|
314
313
|
});
|
|
314
|
+
if (hasNuxtModule("@nuxtjs/i18n", nuxt)) {
|
|
315
|
+
addPlugin({
|
|
316
|
+
src: resolver.resolve(runtimeDir, "plugins/vuetify-i18n.mts")
|
|
317
|
+
});
|
|
318
|
+
}
|
|
315
319
|
}
|
|
316
320
|
});
|
|
317
321
|
function checkVuetifyPlugins(config) {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Ref } from 'vue';
|
|
2
|
+
import type { LocaleMessages, LocaleOptions } from 'vuetify';
|
|
3
|
+
import type { NuxtApp } from '#app';
|
|
4
|
+
export declare function createAdapter(nuxtApp: NuxtApp): {
|
|
5
|
+
name: string;
|
|
6
|
+
current: any;
|
|
7
|
+
fallback: any;
|
|
8
|
+
messages: any;
|
|
9
|
+
t: (key: string, ...params: unknown[]) => any;
|
|
10
|
+
n: any;
|
|
11
|
+
provide: (props: LocaleOptions) => {
|
|
12
|
+
name: string;
|
|
13
|
+
current: Ref<string>;
|
|
14
|
+
fallback: Ref<string>;
|
|
15
|
+
messages: Ref<LocaleMessages>;
|
|
16
|
+
t: (key: string, ...params: unknown[]) => any;
|
|
17
|
+
n: any;
|
|
18
|
+
provide: any;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getCurrentInstance as _getCurrentInstance,
|
|
3
|
+
computed,
|
|
4
|
+
effectScope,
|
|
5
|
+
onScopeDispose,
|
|
6
|
+
ref,
|
|
7
|
+
toRaw,
|
|
8
|
+
watch
|
|
9
|
+
} from "vue";
|
|
10
|
+
import { useI18n } from "#imports";
|
|
11
|
+
export function createAdapter(nuxtApp) {
|
|
12
|
+
const i18n = nuxtApp.$i18n;
|
|
13
|
+
const current = i18n.locale;
|
|
14
|
+
const fallback = i18n.fallbackLocale;
|
|
15
|
+
const messages = i18n.messages;
|
|
16
|
+
watch(() => current, (l) => nuxtApp.$vuetify.locale.current.value = l);
|
|
17
|
+
watch(() => nuxtApp.$vuetify?.locale?.current.value, (l) => i18n.setLocale(l));
|
|
18
|
+
return {
|
|
19
|
+
name: "nuxt-vue-i18n",
|
|
20
|
+
current,
|
|
21
|
+
fallback,
|
|
22
|
+
messages,
|
|
23
|
+
t: (key, ...params) => i18n.t(key, params),
|
|
24
|
+
n: i18n.n,
|
|
25
|
+
provide: createProvideFunction({ current, fallback, messages })
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function getCurrentInstance(name, message) {
|
|
29
|
+
const vm = _getCurrentInstance();
|
|
30
|
+
if (!vm)
|
|
31
|
+
throw new Error(`[Vuetify] ${name} ${message || "must be called from inside a setup function"}`);
|
|
32
|
+
return vm;
|
|
33
|
+
}
|
|
34
|
+
function toKebabCase(str = "") {
|
|
35
|
+
if (toKebabCase.cache.has(str))
|
|
36
|
+
return toKebabCase.cache.get(str);
|
|
37
|
+
const kebab = str.replace(/[^a-z]/gi, "-").replace(/\B([A-Z])/g, "-$1").toLowerCase();
|
|
38
|
+
toKebabCase.cache.set(str, kebab);
|
|
39
|
+
return kebab;
|
|
40
|
+
}
|
|
41
|
+
toKebabCase.cache = /* @__PURE__ */ new Map();
|
|
42
|
+
function useToggleScope(source, fn) {
|
|
43
|
+
let scope;
|
|
44
|
+
function start() {
|
|
45
|
+
scope = effectScope();
|
|
46
|
+
scope.run(
|
|
47
|
+
() => fn.length ? fn(() => {
|
|
48
|
+
scope?.stop();
|
|
49
|
+
start();
|
|
50
|
+
}) : fn()
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
watch(source, (active) => {
|
|
54
|
+
if (active && !scope) {
|
|
55
|
+
start();
|
|
56
|
+
} else if (!active) {
|
|
57
|
+
scope?.stop();
|
|
58
|
+
scope = void 0;
|
|
59
|
+
}
|
|
60
|
+
}, { immediate: true });
|
|
61
|
+
onScopeDispose(() => {
|
|
62
|
+
scope?.stop();
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function useProxiedModel(props, prop, defaultValue, transformIn = (v) => v, transformOut = (v) => v) {
|
|
66
|
+
const vm = getCurrentInstance("useProxiedModel");
|
|
67
|
+
const internal = ref(props[prop] !== void 0 ? props[prop] : defaultValue);
|
|
68
|
+
const kebabProp = toKebabCase(prop);
|
|
69
|
+
const checkKebab = kebabProp !== prop;
|
|
70
|
+
const isControlled = checkKebab ? computed(() => {
|
|
71
|
+
void props[prop];
|
|
72
|
+
return !!((vm.vnode.props?.hasOwnProperty(prop) || vm.vnode.props?.hasOwnProperty(kebabProp)) && (vm.vnode.props?.hasOwnProperty(`onUpdate:${prop}`) || vm.vnode.props?.hasOwnProperty(`onUpdate:${kebabProp}`)));
|
|
73
|
+
}) : computed(() => {
|
|
74
|
+
void props[prop];
|
|
75
|
+
return !!(vm.vnode.props?.hasOwnProperty(prop) && vm.vnode.props?.hasOwnProperty(`onUpdate:${prop}`));
|
|
76
|
+
});
|
|
77
|
+
useToggleScope(() => !isControlled.value, () => {
|
|
78
|
+
watch(() => props[prop], (val) => {
|
|
79
|
+
internal.value = val;
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
const model = computed({
|
|
83
|
+
get() {
|
|
84
|
+
const externalValue = props[prop];
|
|
85
|
+
return transformIn(isControlled.value ? externalValue : internal.value);
|
|
86
|
+
},
|
|
87
|
+
set(internalValue) {
|
|
88
|
+
const newValue = transformOut(internalValue);
|
|
89
|
+
const value = toRaw(isControlled.value ? props[prop] : internal.value);
|
|
90
|
+
if (value === newValue || transformIn(value) === internalValue)
|
|
91
|
+
return;
|
|
92
|
+
internal.value = newValue;
|
|
93
|
+
vm?.emit(`update:${prop}`, newValue);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(model, "externalValue", {
|
|
97
|
+
get: () => isControlled.value ? props[prop] : internal.value
|
|
98
|
+
});
|
|
99
|
+
return model;
|
|
100
|
+
}
|
|
101
|
+
function useProvided(props, prop, provided) {
|
|
102
|
+
const internal = useProxiedModel(props, prop);
|
|
103
|
+
internal.value = props[prop] ?? provided.value;
|
|
104
|
+
watch(provided, (v) => {
|
|
105
|
+
if (props[prop] == null)
|
|
106
|
+
internal.value = v;
|
|
107
|
+
});
|
|
108
|
+
return internal;
|
|
109
|
+
}
|
|
110
|
+
function createProvideFunction(data) {
|
|
111
|
+
return (props) => {
|
|
112
|
+
const current = useProvided(props, "locale", data.current);
|
|
113
|
+
const fallback = useProvided(props, "fallback", data.fallback);
|
|
114
|
+
const messages = useProvided(props, "messages", data.messages);
|
|
115
|
+
const i18n = useI18n({
|
|
116
|
+
locale: current.value,
|
|
117
|
+
fallbackLocale: fallback.value,
|
|
118
|
+
messages: messages.value,
|
|
119
|
+
useScope: "local",
|
|
120
|
+
legacy: false,
|
|
121
|
+
inheritLocale: false
|
|
122
|
+
});
|
|
123
|
+
watch(current, (l) => i18n.locale.value = l);
|
|
124
|
+
return {
|
|
125
|
+
name: "nuxt-vue-i18n",
|
|
126
|
+
current,
|
|
127
|
+
fallback,
|
|
128
|
+
messages,
|
|
129
|
+
// todo: fix this, we should check the options
|
|
130
|
+
// @ts-expect-error Type instantiation is excessively deep and possibly infinite.ts(2589)
|
|
131
|
+
t: (key, ...params) => i18n.t(key, params),
|
|
132
|
+
n: i18n.n,
|
|
133
|
+
provide: createProvideFunction({ current, fallback, messages })
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createAdapter } from './i18n'
|
|
2
|
+
import { defineNuxtPlugin } from '#app'
|
|
3
|
+
|
|
4
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
5
|
+
nuxtApp.hook('vuetify:configuration', (_isDev, vuetifyOptions) => {
|
|
6
|
+
vuetifyOptions.locale = vuetifyOptions.locale ?? {}
|
|
7
|
+
vuetifyOptions.locale.adapter = createAdapter(nuxtApp)
|
|
8
|
+
})
|
|
9
|
+
})
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import { createVuetify } from 'vuetify'
|
|
2
|
-
import { isDev, vuetifyConfiguration } from 'virtual:vuetify-configuration'
|
|
3
|
-
import { defineNuxtPlugin, useNuxtApp } from '#app'
|
|
4
|
-
|
|
5
|
-
export default defineNuxtPlugin({
|
|
6
|
-
name: 'vuetify:configuration:plugin',
|
|
7
|
-
enforce: 'post',
|
|
8
|
-
parallel: false,
|
|
9
|
-
async setup() {
|
|
10
|
-
const nuxtApp = useNuxtApp()
|
|
11
|
-
const options = vuetifyConfiguration()
|
|
12
|
-
|
|
13
|
-
await nuxtApp.hooks.callHook('vuetify:configuration', options)
|
|
14
|
-
|
|
15
|
-
const vuetify = createVuetify(
|
|
16
|
-
|
|
17
|
-
nuxtApp.vueApp.use(vuetify)
|
|
18
|
-
|
|
19
|
-
if (
|
|
20
|
-
// eslint-disable-next-line no-console
|
|
21
|
-
console.log('Vuetify 3 initialized', vuetify)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
provide: {
|
|
26
|
-
vuetify,
|
|
27
|
-
},
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
})
|
|
1
|
+
import { createVuetify } from 'vuetify'
|
|
2
|
+
import { isDev, vuetifyConfiguration } from 'virtual:vuetify-configuration'
|
|
3
|
+
import { defineNuxtPlugin, useNuxtApp } from '#app'
|
|
4
|
+
|
|
5
|
+
export default defineNuxtPlugin({
|
|
6
|
+
name: 'vuetify:configuration:plugin',
|
|
7
|
+
enforce: 'post',
|
|
8
|
+
parallel: false,
|
|
9
|
+
async setup() {
|
|
10
|
+
const nuxtApp = useNuxtApp()
|
|
11
|
+
const options = vuetifyConfiguration()
|
|
12
|
+
|
|
13
|
+
await nuxtApp.hooks.callHook('vuetify:configuration', isDev, options)
|
|
14
|
+
|
|
15
|
+
const vuetify = createVuetify(options)
|
|
16
|
+
|
|
17
|
+
nuxtApp.vueApp.use(vuetify)
|
|
18
|
+
|
|
19
|
+
if (process.client && isDev) {
|
|
20
|
+
// eslint-disable-next-line no-console
|
|
21
|
+
console.log('Vuetify 3 initialized', vuetify)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
provide: {
|
|
26
|
+
vuetify,
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
})
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vuetify-nuxt-module",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.3",
|
|
5
5
|
"packageManager": "pnpm@8.6.5",
|
|
6
6
|
"description": "Zero-Config Nuxt Module for Vuetify ",
|
|
7
7
|
"author": "userquin <userquin@gmail.com>",
|
|
@@ -36,16 +36,19 @@
|
|
|
36
36
|
"*.d.ts"
|
|
37
37
|
],
|
|
38
38
|
"scripts": {
|
|
39
|
-
"
|
|
39
|
+
"build": "pnpm dev:prepare && nuxt-module-build",
|
|
40
40
|
"dev": "nuxi dev playground",
|
|
41
|
-
"dev:
|
|
41
|
+
"dev:multiple-json": "MULTIPLE_LANG_FILES=true nuxi dev playground",
|
|
42
42
|
"dev:prepare": "nuxt-module-build --stub && nuxi prepare playground",
|
|
43
|
-
"
|
|
44
|
-
"
|
|
43
|
+
"dev:prepare:multiple-json": "nuxt-module-build --stub && MULTIPLE_LANG_FILES=true nuxi prepare playground",
|
|
44
|
+
"dev:build": "nuxi build playground",
|
|
45
|
+
"dev:build:multiple-json": "MULTIPLE_LANG_FILES=true nuxi build playground",
|
|
45
46
|
"lint": "eslint .",
|
|
46
47
|
"lint:fix": "nr lint --fix",
|
|
47
48
|
"test": "vitest run",
|
|
48
|
-
"test:watch": "vitest watch"
|
|
49
|
+
"test:watch": "vitest watch",
|
|
50
|
+
"prepublishOnly": "pnpm build",
|
|
51
|
+
"release": "bumpp && npm publish"
|
|
49
52
|
},
|
|
50
53
|
"peerDependencies": {
|
|
51
54
|
"@nuxt/kit": "^3.5.3",
|
|
@@ -65,6 +68,7 @@
|
|
|
65
68
|
"@nuxt/module-builder": "^0.4.0",
|
|
66
69
|
"@nuxt/schema": "^3.6.1",
|
|
67
70
|
"@nuxt/test-utils": "^3.6.1",
|
|
71
|
+
"@nuxtjs/i18n": "^8.0.0-beta.12",
|
|
68
72
|
"@parcel/watcher": "^2.1.0",
|
|
69
73
|
"@types/node": "^18",
|
|
70
74
|
"bumpp": "^9.1.1",
|
|
@@ -90,5 +94,10 @@
|
|
|
90
94
|
"vite-plugin-vuetify",
|
|
91
95
|
"vuetify"
|
|
92
96
|
]
|
|
97
|
+
},
|
|
98
|
+
"pnpm": {
|
|
99
|
+
"patchedDependencies": {
|
|
100
|
+
"@nuxtjs/i18n@8.0.0-beta.12": "patches/@nuxtjs__i18n@8.0.0-beta.12.patch"
|
|
101
|
+
}
|
|
93
102
|
}
|
|
94
|
-
}
|
|
103
|
+
}
|