kobalt
Version:
A cli to generate a theme from figma projects.
91 lines (90 loc) • 3.87 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateTokens = void 0;
const figma_1 = require("../api/figma");
const fs_1 = __importDefault(require("fs"));
const style_dictionary_1 = __importDefault(require("style-dictionary"));
const colors_1 = require("./colors");
const fonts_1 = require("./fonts");
const formats_1 = require("./formats");
const flatten_1 = require("../utilities/flatten");
const templates_1 = require("./templates");
const spacing_1 = require("./spacing");
const getStyles = (pages) => pages.find((page) => page.name === process.env["FIGMA_STYLE_PAGE"]);
const getFrame = (frames) => (name) => frames.find((frame) => frame.name === name);
const generateTokens = async () => {
const project = await figma_1.figma.getProject();
const styles = getStyles(project.document.children);
if (!styles) {
throw new Error(`Invalid page name: ${process.env["FIGMA_STYLE_PAGE"]} is missing as page in figma`);
}
const frame = getFrame(styles.children);
const colorFrame = frame(process.env["FIGMA_COLOR_FRAME"]);
if (!colorFrame) {
throw new Error(`Invalid frame name: ${process.env["FIGMA_COLOR_FRAME"]} is missing as a frame in figma`);
}
const color = (0, colors_1.createColorToken)(colorFrame);
const fontFrame = frame(process.env["FIGMA_FONT_FRAME"]);
if (!fontFrame) {
throw new Error(`Invalid frame name: ${process.env["FIGMA_FONT_FRAME"]} is missing as a frame in figma`);
}
const font = (0, fonts_1.createFontToken)(fontFrame);
const spacingFrame = frame(process.env["FIGMA_SPACING_FRAME"]);
if (!spacingFrame) {
throw new Error(`Invalid frame name: ${process.env["FIGMA_SPACING_FRAME"]} is missing as a frame in figma`);
}
const spacing = (0, spacing_1.createSpacingToken)(spacingFrame);
const tokens = {
color,
font: (0, fonts_1.resolveColorReferences)((0, flatten_1.flatten)(color), font),
spacing,
};
const theme = {
color,
font,
spacing,
};
const outputFolder = `${process.cwd()}/${process.env["OUTPUT_FOLDER"]}`;
if (!fs_1.default.existsSync(outputFolder)) {
fs_1.default.mkdirSync(outputFolder);
}
const tokenFile = `${outputFolder}/tokens.json`;
fs_1.default.writeFileSync(tokenFile, JSON.stringify(tokens, null, 2));
const themeFile = `${outputFolder}/theme.ts`;
fs_1.default.writeFileSync(themeFile, (0, templates_1.createTheme)(JSON.stringify(theme, null, 2)));
const themeDeclarationFile = `${process.cwd()}/theme.d.ts`;
fs_1.default.writeFileSync(themeDeclarationFile, (0, templates_1.createThemeDeclaration)());
const outputFile = `${process.env["OUTPUT_FILE"]}.tsx`;
const buildPath = `${outputFolder}/`;
style_dictionary_1.default
.extend({
format: {
"typescript/styled-components": formats_1.createStyledComponentsFormat,
},
source: [tokenFile],
platforms: {
web: {
transformGroup: "web",
buildPath,
files: [
{
destination: outputFile,
format: "typescript/styled-components",
options: {
outputReferences: true,
},
},
],
options: {
outputReferences: true,
},
},
},
})
.buildAllPlatforms();
fs_1.default.rmSync(tokenFile);
};
exports.generateTokens = generateTokens;