Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/.vitepress/theme/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import defaultTheme from "vitepress/theme";
import "../../../packages/theme/src/index.css";
import "./custom.css";

export default {
Expand Down
31 changes: 25 additions & 6 deletions packages/theme/package.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,37 @@
{
"name": "@tapsioss/theme",
"version": "0.3.1",
"version": "0.4.0",
"type": "module",
"files": [
"./dist/**/*.css"
"./dist"
],
"main": "./dist/index.css",
"types": "./dist/types.d.ts",
"exports": {
".": {
"default": "./dist/index.css"
"./css-variables": {
"default": "./dist/default-theme/tokens.css"
},
"./*/css-variables": {
"default": "./dist/*/tokens.css"
},
"./tokens": {
"default": "./dist/default-theme/tokens.js",
"types": "./dist/default-theme/tokens.d.ts"
},
"./*/tokens": {
"default": "./dist/*/tokens.js",
"types": "./dist/*/tokens.d.ts"
},
"./types": {
"default": "./dist/types.d.ts"
}
},
"scripts": {
"build": "tsx ./scripts/build.ts",
"clear": "shx rm -rf dist",
"prebuild": "run-s clear generate",
"build:transpile": "tsc --project tsconfig.build.json",
"build:copy-css": "tsx ./scripts/copy-css-vars.ts",
"build": "run-s build:*",
"generate": "tsx ./scripts/generate.ts",
"release": "pnpm publish . --tag latest --access public"
}
}
47 changes: 0 additions & 47 deletions packages/theme/scripts/build.ts

This file was deleted.

36 changes: 36 additions & 0 deletions packages/theme/scripts/copy-css-vars.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* eslint-disable no-console */
import globAsync from "fast-glob";
import * as fs from "node:fs/promises";
import * as path from "node:path";
import { getFileMeta } from "../../../scripts/utils.ts";

const { dirname } = getFileMeta(import.meta.url);

const packageDir = path.resolve(dirname, "..");
const srcDir = path.join(packageDir, "src");
const distDir = path.join(packageDir, "dist");
const varsGlobPath = path.join(srcDir, "**/tokens.css");

const copyCssVars = async () => {
const varsFiles = await globAsync(varsGlobPath);
const promises: Promise<void>[] = [];

for (const varsFile of varsFiles) {
const varsPath = path.normalize(varsFile);
const themeDir = path.dirname(varsPath);
const theme = path.basename(themeDir);

promises.push(
fs.copyFile(varsPath, path.join(distDir, theme, "tokens.css")),
);
}

await Promise.all(promises);
};

void (async () => {
console.time("copy-css-vars");
await copyCssVars();
console.timeEnd("copy-css-vars");
})();
/* eslint-enable no-console */
98 changes: 98 additions & 0 deletions packages/theme/scripts/generate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/* eslint-disable no-console */
import globAsync from "fast-glob";
import { exec } from "node:child_process";
import * as fs from "node:fs/promises";
import * as path from "node:path";
import { promisify } from "node:util";
import { getFileMeta } from "../../../scripts/utils.ts";
import type { Tokens } from "../src/types.ts";

type ModuleWithDefaultExport<T> = {
default: T;
};

const execCmd = promisify(exec);

const { dirname } = getFileMeta(import.meta.url);

const packageDir = path.resolve(dirname, "..");
const srcDir = path.join(packageDir, "src");
const tokensGlobPath = path.join(srcDir, "**/tokens.ts");

const generateVar = (
entries: Array<[PropertyKey, unknown]>,
result: string[] = [],
varPath: PropertyKey[] = [],
): string[] => {
for (const entry of entries) {
const [key, val] = entry;

const hasPrimitiveVal = typeof val === "number" || typeof val === "string";

varPath.push(key);

if (hasPrimitiveVal) {
result.push(`--tapsi-${varPath.join("-")}: ${val};`);
} else if (val !== null && typeof val === "object") {
generateVar(Object.entries(val), result, varPath);
}

varPath.pop();
}

return result;
};

const generateVars = async (tokensPath: string, varsPath: string) => {
await execCmd(["shx", "rm", "-rf", varsPath].join(" "));

let tokensModule: ModuleWithDefaultExport<Tokens> | null = null;

try {
tokensModule = (await import(
tokensPath
)) as ModuleWithDefaultExport<Tokens>;
} catch (err) {
console.error(`Couldn't resolve module at ${tokensPath}.`, { err });

return Promise.resolve();
}

const { default: tokens } = tokensModule;

const vars = [
":root {",
generateVar(Object.entries(tokens)).join("\n"),
"}",
].join("\n");

await fs.writeFile(varsPath, vars, { encoding: "utf-8" });
await execCmd(`prettier ${varsPath} --write --fix`);
};

const generate = async () => {
const tokensFiles = await globAsync(tokensGlobPath);
const promises: Promise<void>[] = [];

for (const tokensFile of tokensFiles) {
const tokensPath = path.normalize(tokensFile);
const themeDir = path.dirname(tokensPath);
const theme = path.basename(themeDir);
const varsPath = path.join(themeDir, "tokens.css");

console.log(`🧩 generating variables for ${theme}...`);

promises.push(generateVars(tokensPath, varsPath));
}

await Promise.all(promises);

console.log("✅ generation completed.");
};

void (async () => {
console.time("generate");
await generate();
console.timeEnd("generate");
})();
/* eslint-enable no-console */
Loading