vuetify-nuxt-module 0.3.0 → 0.4.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/README.md CHANGED
@@ -40,7 +40,7 @@
40
40
  - 🌍 **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
41
41
  - 📆 **Date Components**: use Vuetify components [that require date functionality](https://vuetifyjs.com/en/features/dates/) installing and configuring one of the [@date-io](https://github.com/dmtrKovalenko/date-io#projects) adapters
42
42
  - ⚙️ **Auto-Import Vuetify Composables**: you don't need to import Vuetify composables manually, they are automatically imported for you
43
- - 🎨 **Vuetify Blueprints (WIP)**: use [Vuetify Blueprints](https://vuetifyjs.com/en/features/blueprints/) to quickly scaffold components
43
+ - 🎨 **Vuetify Blueprints**: use [Vuetify Blueprints](https://vuetifyjs.com/en/features/blueprints/) to quickly scaffold components
44
44
  - 🦾 **Type Strong**: written in [TypeScript](https://www.typescriptlang.org/)
45
45
 
46
46
  ## 📦 Install
@@ -84,6 +84,34 @@ export default defineNuxtConfig({
84
84
  })
85
85
  ```
86
86
 
87
+ ## 🔥 Components, Directives, Lab Components
88
+
89
+ The module will enable automatic tree shaking for Vuetify components.
90
+
91
+ You don't need to install any Vuetify Vite Plugin (the module will throw an error if any Vuetify Vite Plugin is installed in your Nuxt configuration):
92
+ - the module will provide auto-import support via `vuetify/dist/json/importMap.json` json file and Nuxt `components:extend` hook.
93
+ - the module will register a custom Vite Plugin for Vuetify styles: it is just a copy from the original Vuetify Vite Styles Plugin, changing some virtual names mappings and handling SSR flags.
94
+
95
+ ### Global Components
96
+
97
+ If you need to add some global component, use `vuetifyOptions.components` module option, it has been declared properly to have better DX.
98
+
99
+ Check the [components definition](https://github.com/userquin/vuetify-nuxt-module/blob/main/src/types.ts#L80-L81).
100
+
101
+ You can also provide [Aliasing & Virtual Components](https://vuetifyjs.com/en/features/aliasing/#virtual-component-defaults) via `vuetifyOptions.aliases` module option to register components with a different name, only available for global components. The components require to be registered globally.
102
+
103
+ ### Directives
104
+
105
+ By default, the module will not register any Vuetify directive. If you need to register some directive, use `vuetifyOptions.directives` module option, it has been declared properly to have better DX.
106
+
107
+ You can register all the directives or only the ones you need: check the [directives definition](https://github.com/userquin/vuetify-nuxt-module/blob/main/src/types.ts#L82-L83).
108
+
109
+ ### Labs Components
110
+
111
+ The module provides support to use Vuetify [labs components](https://vuetifyjs.com/en/labs/introduction/) via `vuetifyOptions.labsComponents` module option, it has been declared properly to have better DX.
112
+
113
+ You can register all the labs components or only the ones you need: check the [labsComponent definition](https://github.com/userquin/vuetify-nuxt-module/blob/main/src/types.ts#L84-L85).
114
+
87
115
  ## 😃 Font Icons
88
116
 
89
117
  This module supports the following font icons libraries:
@@ -274,7 +302,13 @@ If you are using another composables that collide with the Vuetify ones, enable
274
302
 
275
303
  ## 🎨 Vuetify Blueprints
276
304
 
277
- **WIP**
305
+ The module supports Vuetify Blueprints, just add it to the `vuetifyOptions.blueprint` module option, but with some limitations:
306
+ - `ssr` will be ignored, this flag can be only configured internally by the module via the Nuxt ssr option.
307
+ - `components` will be ignored, configure them using the `vuetifyOptions.components` module option
308
+ - `directives` will be ignored, configure them using the `vuetifyOptions.directives` module option.
309
+ - `locale` will be ignored, configure it using the `vuetifyOptions.locale` module option.
310
+ - `date` will be ignored, configure it using the `vuetifyOptions.date` module option.
311
+ - `icons` will be ignored, configure it using the `vuetifyOptions.icons` module option.
278
312
 
279
313
  ## 👀 Full config
280
314
 
package/dist/module.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
2
  import * as vuetify from 'vuetify';
3
- import { VuetifyOptions } from 'vuetify';
4
- import * as vuetify_directives from 'vuetify/directives';
3
+ import { VuetifyOptions, LocaleOptions, RtlOptions } from 'vuetify';
5
4
  import * as vuetify_labs_components from 'vuetify/labs/components';
5
+ import * as vuetify_directives from 'vuetify/directives';
6
+ import * as vuetify_components from 'vuetify/components';
6
7
 
7
8
  type DateAdapter = 'vuetify' | 'date-fns' | 'moment' | 'luxon' | 'dayjs' | 'js-joda' | 'date-fns-jalali' | 'jalaali' | 'hijri' | 'custom';
8
9
  /**
@@ -74,11 +75,31 @@ interface IconsOptions {
74
75
  fa?: FontAwesomeSvgIconSet;
75
76
  };
76
77
  }
77
- type LabComponentName = keyof typeof vuetify_labs_components;
78
- type LabComponents = boolean | LabComponentName | LabComponentName[];
78
+ type ComponentName = keyof typeof vuetify_components;
79
+ type Components = false | ComponentName | ComponentName[];
79
80
  type DirectiveName = keyof typeof vuetify_directives;
80
81
  type Directives = boolean | DirectiveName | DirectiveName[];
81
- interface VOptions extends Partial<Omit<VuetifyOptions, 'ssr' | 'directives' | 'locale' | 'date' | 'icons'>> {
82
+ type LabComponentName = keyof typeof vuetify_labs_components;
83
+ type LabComponents = boolean | LabComponentName | LabComponentName[];
84
+ interface VOptions extends Partial<Omit<VuetifyOptions, 'ssr' | 'aliases' | 'components' | 'directives' | 'locale' | 'date' | 'icons'>> {
85
+ aliases?: Record<string, ComponentName>;
86
+ /**
87
+ * Do you need to configure some global components?.
88
+ *
89
+ * @default false
90
+ */
91
+ components?: Components;
92
+ /**
93
+ * Configure the locale messages, the locale, the fallback locale and RTL options.
94
+ *
95
+ * When `@nuxtjs/i18n` Nuxt module is present, the following options will be ignored:
96
+ * - `locale`
97
+ * - `fallback`
98
+ * - `rtl`
99
+ *
100
+ * The adapter will be `vuetify`, if you want to use another adapter, check `date` option.
101
+ */
102
+ locale?: Omit<LocaleOptions, 'adapter'> & RtlOptions;
82
103
  /**
83
104
  * Include the lab components?
84
105
  *
@@ -167,4 +188,4 @@ declare module '#app' {
167
188
 
168
189
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
169
190
 
170
- export { DateAdapter, DateOptions, DirectiveName, Directives, FontAwesomeSvgIconSet, FontIconSet, IconFontName, IconSetName, IconsOptions, JSSVGIconSet, LabComponentName, LabComponents, MOptions, ModuleOptions, VOptions, _default as default };
191
+ export { ComponentName, Components, DateAdapter, DateOptions, DirectiveName, Directives, FontAwesomeSvgIconSet, FontIconSet, IconFontName, IconSetName, IconsOptions, JSSVGIconSet, LabComponentName, LabComponents, MOptions, ModuleOptions, VOptions, _default as default };
package/dist/module.json CHANGED
@@ -4,5 +4,5 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^3.0.0"
6
6
  },
7
- "version": "0.3.0"
7
+ "version": "0.4.0"
8
8
  }
package/dist/module.mjs CHANGED
@@ -6,7 +6,7 @@ import { resolveVuetifyBase, normalizePath, writeStyles, cacheDir } from '@vueti
6
6
  import { isAbsolute, join, relative } from 'pathe';
7
7
  import { normalizePath as normalizePath$1 } from 'vite';
8
8
 
9
- const version = "0.3.0";
9
+ const version = "0.4.0";
10
10
 
11
11
  function isSubdir(root, test) {
12
12
  const relative$1 = relative(root, test);
@@ -184,11 +184,13 @@ const RESOLVED_VIRTUAL_VUETIFY_DATE_CONFIGURATION = `/@nuxt-vuetify-configuratio
184
184
  const VIRTUAL_VUETIFY_ICONS_CONFIGURATION = "virtual:vuetify-icons-configuration";
185
185
  const RESOLVED_VIRTUAL_VUETIFY_ICONS_CONFIGURATION = `/@nuxt-vuetify-configuration/${VIRTUAL_VUETIFY_ICONS_CONFIGURATION.slice("virtual:".length)}`;
186
186
 
187
- function vuetifyConfigurationPlugin(isDev, directives, labComponents, vuetifyAppOptions) {
187
+ function vuetifyConfigurationPlugin(isDev, i18n, directives, labComponents, vuetifyAppOptions) {
188
188
  const {
189
189
  directives: _directives,
190
190
  date: _date,
191
191
  icons: _icons,
192
+ components,
193
+ aliases,
192
194
  ...newVuetifyOptions
193
195
  } = vuetifyAppOptions;
194
196
  return {
@@ -200,55 +202,98 @@ function vuetifyConfigurationPlugin(isDev, directives, labComponents, vuetifyApp
200
202
  },
201
203
  async load(id) {
202
204
  if (id === RESOLVED_VIRTUAL_VUETIFY_CONFIGURATION) {
203
- const directivesResult = buildDirectives();
204
- const labComponentsResult = buildLabComponents();
205
- return `${directivesResult.imports}
206
- ${labComponentsResult.imports}
205
+ if (i18n && newVuetifyOptions.locale) {
206
+ delete newVuetifyOptions.locale.rtl;
207
+ delete newVuetifyOptions.locale.locale;
208
+ delete newVuetifyOptions.locale.fallback;
209
+ }
210
+ const result = buildConfiguration();
211
+ return `${result.imports}
207
212
 
208
213
  export const isDev = ${isDev}
209
214
  export function vuetifyConfiguration() {
210
- const options = ${JSON.stringify(newVuetifyOptions)}
211
- ${directivesResult.expression}
212
- ${labComponentsResult.expression}
215
+ const options = JSON.parse('${JSON.stringify(newVuetifyOptions)}')
216
+ ${result.directives}
217
+ ${result.aliases}
218
+ ${result.components}
213
219
  return options
214
220
  }
215
221
  `;
216
222
  }
217
223
  }
218
224
  };
219
- function buildDirectives() {
220
- if (!directives)
221
- return { imports: "", expression: "" };
225
+ function buildConfiguration() {
226
+ const dateOptions = vuetifyAppOptions.date;
227
+ const config = {
228
+ directives: "",
229
+ imports: [],
230
+ aliasEntries: [],
231
+ aliases: aliases || {},
232
+ components: new Set(components ? Array.isArray(components) ? components : [components] : []),
233
+ labComponents: /* @__PURE__ */ new Set()
234
+ };
222
235
  if (typeof directives === "boolean") {
223
- return {
224
- imports: "import * as directives from 'vuetify/directives'",
225
- expression: "options.directives = directives"
226
- };
236
+ config.imports.push("import * as directives from 'vuetify/directives'");
237
+ config.directives = "options.directives = directives";
227
238
  } else {
228
239
  const useDirectives = Array.isArray(directives) ? directives : [directives];
229
- return {
230
- imports: `${useDirectives.map((d) => `import { ${d} } from 'vuetify/directives/${d}'`).join("\n")}`,
231
- expression: `options.directives = {${useDirectives.join(",")}}`
232
- };
240
+ config.imports.push(useDirectives.map((d) => `import { ${d} } from 'vuetify/directives/${d}'`).join("\n"));
241
+ config.directives = `options.directives = {${useDirectives.join(",")}}`;
233
242
  }
234
- }
235
- function buildLabComponents() {
236
- const dateOptions = vuetifyAppOptions.date;
237
- if (!labComponents && !dateOptions)
238
- return { imports: "", expression: "" };
239
- if (typeof labComponents === "boolean") {
240
- return {
241
- imports: "import * as labsComponents from 'vuetify/labs/components'",
242
- expression: "options.components = labsComponents"
243
- };
244
- } else {
245
- const useComponents = Array.isArray(labComponents) ? labComponents : [labComponents];
246
- const components = [...new Set(dateOptions ? ["VDatePicker", ...useComponents] : useComponents)];
247
- return {
248
- imports: `${components.map((d) => `import { ${d} } from 'vuetify/labs/${d}'`).join("\n")}`,
249
- expression: `options.components = {${components.join(",")}}`
250
- };
243
+ config.imports.push(...Array.from(config.components).map((c) => `import {${c}} from 'vuetify/components/${c}'`));
244
+ Object.entries(config.aliases).forEach(([key, component]) => {
245
+ if (!config.components.has(component)) {
246
+ config.components.add(component);
247
+ config.imports.push(`import {${component}} from 'vuetify/components/${component}'`);
248
+ }
249
+ config.aliasEntries.push(`'${key}': ${component}`);
250
+ });
251
+ let addDatePicker = true;
252
+ if (labComponents) {
253
+ if (typeof labComponents === "boolean") {
254
+ config.imports.push("import * as labsComponents from 'vuetify/labs/components'");
255
+ config.labComponents.add("*");
256
+ addDatePicker = false;
257
+ } else if (Array.isArray(labComponents)) {
258
+ labComponents.forEach((labComponent) => {
259
+ if (!config.labComponents.has(labComponent)) {
260
+ config.labComponents.add(labComponent);
261
+ config.imports.push(`import {${labComponent}} from 'vuetify/labs/${labComponent}'`);
262
+ }
263
+ });
264
+ addDatePicker = !config.labComponents.has("VDatePicker");
265
+ } else {
266
+ config.imports.push(`import {${labComponents}} from 'vuetify/labs/${labComponents}'`);
267
+ config.labComponents.add(labComponents);
268
+ addDatePicker = labComponents !== "VDatePicker";
269
+ }
270
+ }
271
+ if (dateOptions && addDatePicker) {
272
+ config.imports.push("import {VDatePicker} from 'vuetify/labs/VDatePicker'");
273
+ config.labComponents.add("VDatePicker");
251
274
  }
275
+ let componentsEntry = "";
276
+ if (config.components.size) {
277
+ if (config.labComponents.size) {
278
+ if (config.labComponents.has("*"))
279
+ componentsEntry = `options.components = {${Array.from(config.components).join(",")},...labsComponents}`;
280
+ else
281
+ componentsEntry = `options.components = {${Array.from(config.components).join(",")},${Array.from(config.labComponents).join(",")}}`;
282
+ } else {
283
+ componentsEntry = `options.components = {${Array.from(config.components).join(",")}}`;
284
+ }
285
+ } else if (config.labComponents.size) {
286
+ if (config.labComponents.has("*"))
287
+ componentsEntry = "options.components = {...labsComponents}";
288
+ else
289
+ componentsEntry = `options.components = {${Array.from(config.labComponents).join(",")}}`;
290
+ }
291
+ return {
292
+ imports: config.imports.length ? config.imports.join("\n") : "",
293
+ components: componentsEntry,
294
+ aliases: config.aliasEntries.length ? `options.aliases = {${config.aliasEntries.join(",")}}` : "",
295
+ directives: config.directives
296
+ };
252
297
  }
253
298
  }
254
299
 
@@ -269,7 +314,7 @@ export const isDev = ${isDev}
269
314
  export const i18n = ${i18n}
270
315
  export const adapter = '${dateAdapter}'
271
316
  export function dateConfiguration() {
272
- const options = ${JSON.stringify(newDateOptions)}
317
+ const options = JSON.parse('${JSON.stringify(newDateOptions)}')
273
318
  ${buildAdapter()}
274
319
  return options
275
320
  }
@@ -536,6 +581,7 @@ const module = defineNuxtModule({
536
581
  const vuetifyAppOptions = defu(vOptions, {
537
582
  ssr: isSSR
538
583
  });
584
+ cleanupBlueprint(vuetifyAppOptions);
539
585
  const { styles } = moduleOptions;
540
586
  const i18n = hasNuxtModule("@nuxtjs/i18n", nuxt);
541
587
  let dateAdapter;
@@ -630,6 +676,7 @@ const module = defineNuxtModule({
630
676
  viteInlineConfig.plugins.push(vuetifyStylesPlugin({ styles }, logger));
631
677
  viteInlineConfig.plugins.push(vuetifyConfigurationPlugin(
632
678
  nuxt.options.dev,
679
+ i18n,
633
680
  directives,
634
681
  labComponents,
635
682
  vuetifyAppOptions
@@ -677,5 +724,17 @@ function detectDate() {
677
724
  const result = [];
678
725
  return result;
679
726
  }
727
+ function cleanupBlueprint(vuetifyOptions) {
728
+ const blueprint = vuetifyOptions.blueprint;
729
+ if (blueprint) {
730
+ delete blueprint.ssr;
731
+ delete blueprint.components;
732
+ delete blueprint.directives;
733
+ delete blueprint.locale;
734
+ delete blueprint.date;
735
+ delete blueprint.icons;
736
+ vuetifyOptions.blueprint = blueprint;
737
+ }
738
+ }
680
739
 
681
740
  export { module as default };
@@ -7,8 +7,7 @@ import {
7
7
  toRaw,
8
8
  watch
9
9
  } from "vue";
10
- import { toKebabCase } from "../../utils";
11
- import { useI18n } from "#imports";
10
+ import { useI18n } from "vue-i18n";
12
11
  import { useNuxtApp } from "#app";
13
12
  export function createAdapter(vuetifyOptions) {
14
13
  vuetifyOptions.locale = {};
@@ -60,6 +59,9 @@ function useToggleScope(source, fn) {
60
59
  scope?.stop();
61
60
  });
62
61
  }
62
+ function toKebabCase(str = "") {
63
+ return str.replace(/[^a-z]/gi, "-").replace(/\B([A-Z])/g, "-$1").toLowerCase();
64
+ }
63
65
  function useProxiedModel(props, prop, defaultValue, transformIn = (v) => v, transformOut = (v) => v) {
64
66
  const vm = getCurrentInstance("useProxiedModel");
65
67
  const internal = ref(props[prop] !== void 0 ? props[prop] : defaultValue);
package/dist/types.d.ts CHANGED
@@ -12,4 +12,4 @@ declare module 'nuxt/schema' {
12
12
  }
13
13
 
14
14
 
15
- export { DateAdapter, DateOptions, DirectiveName, Directives, FontAwesomeSvgIconSet, FontIconSet, IconFontName, IconSetName, IconsOptions, JSSVGIconSet, LabComponentName, LabComponents, MOptions, ModuleOptions, VOptions, default } from './module'
15
+ export { ComponentName, Components, DateAdapter, DateOptions, DirectiveName, Directives, FontAwesomeSvgIconSet, FontIconSet, IconFontName, IconSetName, IconsOptions, JSSVGIconSet, LabComponentName, LabComponents, MOptions, ModuleOptions, VOptions, default } from './module'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vuetify-nuxt-module",
3
3
  "type": "module",
4
- "version": "0.3.0",
4
+ "version": "0.4.0",
5
5
  "packageManager": "pnpm@8.6.6",
6
6
  "description": "Zero-Config Nuxt Module for Vuetify ",
7
7
  "author": "userquin <userquin@gmail.com>",