UNPKG

@kanton-basel-stadt/designsystem

Version:

Unplugin to install the digital design system of the canton of Basel-Stadt

311 lines (294 loc) 9.81 kB
import { postcss_config_default } from "./chunk-MSCKX2TC.js"; // src/index.ts import { createUnplugin } from "unplugin"; // src/core/unplugins/postcssTailwind.ts import fs from "node:fs"; import path4 from "node:path"; // src/core/utils/getConfigsPath.ts import path2 from "node:path"; // src/core/utils/getDirName.ts import path from "node:path"; import { fileURLToPath } from "node:url"; function getDirName() { return path.dirname(fileURLToPath(import.meta.url)); } // src/core/utils/getConfigsPath.ts function getConfigsPath() { const dirname = getDirName(); return path2.resolve(`${dirname}/configs/`); } // src/core/utils/getPostcssConfig.ts import merge from "lodash.merge"; import loadOptions from "postcss-load-config/src/options.js"; import loadPlugins from "postcss-load-config/src/plugins.js"; async function getPostcssConfig(configPath, tailwindConfig) { if (tailwindConfig) { postcss_config_default.plugins.tailwindcss.config = merge(postcss_config_default.plugins.tailwindcss.config, tailwindConfig); } const file = `${configPath}/postcss.config.ts`; return { file, options: await loadOptions(postcss_config_default, file), plugins: await loadPlugins(postcss_config_default, file) }; } // src/core/utils/transformIdsInCode.ts import path3 from "node:path"; import MagicString from "magic-string"; function transformIdsInCode(code, id) { let dirname = getDirName(); if (dirname.endsWith(path3.sep)) { dirname = dirname.replace(/[\\/]+$/, ""); } if (dirname.endsWith("dist")) { dirname = dirname.replace(/[\\/]+dist$/, ""); } const s = new MagicString(code); s.replace(/(['"(]+)(@{1,2})kanton-basel-stadt\/designsystem\/(icons\/symbols\/(\w+)|([^"')]+))(['")]+)/g, (_, surroundingStart, ats, fullPathMatch, _2, iconMatch, surroundingEnd) => { if (ats.length === 2) { return `${surroundingStart}@kanton-basel-stadt/designsystem/${fullPathMatch}${surroundingEnd}`; } if (fullPathMatch.startsWith(path3.sep) || fullPathMatch.startsWith("/")) { fullPathMatch = fullPathMatch.replace(/^[\\/]+/, ""); } if (fullPathMatch.startsWith("icons/symbol/")) { return `${surroundingStart}~${iconMatch}${surroundingEnd}`; } if (fullPathMatch.startsWith("dist")) { fullPathMatch = fullPathMatch.replace(/^dist[\\/]+/, ""); } fullPathMatch = fullPathMatch.replace(/\//g, path3.sep); return `${surroundingStart}${dirname}${path3.sep}dist${path3.sep}${fullPathMatch}${surroundingEnd}`; }); if (!s.hasChanged()) { return; } return { code: s.toString(), map: s.generateMap({ source: id, includeContent: true, hires: true }) }; } // src/core/unplugins/postcssTailwind.ts function getPostcssTailwindUnplugin(options) { const postcssConfig = getPostcssConfig(getConfigsPath(), options.tailwindOptions?.config); return { name: "@kanton-basel-stadt/designsystem/postcss-tailwind", esbuild: { async setup(build) { build.onLoad({ filter: /\.woff2?$/i }, () => { return { loader: "copy" }; }); const postcss = (await import("postcss")).default; const loadedPostcss = await postcssConfig; const postcssInstance = postcss(loadedPostcss.plugins); build.onLoad({ filter: /\.css$/i }, async (args) => { const code = fs.readFileSync(args.path, "utf-8"); const transformed = transformIdsInCode(code, args.path); const processed = await postcssInstance.process(transformed ? transformed.code : code, { from: args.path, to: options.tailwindOptions?.targetDir || "dist", map: { absolute: true, from: args.path } }); return { contents: processed.content, loader: "css" }; }); } }, webpack(compiler) { compiler.hooks.beforeRun.tapPromise("@kanton-basel-stadt/designsystem", async (params) => { let initialLoader = "style-loader"; if (params.options.mode === "production") { const MiniCssExtractPlugin = (await import("mini-css-extract-plugin")).default; new MiniCssExtractPlugin({ filename: "app.css" }).apply(params); initialLoader = { loader: MiniCssExtractPlugin.loader, options: { publicPath: "../" // adjust based on where fonts are output relative to your CSS } }; } const postcssConfigLoaded = await postcssConfig; const cssLoaders = [ initialLoader, { loader: "css-loader", options: { url: true, modules: false, importLoaders: 1 } }, { loader: "postcss-loader", options: { postcssOptions: { plugins: postcssConfigLoaded.plugins, to: options.tailwindOptions?.targetDir || "dist", modules: false } } } ]; params.options.module.rules.push({ test: /\.css$/, use: cssLoaders }); params.options.module.rules.unshift({ test: /\.(woff2?)$/i, type: "asset/resource" }); }); }, rollup: { async options(rollupOptions) { const postcss = (await import("rollup-plugin-postcss")).default; const urlCopy = (await import("postcss-url-copy")).default; if (!rollupOptions.plugins) { rollupOptions.plugins = []; } const fullTargetDir = path4.resolve(options.tailwindOptions?.targetDir || "dist"); const plugins = [ ...(await postcssConfig).plugins, urlCopy({ destPath: fullTargetDir, assetsDestPath: `${fullTargetDir}${path4.sep}assets`, transformUrlBeforeLoad(url) { return url.replace(/@kanton-basel-stadt\/designsystem\//g, `.${path4.sep}node_modules${path4.sep}@kanton-basel-stadt${path4.sep}designsystem${path4.sep}dist${path4.sep}`); }, transformUrlBeforeWrite(url) { return url.replace(fullTargetDir, "."); } }) ]; if (Array.isArray(rollupOptions.plugins)) { rollupOptions.plugins.unshift(postcss({ extract: true, modules: false, to: options.tailwindOptions?.targetDir || "dist/", plugins })); } return rollupOptions; } }, vite: { async config() { return { css: { postcss: await postcssConfig } }; } } }; } // src/core/unplugins/transformIds.ts function getTransformIdsUnplugin() { return { name: "@kanton-basel-stadt/designsystem/transform-ids", enforce: "pre", transform: transformIdsInCode, transformInclude(id) { return !id.endsWith(".woff") && !id.endsWith(".woff2"); }, esbuild: { onLoadFilter: /\.(?!woff2?$)[^.]+$/i }, vite: { config() { return { optimizeDeps: { exclude: ["@kanton-basel-stadt/designsystem/dist/configs/icons-index"] } }; } } }; } // src/core/unplugins/unpluginIconsPatched.ts import merge2 from "lodash.merge"; import { optimize } from "svgo"; import unpluginIcons from "unplugin-icons"; import { FileSystemIconLoader } from "unplugin-icons/loaders"; // src/core/utils/getAssetsPath.ts import path5 from "node:path"; function getAssetsPath() { const dirname = getDirName(); return path5.resolve(`${dirname}${path5.sep}assets${path5.sep}`); } // src/core/utils/consts.ts var ICON_PATH_ALIAS = "@kanton-basel-stadt/designsystem/icons/symbol"; var ICON_PATH = "~icons/symbol"; // src/core/utils/transformIconId.ts function transformIconId(id) { return id.replace(ICON_PATH_ALIAS, ICON_PATH); } // src/core/unplugins/unpluginIconsPatched.ts function getUnpluginIconsPatchedUnplugin(options, meta) { const unpluginIconsConfig = { customCollections: { symbol: FileSystemIconLoader(`${getAssetsPath()}/symbols`, (svg) => { const res = optimize(svg, { plugins: [ "removeEmptyAttrs", "removeDimensions", // Width and height can mess with the rendering in some browsers. "removeComments" // Not needed for the final icon. ] }); return res.data; }) }, compiler: "web-components", webComponents: { autoDefine: true } }; const mergedUnpluginIconsConfig = merge2(unpluginIconsConfig, options.iconOptions); if (mergedUnpluginIconsConfig.compiler !== "web-components") { delete mergedUnpluginIconsConfig.webComponents; } let builtUnpluginIcons = unpluginIcons; if ("default" in unpluginIcons) builtUnpluginIcons = unpluginIcons.default; const usableUnpluginIcons = builtUnpluginIcons.raw(mergedUnpluginIconsConfig, meta); return { ...usableUnpluginIcons, name: "unplugin-icons-patched", resolveId(id) { return usableUnpluginIcons.resolveId(transformIconId(id)); }, loadInclude(id) { return usableUnpluginIcons.loadInclude(transformIconId(id)); }, async load(id) { return await usableUnpluginIcons.load(transformIconId(id)); } }; } // src/index.ts var unpluginFactory = (options, meta) => { if (options === void 0) { options = {}; } return [ getTransformIdsUnplugin(), getUnpluginIconsPatchedUnplugin(options, meta), getPostcssTailwindUnplugin(options) ]; }; var unplugin = /* @__PURE__ */ createUnplugin(unpluginFactory); var src_default = unplugin; export { unpluginFactory, unplugin, src_default };