Skip to main content
Glama
css-generator.ts4.89 kB
import type { FlatElement, PseudoCodeOptions } from "../types/generator.js"; /** * Generates CSS classes for all elements in the design. * Creates class definitions based on element properties and appearance. */ export const generateCSS = ({ elements, options, }: { elements: FlatElement[]; options: PseudoCodeOptions; }): string => { const cssBlocks: string[] = []; elements.forEach((element) => { if (element.type === "Component") return; const className = generateClassName(element); const cssProperties = generateCSSProperties(element); if (Object.keys(cssProperties).length > 0) { const cssBlock = formatCSSBlock({ className, properties: cssProperties, options, }); cssBlocks.push(cssBlock); } }); return cssBlocks.join("\n\n"); }; /** * Generates a CSS class name from an element's properties. * Creates a unique, clean, and descriptive class name based on element type and name. */ export const generateClassName = (element: FlatElement): string => { return element.name .toLowerCase() .replace(/[^a-z0-9\s]/g, "") .replace(/\s+/g, "-") .replace(/^-+|-+$/g, "").slice(0, 50); }; /** * Extracts and formats CSS properties from an element's attributes. * Converts Figma style properties into valid CSS properties. */ export const generateCSSProperties = ( element: FlatElement ): Record<string, string> => { const properties: Record<string, string> = {}; if (element.appearance) { const { appearance } = element; if (appearance.backgroundColor) properties["background-color"] = appearance.backgroundColor; if (appearance.borderColor) properties["border-color"] = appearance.borderColor; if (appearance.borderWidth) properties["border-width"] = appearance.borderWidth; if (appearance.borderRadius) properties["border-radius"] = appearance.borderRadius; if (appearance.opacity !== undefined) properties["opacity"] = String(appearance.opacity); if (appearance.shadow) properties["box-shadow"] = appearance.shadow; } if (element.text) { const { text } = element; if (text.fontFamily) properties["font-family"] = `'${text.fontFamily}'`; if (text.fontSize) properties["font-size"] = `${text.fontSize}px`; if (text.fontWeight) properties["font-weight"] = String(text.fontWeight); if (text.color) properties["color"] = text.color; if (text.alignment) properties["text-align"] = text.alignment.toLowerCase(); properties["margin"] = "0"; } if (element.layout) { const { layout } = element; if (layout.direction) { properties["display"] = "flex"; properties["flex-direction"] = layout.direction === "column" ? "column" : "row"; } if (layout.justifyContent) properties["justify-content"] = convertJustifyContent( layout.justifyContent ); if (layout.alignItems) properties["align-items"] = convertAlignItems(layout.alignItems); if (layout.gap) properties["gap"] = `${layout.gap}px`; if (layout.padding) properties["padding"] = layout.padding; if (layout.width) properties["width"] = layout.width; if (layout.height) properties["height"] = layout.height; } return properties; }; /** * Converts Figma justify content values to standard CSS values * Maps between Figma's property names and CSS flexbox justify-content values. */ export const convertJustifyContent = (figmaValue: string): string => { const mapping: Record<string, string> = { "space-between": "space-between", "space-around": "space-around", "space-evenly": "space-evenly", center: "center", "flex-start": "flex-start", "flex-end": "flex-end", start: "flex-start", end: "flex-end", }; return mapping[figmaValue] || figmaValue; }; /** * Converts Figma alignment values to standard CSS values * Maps between Figma's property names and CSS flexbox align-items values. */ export const convertAlignItems = (figmaValue: string): string => { const mapping: Record<string, string> = { center: "center", "flex-start": "flex-start", "flex-end": "flex-end", stretch: "stretch", baseline: "baseline", start: "flex-start", end: "flex-end", }; return mapping[figmaValue] || figmaValue; }; /** * Formats CSS properties into a properly indented CSS class block * Creates a formatted CSS class with its properties. */ export const formatCSSBlock = ({ className, properties, options, }: { className: string; properties: Record<string, string>; options: PseudoCodeOptions; }): string => { const propertyLines = Object.entries(properties) .map(([key, value]) => ` ${key}: ${value};`) .join("\n"); let cssBlock = `.${className} {\n${propertyLines}\n}`; if (options.includeComments) { cssBlock = `\n${cssBlock}`; } return cssBlock; };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/toddle-edu/figma-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server