UNPKG

@theemo/build

Version:
226 lines (218 loc) 6.97 kB
//#region rolldown:runtime var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { key = keys[i]; if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: ((k) => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); //#endregion const node_fs = __toESM(require("node:fs")); const node_path = __toESM(require("node:path")); const lightningcss = __toESM(require("lightningcss")); const read_pkg = __toESM(require("read-pkg")); const write_package = __toESM(require("write-package")); //#region ../theme/dist/index.js /** * Color Contrasts * * @see https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-contrast */ const ColorContrast = { NoPreference: "no-preference", More: "more", Less: "less", Custom: "custom" }; /** * Color Scheme * * @see https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme */ const ColorScheme = { Light: "light", Dark: "dark" }; /** * Motion * * @see https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion */ const Motion = { NoPreference: "no-preference", Reduce: "reduce" }; const BrowserMechanic = { ColorScheme: "color-scheme", ColorContrast: "color-contrast", Motion: "motion" }; /** * Checks wether the given feature uses mode behavior * * @param feature the feature in question * @returns `true` for a mode behavior, otherwise `false` */ function isModalFeature(feature) { return feature.defaultOption !== void 0; } const queries = { [BrowserMechanic.ColorScheme]: { [ColorScheme.Dark]: "(prefers-color-scheme: dark)", [ColorScheme.Light]: "(prefers-color-scheme: light)" }, [BrowserMechanic.ColorContrast]: { [ColorContrast.NoPreference]: "(prefers-color-contrast: no-preference)", [ColorContrast.More]: "(prefers-color-contrast: more)", [ColorContrast.Less]: "(prefers-color-contrast: less)", [ColorContrast.Custom]: "(prefers-color-contrast: custom)" }, [BrowserMechanic.Motion]: { [Motion.NoPreference]: "(prefers-reduced-motion: no-preference)", [Motion.Reduce]: "(prefers-reduced-motion)" } }; //#endregion //#region src/config.ts const DEFAULT_CONFIG = { outDir: "dist", features: [], lightningcss: true }; function configWithDefaults(config) { return { ...DEFAULT_CONFIG, ...config }; } //#endregion //#region src/features.ts function isModalBuildFeature(feature) { return isModalFeature(feature); } function isColorSchemeFeature(feature) { return feature.browserFeature === BrowserMechanic.ColorScheme; } function isMediaQueryFeature(feature) { return feature.browserFeature === BrowserMechanic.ColorContrast || feature.browserFeature === BrowserMechanic.Motion; } //#endregion //#region src/build.ts const MEDIA_QUERY = { [BrowserMechanic.ColorScheme]: "prefers-color-scheme", [BrowserMechanic.ColorContrast]: "prefers-contrast", [BrowserMechanic.Motion]: "prefers-reduced-motion" }; function readFile(file) { const contents = node_fs.default.existsSync(file) ? node_fs.default.readFileSync(file, "utf-8") : ""; return contents; } function combineFiles(config) { const contents = []; for (const file of config.files ?? []) contents.push(readFile(file).trim()); return contents; } function buildColorSchemeFeature(feature) { return ` :root { color-scheme: ${feature.options.join(" ")}; } [data-theemo-color-scheme="light"] { color-scheme: light; } [data-theemo-color-scheme="dark"] { color-scheme: dark; } `.trim(); } function buildFeature(feature) { const contents = []; for (const [option, file] of Object.entries(feature.options)) { const fileContents = readFile(file); const selectors = option === feature.defaultOption ? [":root"] : []; selectors.push(`[data-theemo-${feature.name}="${option}"]`); const css = fileContents.replace(":root", selectors.join(", ")).trim(); contents.push(css); } return contents; } function buildMediaQueryBrowserFeature(feature) { const contents = []; const mediaQuery = MEDIA_QUERY[feature.browserFeature]; for (const [option, file] of Object.entries(feature.options)) { const fileContents = readFile(file); const css = `@media (${mediaQuery}: ${option}) { ${fileContents} }`; contents.push(css); } return contents; } function buildFeatures(config) { const contents = []; for (const feature of config.features) { if (isColorSchemeFeature(feature)) contents.push(buildColorSchemeFeature(feature)); else if (isModalBuildFeature(feature)) contents.push(...buildFeature(feature)); if (isMediaQueryFeature(feature)) contents.push(...buildMediaQueryBrowserFeature(feature)); } return contents; } function getThemeName() { const data = (0, read_pkg.readPackageSync)(); return data.theemo?.name ?? data.name; } function buildFiles(config) { const name = getThemeName(); const contents = [...combineFiles(config), ...buildFeatures(config)]; if (!node_fs.default.existsSync(config.outDir)) node_fs.default.mkdirSync(config.outDir); const outFile = node_path.default.join(config.outDir, `${name}.css`); const css = contents.join("\n\n"); node_fs.default.writeFileSync(outFile, css); if (config.lightningcss !== false) { const options = typeof config.lightningcss === "object" ? config.lightningcss : {}; const { code } = (0, lightningcss.transform)({ code: Buffer.from(css), filename: outFile, ...options }); node_fs.default.writeFileSync(outFile, code); } } function updatePackage(config) { const packageJson = (0, read_pkg.readPackageSync)({ normalize: false }); const theemo = packageJson.theemo; theemo.file = node_path.default.join(config.outDir, `${theemo.name}.css`); theemo.features = config.features.map((f) => ({ ...f, options: Array.isArray(f.options) ? f.options : Object.keys(f.options) })); if (!Array.isArray(packageJson.keywords)) packageJson.keywords = []; if (!packageJson.keywords.includes("theemo-theme")) packageJson.keywords.push("theemo-theme"); (0, write_package.writePackageSync)(packageJson); } /** * Build a theme, which can be managed by theemo * * @param config The configuration for the theme and its behavior */ function build(config) { const defaultConfig = configWithDefaults(config); buildFiles(defaultConfig); updatePackage(defaultConfig); } //#endregion exports.build = build; //# sourceMappingURL=index.cjs.map