UNPKG

@primevue/nuxt-module

Version:

Nuxt module for PrimeVue

306 lines (294 loc) 11.7 kB
import { addComponent, addImports, defineNuxtModule, createResolver, addTemplate, addPlugin, addPluginTemplate } from '@nuxt/kit'; import { isNotEmpty as isNotEmpty$1 } from '@primeuix/utils'; import { PrimeVueResolver } from '@primevue/auto-import-resolver'; import { normalize } from 'pathe'; import Components from 'unplugin-vue-components/nuxt'; import { isFunction, isNotEmpty, resolve, isString } from '@primeuix/utils/object'; import { components, directives, composables } from '@primevue/metadata'; import { createStyleAsString } from '@primeuix/utils/dom'; const Utils = { object: { getName(item, options) { return isFunction(options?.name) ? options.name(item) : `${options.prefix}${item.name}`; }, getPath(fn, options) { return isFunction(fn) ? fn(options) : options.from; }, createStyleAsString(css, options = { name: "" }) { const { name, ...rest } = options; return createStyleAsString(css, { "data-primevue-style-id": name, ...rest }); } } }; function registerItems(items = [], options = {}, params) { const included = resolve(options.include, params); const excluded = resolve(options.exclude, params); const isMatched = (name, tName) => name?.toLowerCase() === (isString(tName) ? tName?.toLowerCase() : tName?.name?.toLowerCase()); return items.filter((item) => { const name = item?.name; const matchedIn = included === "*" || included === void 0 ? true : isNotEmpty(included) ? included.some((inc) => isMatched(name, inc)) : false; const matchedEx = included === "*" && excluded === "*" ? false : excluded === "*" ? true : isNotEmpty(excluded) ? excluded.some((exc) => isMatched(name, exc)) : false; return matchedIn && !matchedEx; }); } function registerConfig(resolvePath) { return [ { name: "PrimeVue", as: "PrimeVue", from: resolvePath({ name: "PrimeVue", as: "PrimeVue", from: `primevue/config`, type: "config" }) } ]; } function registerComponents(resolvePath, moduleOptions) { const options = moduleOptions.components || {}; const items = registerItems(components, options, { components }); return items.map((item) => { const _item = { ...item, name: item.name, as: item.name, from: item.from }; const name = Utils.object.getName(_item, options); const from = resolvePath({ name, as: _item.as, from: _item.from, type: "component" }); const opt = { export: "default", name, filePath: from, global: true }; //!moduleOptions.autoImport && addComponent(opt); addComponent(opt); return { ..._item, ...opt }; }); } function registerDirectives(resolvePath, moduleOptions) { const options = moduleOptions.directives || {}; const items = registerItems(directives, options, { directives }); return items.map((item) => { const name = Utils.object.getName(item, options); const opt = { ...item, name, from: resolvePath({ name, as: item.as, from: item.from, type: "directive" }) }; return opt; }); } function registerComposables(resolvePath, moduleOptions) { const options = moduleOptions.composables || {}; const items = registerItems(composables, options, { composables }); return items.map((item) => { const name = item.name; const opt = { ...item, name, from: resolvePath({ name, as: item.as, from: item.from, type: "composable" }) }; addImports(opt); return opt; }); } function registerServices(resolvePath, registered) { const services = /* @__PURE__ */ new Set(); registered?.components?.forEach((component) => component?.use && services.add(component.use.as)); return [...services].map((service) => ({ name: service, as: service, from: resolvePath({ name: service, as: service, from: `primevue/${service.toLowerCase()}`, type: "service" }) })); } function registerStyles(resolvePath, registered, moduleOptions) { const options = moduleOptions.options || {}; const styles = [ { name: "BaseStyle", as: "BaseStyle", from: resolvePath({ name: "BaseStyle", as: "BaseStyle", from: "@primevue/core/base/style", type: "style" }) } ]; if (!options?.unstyled) { if (isNotEmpty(registered?.components)) { styles.push({ name: "BaseComponentStyle", as: "BaseComponentStyle", from: resolvePath({ name: "BaseComponentStyle", as: "BaseComponentStyle", from: "@primevue/core/basecomponent/style", type: "style" }) }); } [registered.components, registered.directives].flat().reduce((acc, citem) => acc.some((item) => item.as.toLowerCase() === citem.as.toLowerCase()) ? acc : [...acc, citem], []).forEach( (item) => styles.push({ name: `${item.as}Style`, as: `${item.as}Style`, from: resolvePath({ name: `${item.as}Style`, as: `${item.as}Style`, from: `${item.from.toLowerCase()}/style`, type: "style" }) }) ); } return styles; } function registerInjectStylesAsString(moduleOptions) { return []; } function registerInjectStylesAsStringToTop(moduleOptions) { return [Utils.object.createStyleAsString(moduleOptions.cssLayerOrder ? `@layer ${moduleOptions.cssLayerOrder}` : void 0, { name: "layer-order" })]; } function register(moduleOptions) { const resolvePath = (resolveOptions) => Utils.object.getPath(moduleOptions.resolvePath, resolveOptions); const config = registerConfig(resolvePath); const components2 = registerComponents(resolvePath, moduleOptions); const directives2 = registerDirectives(resolvePath, moduleOptions); const composables2 = registerComposables(resolvePath, moduleOptions); const registered = { components: components2, directives: directives2, composables: composables2 }; const services = registerServices(resolvePath, registered); const styles = registerStyles(resolvePath, registered, moduleOptions); const injectStylesAsString = registerInjectStylesAsString(); const injectStylesAsStringToTop = registerInjectStylesAsStringToTop(moduleOptions); return { config, ...registered, services, styles, injectStylesAsString, injectStylesAsStringToTop }; } const module = defineNuxtModule({ meta: { name: "@primevue/nuxt-module", configKey: "primevue", compatibility: { nuxt: ">=3.0.0" } }, defaults: { usePrimeVue: true, autoImport: true, resolvePath: void 0, //cssLayerOrder: undefined, importPT: void 0, importTheme: void 0, loadStyles: true, options: {}, components: { prefix: "", name: void 0, include: void 0, exclude: void 0 }, directives: { prefix: "", name: void 0, include: void 0, exclude: void 0 }, composables: { //prefix: '', name: void 0, include: void 0, exclude: void 0 } }, hooks: {}, setup(moduleOptions, nuxt) { moduleOptions.components.exclude = moduleOptions.components.exclude || ["Editor", "Chart"]; const resolver = createResolver(import.meta.url); const registered = register(moduleOptions); const { autoImport, importPT, importTheme, options, loadStyles } = moduleOptions; const hasTheme = options?.theme !== "none" && (importTheme || options?.theme) && !options?.unstyled; nuxt.options.runtimeConfig.public.primevue = { ...moduleOptions, ...registered }; nuxt.options.build.transpile.push("primevue"); hasTheme && nuxt.options.build.transpile.push("@primevue/themes"); hasTheme && nuxt.options.build.transpile.push("@primeuix/themes"); let registeredStyles = registered.styles; if (autoImport) { const dts = isNotEmpty$1(moduleOptions.components?.prefix) || isNotEmpty$1(moduleOptions.directives?.prefix); Components( { dts, resolvers: [ PrimeVueResolver({ components: moduleOptions.components, directives: moduleOptions.directives }) ] }, nuxt ); } const styleContent = () => { if (!loadStyles) return `export const styles = [], stylesToTop = [], themes = [];`; const uniqueRegisteredStyles = Array.from(new Map(registeredStyles?.map((m) => [m.name, m])).values()); return ` import { useRuntimeConfig } from '#imports'; ${uniqueRegisteredStyles?.map((style) => `import ${style.as} from '${style.from}';`).join("\n")} ${hasTheme ? `import { Theme } from '@primeuix/styled'; ${importTheme ? `import ${importTheme.as} from '${normalize(importTheme.from)}'; ` : ""}` : ""} const runtimeConfig = useRuntimeConfig(); const config = runtimeConfig?.public?.primevue ?? {}; const { options = {} } = config; const stylesToTop = [${registered.injectStylesAsStringToTop.join("")}].join(''); const styleProps = { ${options?.csp?.nonce ? `nonce: ${options?.csp?.nonce}` : ""} } const styles = [ ${registered.injectStylesAsString.join("")}, ${uniqueRegisteredStyles?.map((item) => `${item.as} && ${item.as}.getStyleSheet ? ${item.as}.getStyleSheet(undefined, styleProps) : ''`).join(",")} ].join(''); ${hasTheme ? `Theme.setTheme(${importTheme?.as} || options?.theme)` : ""} const themes = ${!hasTheme ? `[]` : ` [ ${`${uniqueRegisteredStyles?.[0].as} && ${uniqueRegisteredStyles?.[0].as}.getCommonThemeStyleSheet ? ${uniqueRegisteredStyles?.[0].as}.getCommonThemeStyleSheet(undefined, styleProps) : ''`}, ${uniqueRegisteredStyles?.map((item) => `${item.as} && ${item.as}.getThemeStyleSheet ? ${item.as}.getThemeStyleSheet(undefined, styleProps) : ''`).join(",")} ].join('');`} export { styles, stylesToTop, themes }; `; }; nuxt.options.alias["#primevue-style"] = addTemplate({ filename: "primevue-style.mjs", getContents: styleContent }).dst; addPlugin(resolver.resolve("./runtime/plugin.client")); addPluginTemplate({ filename: "primevue-plugin.mjs", getContents() { return ` import { defineNuxtPlugin, useRuntimeConfig } from '#imports'; ${registered.config.map((config) => `import ${config.as} from '${config.from}';`).join("\n")} ${registered.services.map((service) => `import ${service.as} from '${service.from}';`).join("\n")} ${!autoImport && registered.directives.map((directive) => `import ${directive.as} from '${directive.from}';`).join("\n")} ${importPT ? `import ${importPT.as} from '${normalize(importPT.from)}'; ` : ""} ${hasTheme && importTheme ? `import ${importTheme.as} from '${normalize(importTheme.from)}'; ` : ""} export default defineNuxtPlugin(({ vueApp }) => { const runtimeConfig = useRuntimeConfig(); const config = runtimeConfig?.public?.primevue ?? {}; const { usePrimeVue = true, options = {} } = config; const pt = ${importPT ? `{ pt: ${importPT.as} }` : `{}`}; const theme = ${hasTheme ? `{ theme: ${importTheme?.as} || options?.theme }` : `{}`}; usePrimeVue && vueApp.use(PrimeVue, { ...options, ...pt, ...theme }); ${registered.services.map((service) => `vueApp.use(${service.as});`).join("\n")} ${!autoImport && registered.directives.map((directive) => `vueApp.directive('${directive.name}', ${directive.as});`).join("\n")} }); `; } }); nuxt.hook("nitro:config", async (config) => { config.externals = config.externals || {}; config.externals.inline = config.externals.inline || []; config.externals.inline.push(resolver.resolve("./runtime/plugin.server")); config.virtual = config.virtual || {}; config.virtual["#primevue-style"] = styleContent; config.plugins = config.plugins || []; config.plugins.push(resolver.resolve("./runtime/plugin.server")); }); } }); export { module as default };