vuetify-nuxt4-module 1.1.0

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 chenhai-dev
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 ADDED
@@ -0,0 +1,375 @@
1
+ # Vuetify Nuxt 4 Module
2
+
3
+ [![npm version](https://img.shields.io/npm/v/vuetify-nuxt4-module/latest.svg?style=flat&colorA=020420&colorB=00DC82)](https://npmjs.com/package/vuetify-nuxt4-module)
4
+ [![npm downloads](https://img.shields.io/npm/dm/vuetify-nuxt4-module.svg?style=flat&colorA=020420&colorB=00DC82)](https://npm.chart.dev/vuetify-nuxt4-module)
5
+ [![License](https://img.shields.io/npm/l/vuetify-nuxt4-module.svg?style=flat&colorA=020420&colorB=00DC82)](https://npmjs.com/package/vuetify-nuxt4-module)
6
+ [![CI](https://github.com/KHNexTech/Vuetify-Nuxt4-Module/actions/workflows/ci.yml/badge.svg)](https://github.com/KHNexTech/Vuetify-Nuxt4-Module/actions/workflows/ci.yml)
7
+ [![Nuxt](https://img.shields.io/badge/Nuxt-020420?logo=nuxt.js)](https://nuxt.com)
8
+
9
+ Nuxt 4 module for Vuetify with theming and performance optimizations
10
+
11
+ - [✨ Release Notes](/CHANGELOG.md)
12
+
13
+ ## Features
14
+
15
+ - ⚡ **Auto-import** - Automatic tree-shaking with vite-plugin-vuetify
16
+ - 🎨 **Theme Persistence** - Cookie/localStorage/sessionStorage support
17
+ - 🔧 **Date Adapters** - Support for date-fns, dayjs, luxon, moment
18
+ - 🎯 **Icon Sets** – MDI, FontAwesome, and SVG variants
19
+ - 🌍 **Locale Support** – Multiple languages with RTL support
20
+ - 🎭 **Blueprints** - Material Design MD1/MD2/MD3 presets
21
+ - 🚀 **Performance** – Optimized chunking and tree-shaking
22
+ - 🔌 **Hooks** – Extend Vuetify configuration via hooks
23
+
24
+ ## Quick Setup
25
+
26
+ Install the module:
27
+ ```bash
28
+ # npm
29
+ npm install vuetify-nuxt4-module
30
+
31
+ # pnpm
32
+ pnpm add vuetify-nuxt4-module
33
+
34
+ # yarn
35
+ yarn add vuetify-nuxt4-module
36
+ ```
37
+
38
+ Add to your `nuxt.config.ts`:
39
+ ```typescript
40
+ export default defineNuxtConfig({
41
+ modules: ['vuetify-nuxt4-module'],
42
+
43
+ vuetify: {
44
+ moduleOptions: {
45
+ themePersistence: true,
46
+ defaultTheme: 'light',
47
+ },
48
+
49
+ vuetifyOptions: {
50
+ theme: {
51
+ defaultTheme: 'light',
52
+ themes: {
53
+ light: {
54
+ dark: false,
55
+ colors: {
56
+ primary: '#1976D2',
57
+ secondary: '#424242',
58
+ background: '#FFFFFF',
59
+ },
60
+ },
61
+ dark: {
62
+ dark: true,
63
+ colors: {
64
+ primary: '#2196F3',
65
+ background: '#121212',
66
+ },
67
+ },
68
+ },
69
+ },
70
+ },
71
+ },
72
+ })
73
+
74
+ ```
75
+
76
+ ## Configuration
77
+
78
+ ### Full Example
79
+ ```typescript
80
+ export default defineNuxtConfig({
81
+ modules: ['vuetify-nuxt4-module'],
82
+
83
+ vuetify: {
84
+ vuetifyOptions: {
85
+ ssr: true,
86
+ blueprint: 'md3', // 'md1' | 'md2' | 'md3'
87
+ dateAdapter: 'vuetify', // 'vuetify' | 'date-fns' | 'dayjs' | 'luxon' | 'moment'
88
+
89
+ icons: {
90
+ defaultSet: 'mdi', // 'mdi' | 'mdi-svg' | 'fa' | 'fa-svg'
91
+ aliases: {
92
+ // Custom icon aliases
93
+ },
94
+ },
95
+
96
+ locale: {
97
+ locale: 'en',
98
+ fallback: 'en',
99
+ rtl: {
100
+ ar: true,
101
+ },
102
+ },
103
+
104
+ theme: {
105
+ defaultTheme: 'light',
106
+ themes: {
107
+ light: {
108
+ colors: {
109
+ primary: '#6200EE',
110
+ secondary: '#03DAC6',
111
+ },
112
+ },
113
+ dark: {
114
+ colors: {
115
+ primary: '#BB86FC',
116
+ secondary: '#03DAC6',
117
+ },
118
+ },
119
+ },
120
+ },
121
+
122
+ defaults: {
123
+ VBtn: {
124
+ variant: 'elevated',
125
+ rounded: 'lg',
126
+ },
127
+ VCard: {
128
+ elevation: 4,
129
+ },
130
+ },
131
+ },
132
+
133
+ // Module options
134
+ importComposables: true,
135
+ prefixComposables: false, // Set true to prefix: useVTheme, useVDisplay, etc.
136
+ transformAssetUrls: true,
137
+ autoImport: true, // or { labs: true, ignore: [] }
138
+ styles: true, // true | 'sass' | 'none' | { configFile: 'path/to/settings.scss' }
139
+
140
+ persistence: {
141
+ enabled: true,
142
+ key: 'nuxt-vuetify-theme',
143
+ storage: 'cookie', // 'cookie' | 'localStorage' | 'sessionStorage'
144
+ cookieOptions: {
145
+ maxAge: 60 * 60 * 24 * 365,
146
+ path: '/',
147
+ sameSite: 'lax',
148
+ },
149
+ },
150
+ },
151
+ })
152
+ ```
153
+
154
+ ### Options Reference
155
+
156
+ | Option | Type | Default | Description |
157
+ |--------|------|---------|-------------|
158
+ | `vuetifyOptions.ssr` | `boolean` | `true` | Enable SSR support |
159
+ | `vuetifyOptions.blueprint` | `'md1' \| 'md2' \| 'md3'` | `'md3'` | Material Design blueprint |
160
+ | `vuetifyOptions.dateAdapter` | `string` | `'vuetify'` | Date adapter to use |
161
+ | `vuetifyOptions.icons` | `object` | `{ defaultSet: 'mdi' }` | Icon configuration |
162
+ | `vuetifyOptions.locale` | `object` | - | Locale configuration |
163
+ | `vuetifyOptions.theme` | `object` | - | Theme configuration |
164
+ | `vuetifyOptions.defaults` | `object` | - | Component defaults |
165
+ | `importComposables` | `boolean` | `true` | Auto-import Vuetify composables |
166
+ | `prefixComposables` | `boolean` | `false` | Prefix composables with 'V' |
167
+ | `transformAssetUrls` | `boolean` | `true` | Transform asset URLs in templates |
168
+ | `autoImport` | `boolean \| object` | `true` | Enable auto-import via vite-plugin-vuetify |
169
+ | `styles` | `boolean \| string \| object` | `true` | Style configuration |
170
+ | `persistence` | `object` | `{ enabled: true, ... }` | Theme persistence |
171
+
172
+ ## Usage
173
+
174
+ ### Using the Composable
175
+ ```vue
176
+ <script setup lang="ts">
177
+ const {
178
+ isDark,
179
+ isMobile,
180
+ currentTheme,
181
+ currentBreakpoint,
182
+ toggleTheme,
183
+ setTheme,
184
+ setLocale,
185
+ } = useVuetify()
186
+ </script>
187
+
188
+ <template>
189
+ <v-app>
190
+ <v-btn @click="toggleTheme">
191
+ {{ isDark ? 'Light' : 'Dark' }} Mode
192
+ </v-btn>
193
+ </v-app>
194
+ </template>
195
+ ```
196
+
197
+ ### Using Hooks
198
+
199
+ Create a plugin to hook into Vuetify lifecycle:
200
+ ```typescript
201
+ // plugins/vuetify-custom.ts
202
+ export default defineNuxtPlugin((nuxtApp) => {
203
+ // Modify options before Vuetify is created
204
+ onVuetifyHook(nuxtApp, 'vuetify:before-create', ({ vuetifyOptions }) => {
205
+ vuetifyOptions.defaults = {
206
+ ...vuetifyOptions.defaults,
207
+ VAlert: {
208
+ variant: 'tonal',
209
+ },
210
+ }
211
+ })
212
+
213
+ // Access Vuetify instance when ready
214
+ onVuetifyHook(nuxtApp, 'vuetify:ready', (vuetify) => {
215
+ console.log('Vuetify ready:', vuetify.theme.global.name.value)
216
+ })
217
+ })
218
+ ```
219
+
220
+ ### Available Hooks
221
+
222
+ | Hook | Payload | Description |
223
+ |------|---------|-------------|
224
+ | `vuetify:before-create` | `{ vuetifyOptions }` | Modify options before Vuetify is created |
225
+ | `vuetify:configuration` | `{ vuetifyOptions }` | After configuration is applied |
226
+ | `vuetify:ready` | `vuetify` | When Vuetify instance is ready |
227
+
228
+ ## Date Adapters
229
+
230
+ To use a date adapter other than the built-in one, install the required packages:
231
+ ```bash
232
+ # date-fns
233
+ npm install @date-io/date-fns date-fns
234
+
235
+ # dayjs
236
+ npm install @date-io/dayjs dayjs
237
+
238
+ # luxon
239
+ npm install @date-io/luxon luxon
240
+
241
+ # moment
242
+ npm install @date-io/moment moment
243
+ ```
244
+
245
+ Then configure:
246
+ ```typescript
247
+ vuetify: {
248
+ vuetifyOptions: {
249
+ dateAdapter: 'date-fns'
250
+ }
251
+ }
252
+ ```
253
+
254
+ ## Custom SASS Variables
255
+
256
+ To customize Vuetify's SASS variables:
257
+
258
+ 1. Create a settings file:
259
+ ```scss
260
+ // assets/settings.scss
261
+ @use 'vuetify/settings' with (
262
+ $body-font-family: 'Inter',
263
+ $border-radius-root: 8px,
264
+ $button-height: 44px,
265
+ );
266
+ ```
267
+
268
+ 2. Configure in nuxt.config.ts:
269
+ ```typescript
270
+ vuetify: {
271
+ styles: {
272
+ configFile: 'assets/settings.scss'
273
+ }
274
+ }
275
+ ```
276
+
277
+ > **Note:** When using a custom config file with SSR, disable inline SSR styles:
278
+ > ```typescript
279
+ > experimental: {
280
+ > inlineSSRStyles: false
281
+ > }
282
+ > ```
283
+
284
+ ## Performance Tips
285
+
286
+ ### 1. Use SVG Icons for Better Performance
287
+ ```typescript
288
+ vuetify: {
289
+ vuetifyOptions: {
290
+ icons: {
291
+ defaultSet: 'mdi-svg' // SVG icons are tree-shaken
292
+ }
293
+ }
294
+ }
295
+ ```
296
+
297
+ ### 2. Import Only Needed Icons (with mdi-svg)
298
+ ```typescript
299
+ // plugins/vuetify-icons.ts
300
+ import { mdiAccount, mdiHome, mdiMenu } from '@mdi/js'
301
+
302
+ export default defineNuxtPlugin((nuxtApp) => {
303
+ onVuetifyHook(nuxtApp, 'vuetify:before-create', ({ vuetifyOptions }) => {
304
+ vuetifyOptions.icons = {
305
+ defaultSet: 'mdi-svg',
306
+ aliases: {
307
+ account: mdiAccount,
308
+ home: mdiHome,
309
+ menu: mdiMenu,
310
+ },
311
+ }
312
+ })
313
+ })
314
+ ```
315
+
316
+ ### 3. Lazy Load Heavy Components
317
+ ```vue
318
+ <script setup>
319
+ // Lazy load data tables, calendars, etc.
320
+ const VDataTable = defineAsyncComponent(() =>
321
+ import('vuetify/components/VDataTable').then(m => m.VDataTable)
322
+ )
323
+ </script>
324
+ ```
325
+
326
+ ### 4. Use CSS Instead of JS for Themes
327
+ ```typescript
328
+ // nuxt.config.ts
329
+ vuetify: {
330
+ styles: {
331
+ configFile: 'assets/vuetify.scss'
332
+ }
333
+ }
334
+ ```
335
+
336
+ ### 5. Enable Compression
337
+ ```typescript
338
+ // nuxt.config.ts
339
+ nitro: {
340
+ compressPublicAssets: true
341
+ }
342
+ ```
343
+
344
+ ## TypeScript
345
+
346
+ The module provides full TypeScript support. Types are automatically generated.
347
+
348
+ ## Local Development
349
+ ```bash
350
+ # Install dependencies
351
+ npm install
352
+
353
+ # Generate type stubs
354
+ npm run dev:prepare
355
+
356
+ # Develop with the playground
357
+ npm run dev
358
+
359
+ # Build the playground
360
+ npm run dev:build
361
+
362
+ # Run ESLint
363
+ npm run lint
364
+
365
+ # Run Vitest
366
+ npm run test
367
+ npm run test:watch
368
+
369
+ # Release new version
370
+ npm run release
371
+ ```
372
+
373
+ ## License
374
+
375
+ [MIT License](LICENSE)
@@ -0,0 +1,189 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+ import { HookResult } from '@nuxt/schema';
3
+ import * as Components from 'vuetify/components';
4
+ import * as Directives from 'vuetify/directives';
5
+ import { VuetifyOptions, IconOptions, LocaleMessages, createVuetify, Vuetify } from 'vuetify';
6
+
7
+ type IconSet = 'mdi' | 'mdi-svg' | 'fa' | 'fa-svg';
8
+ type BlueprintName = 'md1' | 'md2' | 'md3';
9
+ type DateAdapterName = 'vuetify' | 'date-fns' | 'dayjs' | 'luxon' | 'moment';
10
+ interface VuetifyOptionsConfig {
11
+ /**
12
+ * Component aliases (e.g., { VButton: VBtn, MyButton: 'VBtn' })
13
+ */
14
+ aliases?: Record<string, keyof typeof Components> | Record<string, string>;
15
+ /**
16
+ * Blueprint preset
17
+ * @default 'md3'
18
+ */
19
+ blueprint?: BlueprintName;
20
+ /**
21
+ * Default component configurations
22
+ */
23
+ defaults?: VuetifyOptions['defaults'];
24
+ /**
25
+ * Theme configuration
26
+ */
27
+ theme?: Exclude<VuetifyOptions['theme'], false>;
28
+ /**
29
+ * Icon configuration
30
+ */
31
+ icons?: {
32
+ defaultSet?: IconSet;
33
+ aliases?: IconOptions['aliases'];
34
+ sets?: IconOptions['sets'];
35
+ };
36
+ /**
37
+ * Locale configuration
38
+ */
39
+ locale?: {
40
+ locale?: string;
41
+ fallback?: string;
42
+ messages?: LocaleMessages;
43
+ rtl?: Record<string, boolean>;
44
+ };
45
+ /**
46
+ * Date adapter configuration for date pickers
47
+ * Options: 'vuetify' (built-in), 'date-fns', 'moment', 'luxon', 'dayjs', 'js-joda'
48
+ * @default 'vuetify'
49
+ */
50
+ dateAdapter?: DateAdapterName;
51
+ /**
52
+ * Enable/disable SSR
53
+ * @default true
54
+ */
55
+ ssr?: boolean;
56
+ }
57
+ interface PersistenceConfig {
58
+ enabled?: boolean;
59
+ key?: string;
60
+ storage?: 'cookie' | 'localStorage' | 'sessionStorage';
61
+ cookieOptions?: {
62
+ maxAge?: number;
63
+ path?: string;
64
+ sameSite?: 'strict' | 'lax' | 'none';
65
+ };
66
+ }
67
+ interface ModuleOptions {
68
+ /**
69
+ * Vuetify instance configuration
70
+ */
71
+ vuetifyOptions: Partial<Omit<VuetifyOptions, 'aliases' | 'blueprint' | 'theme' | 'icons' | 'locale'> & VuetifyOptionsConfig>;
72
+ /**
73
+ * Auto-import Vuetify composables
74
+ * @default true
75
+ */
76
+ importComposables?: boolean;
77
+ /**
78
+ * If you are using another composables that collide with the Vuetify ones,
79
+ * enable this flag to prefix them with `V`:
80
+ * - `useLocale` -> `useVLocale`
81
+ * - `useDefaults` -> `useVDefaults`
82
+ * - `useDisplay` -> `useVDisplay`
83
+ * - `useLayout` -> `useVLayout`
84
+ * - `useRtl` -> `useVRtl`
85
+ * - `useTheme` -> `useVTheme`
86
+ *
87
+ * @default false
88
+ */
89
+ prefixComposables?: boolean;
90
+ /**
91
+ * Transform asset URLs in Vuetify components
92
+ * @default true
93
+ */
94
+ transformAssetUrls?: boolean;
95
+ /**
96
+ * Enable automatic tree-shaking via vite-plugin-vuetify
97
+ * Vuetify components and directives will be automatically imported
98
+ * Include lab components when autoImport: { labs: true }
99
+ * @default true
100
+ */
101
+ autoImport?: boolean | {
102
+ labs?: boolean;
103
+ ignore?: (keyof typeof Components | keyof typeof Directives)[];
104
+ };
105
+ /**
106
+ * Include Vuetify styles
107
+ * @default true
108
+ */
109
+ styles?: true | 'none' | 'sass' | {
110
+ configFile: string;
111
+ };
112
+ /**
113
+ * Theme persistence configuration
114
+ * @default { enabled: true, storage: 'cookie', key: 'nuxt-vuetify-theme' }
115
+ */
116
+ persistence?: PersistenceConfig;
117
+ }
118
+ interface VuetifyRuntimeConfig {
119
+ vuetifyOptions: ModuleOptions['vuetifyOptions'];
120
+ persistence?: PersistenceConfig;
121
+ }
122
+ declare module '@nuxt/schema' {
123
+ interface NuxtConfig {
124
+ vuetify?: Partial<ModuleOptions>;
125
+ }
126
+ interface NuxtOptions {
127
+ vuetify?: ModuleOptions;
128
+ }
129
+ }
130
+ declare module 'nuxt/schema' {
131
+ interface NuxtConfig {
132
+ vuetify?: Partial<ModuleOptions>;
133
+ }
134
+ interface NuxtOptions {
135
+ vuetify?: ModuleOptions;
136
+ }
137
+ }
138
+
139
+ interface VuetifyHookContext {
140
+ vuetifyOptions: VuetifyOptions;
141
+ }
142
+ type VuetifyHooks = {
143
+ 'vuetify:register': (registerModule: (options: Partial<ModuleOptions>) => void) => HookResult;
144
+ 'vuetify:before-create': (context: VuetifyHookContext) => HookResult;
145
+ 'vuetify:configuration': (context: VuetifyHookContext) => HookResult;
146
+ 'vuetify:ready': (vuetify: ReturnType<typeof createVuetify>) => HookResult;
147
+ };
148
+
149
+ /* eslint-disable @typescript-eslint/no-empty-object-type */
150
+
151
+
152
+ declare module '#app' {
153
+ interface PublicRuntimeConfig {
154
+ vuetify: VuetifyRuntimeConfig
155
+ }
156
+
157
+ interface NuxtApp {
158
+ $vuetify: Vuetify
159
+ }
160
+
161
+ interface RuntimeNuxtHooks extends VuetifyHooks {}
162
+ }
163
+
164
+ declare module '@nuxt/schema' {
165
+ interface PublicRuntimeConfig {
166
+ vuetify: VuetifyRuntimeConfig
167
+ }
168
+
169
+ interface NuxtHooks extends VuetifyHooks {}
170
+ }
171
+
172
+ declare module 'nuxt/schema' {
173
+ interface PublicRuntimeConfig {
174
+ vuetify: VuetifyRuntimeConfig
175
+ }
176
+
177
+ interface NuxtHooks extends VuetifyHooks {}
178
+ }
179
+
180
+ declare module 'vue' {
181
+ interface ComponentCustomProperties {
182
+ $vuetify: Vuetify
183
+ }
184
+ }
185
+
186
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
187
+
188
+ export { _default as default };
189
+ export type { ModuleOptions, VuetifyHookContext, VuetifyHooks };
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "nuxt-vuetify-module",
3
+ "configKey": "vuetify",
4
+ "compatibility": {
5
+ "nuxt": ">=4.0.0"
6
+ },
7
+ "version": "1.1.0",
8
+ "builder": {
9
+ "@nuxt/module-builder": "1.0.2",
10
+ "unbuild": "3.6.1"
11
+ }
12
+ }