Skip to main content
Glama
component-processor.ts4.35 kB
import type { SimplifiedNode } from "../types/figma.js"; import type { FlatElement } from "../types/generator.js"; import { resolveAppearance, resolveText, resolveLayout, } from "./style-processor.js"; import { getSimplifiedFigmaData, simplifyType } from "./node-processor.js"; /** * Resolves component-related properties of a node. * Identifies instances, retrieves variants, and extracts component properties. */ export const resolveComponent = ({ node, components, }: { node: SimplifiedNode; components: Record<string, any>; }): FlatElement["component"] | undefined => { if ( node.type !== "INSTANCE" && !node.componentId && !node.componentProperties ) { return undefined; } const component: FlatElement["component"] = { isInstance: node.type === "INSTANCE" || !!node.componentId, }; component.componentName = node.name; if (node.componentId) { component.componentId = node.componentId; const componentDef = components[node.componentId]; if (componentDef) { if (componentDef.description) { component.description = componentDef.description; } } } if (node.componentProperties) { component.variantProperties = Object.entries(node.componentProperties).map( ([name, prop]) => { const value = typeof prop === "object" && "value" in prop ? prop.value.toString() : String(prop); return { name, value, }; } ); } if (node.exposedInstances && node.exposedInstances.length > 0) { component.exposedInstances = node.exposedInstances; } if (node.isExposedInstance !== undefined) { component.isExposed = node.isExposedInstance; } if (node.componentSetId) { component.componentSetId = node.componentSetId; } if (node.overrides && node.overrides.length > 0) { component.overrides = node.overrides.map((override) => ({ id: override.id, overriddenFields: override.overriddenFields, })); } if (node.componentPropertyReferences) { const references = Object.entries(node.componentPropertyReferences).map( ([field, reference]) => ({ field, reference, }) ); component.propertyReferences = references; } return component; }; /** * Recursively processes a node and its children to build a flat element structure. * Converts the hierarchical Figma nodes into a flat array with parent-child relationships. */ export const processNode = ({ data, elements, node, parentId, level = 0, pathPrefix = "", }: { data: ReturnType<typeof getSimplifiedFigmaData>; elements: FlatElement[]; node: SimplifiedNode; parentId?: string; level?: number; pathPrefix?: string; }): void => { const path = pathPrefix ? `${pathPrefix} > ${node.id}` : node.id; const appearance = resolveAppearance({ node, styles: data.styles }); const text = resolveText({ node, styles: data.styles }); const layout = resolveLayout({ node, styles: data.styles }); const component = resolveComponent({ node, components: data.components }); let parentComponentReferences: FlatElement["parentComponentReferences"] = []; if (node.componentPropertyReferences) { parentComponentReferences = Object.entries( node.componentPropertyReferences ).map(([name, value]) => ({ name, value })); } const flatElement: FlatElement = { id: node.id, name: node.name, type: simplifyType(node.type), parentId, childIds: node.children?.map((child) => child.id) || [], level, path, appearance, text, layout, component, parentComponentReferences, }; elements.push(flatElement); if (node.children) { node.children.forEach((child, index) => { processNode({ data, elements, node: child, parentId: node.id, level: level + 1, pathPrefix: path, }); }); } }; /** * Processes all nodes in the data to create a flat array of elements. * This is the main entry point for converting Figma nodes to processable elements. */ export const flattenElements = ( data: ReturnType<typeof getSimplifiedFigmaData> ): FlatElement[] => { const elements: FlatElement[] = []; data.nodes.forEach((node) => processNode({ data, elements, node })); return elements; };

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