- 桌面应用
- 开发者工具
- 人工智能
- AI 应用
- AI Agent
- 代码智能体
【免费下载链接】warp
Warp is an agentic development environment, born out of the terminal.
本文是 figma-use Skill 核心参考文档 text-style-patterns.md 的完整展开。它回答一个实际问题:当需要通过
use_figmaMCP 在 Figma 文件中用代码创建、查询和应用文本样式(Text Style)时,应该怎么写 JavaScript?读完本文,你将掌握文本样式列举、字体探测、完整类型刻度(Type Ramp)生成、库样式导入与批量应用的全部可运行代码模式,并理解use_figma无头(headless)运行环境的边界限制。
Text Style(文本样式)是 Figma 中最接近设计令牌体系里"类型刻度(type ramp)"的实体:它把字体家族、字号、字重、行高、字距等排版属性打包成一个可命名的、可复用的样式对象,并可以一键应用到任意文本节点。在 Warp 仓库的 figma-use Skill 中,所有涉及文本样式读写能力的参考均收敛到本文所基于的 text-style-patterns.md,其姊妹篇 wwds-text-styles.md 则负责解释"何时该创建文本样式、它和设计令牌的关系、无头环境的局限"等设计体系层面的问题。
前置:use_figma的文本样式运行规则
在阅读具体代码前,先明确 figma-use Skill 中与文本操作强相关的三条硬规则(完整清单见 SKILL.md 第 1 节):
- 字体必须先加载:任何文本操作(设置
fontName、修改文本内容)之前,必须先await figma.loadFontAsync({ family, style })。未加载就设置字体会直接抛错。 lineHeight与letterSpacing必须是{ value, unit }对象:裸数字(如style.lineHeight = 1.5)会抛异常。合法形式只有{ unit: 'AUTO' }、{ value: 24, unit: 'PIXELS' }、{ value: 150, unit: 'PERCENT' }三种。TextStyle.setBoundVariable在无头模式下不可用:use_figma运行在 MCP/助手的无头运行时中,调用ts.setBoundVariable(...)会抛"not a function";节点级node.setBoundVariable(...)与画布填充级figma.variables.setBoundVariableForPaint(...)不受影响(见 gotchas.md 第 255 行附近)。
此外,return是use_figma唯一的输出通道,代码会自动包裹进 async 上下文,因此可以直接使用顶层await与return,禁止figma.closePlugin()与console.log()输出。
TextStyle 数据模型:可写属性与取值约束
wwds-text-styles.md 给出了TextStyle的完整可写属性清单:
| 属性 | 类型 | 说明 |
|---|---|---|
name | string | 斜杠分隔便于分组,如"Heading/XL" |
fontSize | number | 单位是像素 |
fontName | FontName | { family: string, style: string },设置前字体必须已加载 |
letterSpacing | LetterSpacing | { value: number, unit: 'PIXELS' \| 'PERCENT' } |
lineHeight | LineHeight | { value: number, unit: 'PIXELS' \| 'PERCENT' }或{ unit: 'AUTO' } |
textCase | TextCase | 'ORIGINAL' \| 'UPPER' \| 'LOWER' \| 'TITLE' \| 'SMALL_CAPS' |
textDecoration | TextDecoration | 'NONE' \| 'UNDERLINE' \| 'STRIKETHROUGH' |
paragraphSpacing | number | 段落间距 |
paragraphIndent | number | 段落缩进 |
description | string | 继承自BaseStyleMixin,常用于记录 CSS 变量名 |
TextStyle在类型系统中继承BaseStyleMixin(提供name、id、key、type、description、remove()),其类型签名定义于 plugin-api-standalone.d.ts 第 11018 行附近;同一文件的 plugin-api-standalone.index.md 是检索这些 API 的索引入口(其中LineHeight位于 L4830、LetterSpacing位于 L4826、FontName位于 L3697、TextStyle位于 L11018)。
lineHeight 与 letterSpacing 的合法写法
这两个属性是对象而非裸数字,以下写法来自 wwds-text-styles.md 的官方示范:
// WRONG —— 裸数字会抛错 style.lineHeight = 1.5; style.letterSpacing = 0; // CORRECT style.lineHeight = { unit: "AUTO" }; // 自动行高 style.lineHeight = { value: 24, unit: "PIXELS" }; // 固定像素行高 style.lineHeight = { value: 150, unit: "PERCENT" }; // 字号 150% 行高 style.letterSpacing = { value: 0, unit: "PIXELS" }; // 零字距 style.letterSpacing = { value: -2, unit: "PIXELS" }; // 紧凑字距(负数) style.letterSpacing = { value: 5, unit: "PERCENT" }; // 百分比字距读回时的陷阱:{ unit: 'AUTO' }形式的lineHeight没有value键,读取时必须先检查unit再访问value,否则会得到undefined。
列举本地文本样式
最基础的读操作是拉取当前文件所有本地文本样式。以下代码来自 text-style-patterns.md 的 Listing Text Styles 一节,它把每个样式的核心排版属性整理成结构化对象返回:
/** * Lists all local text styles with their key properties. * * @returns {Promise<Array<{id: string, name: string, key: string, fontSize: number, fontName: FontName, lineHeight: LineHeight, letterSpacing: LetterSpacing}>>} */ async function listTextStyles() { const styles = await figma.getLocalTextStylesAsync(); return styles.map(s => ({ id: s.id, name: s.name, key: s.key, fontSize: s.fontSize, fontName: s.fontName, lineHeight: s.lineHeight, letterSpacing: s.letterSpacing })); }完整可运行脚本(use_figma中直接粘贴):
const results = await listTextStyles(); return results;注意使用异步变体:getLocalTextStyles()已被官方标记为 deprecated(见 plugin-api-standalone.d.ts 第 1475 行附近,且文档访问模式为dynamic-page时会直接抛错),应始终使用figma.getLocalTextStylesAsync()。
名称不唯一:Figma 允许两个文本样式同名,因此查找已知样式时应当按id或key匹配,而不是仅凭name。key也是后续importStyleByKeyAsync导入团队库样式时需要的稳定标识。
创建文本样式:字体必须先加载
创建文本样式的核心函数(Creating a Text Style 一节)。函数签名中明确了三个关键约定:
- 字体必须在调用前完成加载;
lineHeight与letterSpacing必须是{ value, unit }对象,裸数字会抛错;description字段建议直接写入 CSS 变量名(如"CSS: var(--font-body-base)"),让 Figma 样式与代码库令牌一一对应。
/** * Creates a text style with all typographic properties set. * Font MUST be loaded before calling. * * @param {string} name - Slash-delimited name, e.g. "body/base" * @param {{ family: string, style: string }} fontName * @param {number} fontSize - In pixels * @param {{ value: number, unit: 'PIXELS' | 'PERCENT' } | { unit: 'AUTO' }} lineHeight * @param {{ value: number, unit: 'PIXELS' | 'PERCENT' }} [letterSpacing] * @param {string} [description] - e.g. the CSS variable name "CSS: var(--font-body-base)" * @returns {TextStyle} */ function createTextStyleFull(name, fontName, fontSize, lineHeight, letterSpacing, description) { const style = figma.createTextStyle(); style.name = name; style.fontName = fontName; style.fontSize = fontSize; style.lineHeight = lineHeight; // { unit: 'AUTO' } | { value, unit: 'PIXELS'|'PERCENT' } if (letterSpacing) style.letterSpacing = letterSpacing; if (description) style.description = description; return style; }与变量绑定相关的无头环境限制
文本样式可以与变量绑定(可绑定的字段包括fontFamily、fontSize、fontStyle、fontWeight、letterSpacing、lineHeight、paragraphSpacing、paragraphIndent),解绑用style.setBoundVariable(field, null)。但 wwds-text-styles.md 明确警告:TextStyle.setBoundVariable在use_figma无头模式下不可用,调用即抛"not a function",它只存在于交互式插件(Figma 编辑器内的 UI 插件)上下文:
// use_figma(无头)—— 无法绑定变量,直接设裸值 const ts = figma.createTextStyle(); ts.fontSize = 24; // 真实交互式插件 —— 变量绑定可用 const ts = figma.createTextStyle(); ts.setBoundVariable("fontSize", fontSizeVariable);因此当类型刻度需要参与令牌系统、且必须实现实时变量绑定时,推荐的三步路径是:① 通过use_figma以裸值创建文本样式 → ② 在 Figma 编辑器中打开文件,通过 Styles 面板手动绑定变量 → ③ 或改用运行于编辑器内的交互式插件完成绑定(详见 wwds-text-styles.md)。
探测字体样式:不要硬编码风格名
字体风格名因提供商和文件而异——"SemiBold"与"Semi Bold"是两个不同字符串,加载错误风格名会静默失败或抛错,且不存在标准清单。因此正确做法是逐候选探测(Probing Font Styles 一节):
/** * Probes available font styles for a given family. * Useful when font style names are unknown (e.g. "SemiBold" vs "Semi Bold"). * * @param {string} family - Font family name, e.g. "Inter" * @param {string[]} stylesToTest - Candidate style names to probe * @returns {Promise<string[]>} - Style names that loaded successfully */ async function probeAvailableFontStyles(family, stylesToTest) { const available = []; for (const style of stylesToTest) { try { await figma.loadFontAsync({ family, style }); available.push(style); } catch (_) {} } return available; }用法示例:await probeAvailableFontStyles('Inter', ['SemiBold', 'Semi Bold', 'Semibold'])会返回真实可用的风格名列表。相关佐证同样出现在 gotchas.md 的字体风格一节:构建类型刻度脚本前,务必先针对目标文件验证字体风格字符串,再决定是否硬编码。
创建类型刻度(Type Ramp):多步骤、去重、幂等
这是本文档最有价值的一段:给定令牌定义数组,批量生成整个类型刻度,并同时处理字体加载去重、已有样式跳过(幂等)两个问题。
数据格式:每条定义为六元组[name, fontFamily, fontStyle, fontSize_px, lineHeight, cssVar],其中lineHeight为{ unit: 'AUTO' }或{ value: number, unit: 'PIXELS' | 'PERCENT' }。
/** * Creates a full type ramp from a token definition array. * Handles font loading, deduplication, and idempotency. * * Each entry: [name, fontFamily, fontStyle, fontSize_px, lineHeight, cssVar] * - lineHeight: { unit: 'AUTO' } or { value: number, unit: 'PIXELS' | 'PERCENT' } * * @param {Array} defs - Array of [name, fontFamily, fontStyle, fontSize, lineHeight, cssVar] tuples * @returns {Promise<{ created: string[], skipped: string[] }>} */ async function createTypeRamp(defs) { const uniqueFonts = new Set(); for (const [, family, style] of defs) { uniqueFonts.add(JSON.stringify({ family, style })); } await Promise.all( [...uniqueFonts].map(f => figma.loadFontAsync(JSON.parse(f))) ); const existing = new Set( (await figma.getLocalTextStylesAsync()).map(s => s.name) ); const created = []; const skipped = []; for (const [name, family, style, fontSize, lineHeight, cssVar] of defs) { if (existing.has(name)) { skipped.push(name); continue; } const ts = figma.createTextStyle(); ts.name = name; ts.fontName = { family, style }; ts.fontSize = fontSize; ts.lineHeight = lineHeight ?? { unit: 'AUTO' }; if (cssVar) ts.description = `CSS: var(${cssVar})`; created.push(name); } return { created, skipped }; }实现要点拆解:
- 字体加载去重:先用
Set+JSON.stringify收集所有唯一的{family, style}组合,再Promise.all并发加载,避免同一字体重复加载浪费往返。 - 幂等性:创建前先取全部本地样式名构建
existing集合;已存在的名字直接跳过并记入skipped,不会重复创建。这对应 token-creation.md 中"Check-Before-Create"幂等模式在文本样式上的落地——注意名字仍可能不唯一,严格场景下幂等判定可改为按key或getSharedPluginData标记。 - CSS 变量回填:
cssVar存在时写入description字段(CSS: var(--font-body-base)形式),使 Figma 样式与代码库令牌双向可追溯。
HEADLESS 注意事项(原文档明确标注):setBoundVariable在TextStyle上不受use_figma支持,因此本函数只设置裸值;如需绑定变量,应在 Figma 内交互完成。
完整可运行的类型刻度脚本(可直接粘贴到use_figma):
const defs = [ ['heading/xl', 'Inter', 'Bold', 48, { unit: 'PIXELS', value: 56 }, '--font-heading-xl'], ['heading/lg', 'Inter', 'Bold', 36, { unit: 'PIXELS', value: 44 }, '--font-heading-lg'], ['body/base', 'Inter', 'Regular', 16, { unit: 'AUTO' }, '--font-body-base'], ['body/sm', 'Inter', 'Regular', 14, { unit: 'AUTO' }, '--font-body-sm'], ['code/base', 'Roboto Mono', 'Regular', 14, { unit: 'AUTO' }, '--font-code-base'], ]; const result = await createTypeRamp(defs); return result;运行后result形如{ created: ['heading/xl', 'heading/lg', 'body/base', 'body/sm', 'code/base'], skipped: [] }。created与skipped两个数组可直接返回给上层做后续引用或校验。
类型刻度与设计体系脚本的联动
同样的模式在 figma-generate-library Skill 的 token-creation.md 中有一个更接近真实设计体系的变体:它用Display/Hero、Heading/H1、Body/Medium、Label/Small、Code/Base等 SDS(Simple Design System)风格命名定义文本样式数组,同样先以Set收集唯一字体并Promise.all加载,然后逐条figma.createTextStyle()并设置lineHeight = { value, unit: 'PIXELS' }、letterSpacing = { value, unit: 'PIXELS' },最后用setSharedPluginData打上run_id与key标记以便幂等与清理。该文件还给出配套的样式校验脚本:
const [textStyles, effectStyles] = await Promise.all([ figma.getLocalTextStylesAsync(), figma.getLocalEffectStylesAsync() ]); return { textStyles: textStyles.map(s => ({ name: s.name, fontSize: s.fontSize, fontFamily: s.fontName.family })), effectStyles: effectStyles.map(s => ({ name: s.name, effectCount: s.effects.length })), counts: { text: textStyles.length, effect: effectStyles.length } };这说明文本样式阶段通常属于设计体系搭建的 Phase 1(令牌与样式创建),完成后应校验"所有计划中的文本样式均存在且字体家族/字号/字重正确"作为退出标准之一。
导入团队库文本样式
对于来自**团队库(team library)**的文本样式,不要重新创建,而是用importStyleByKeyAsync按key导入并复用:
// Import a library text style by key const headingStyle = await figma.importStyleByKeyAsync("TEXT_STYLE_KEY"); // Apply to a text node await textNode.setTextStyleIdAsync(headingStyle.id);关键提示(原文档明确写出):优先导入库样式,而不是新建样式。search_design_system在includeStyles: true时返回的样式key可以直接用于上述导入。这与 SKILL.md 中"先发现设计系统约定、匹配既有约定而非强加新约定"的总体原则一脉相承。
将文本样式应用到节点
创建样式本身不会影响任何节点——必须把样式 ID 赋给文本节点。批量应用模式如下(Applying Text Styles to Nodes 一节):遍历当前页面所有TEXT节点,按名称子串匹配后调用异步 settersetTextStyleIdAsync。
/** * Applies a text style to all TEXT nodes on the current page that match a given name pattern. * * @param {string} styleId - The ID of a TextStyle. * @param {string} nodeNamePattern - Substring match against node names. * @returns {Promise<number>} - Number of nodes the style was applied to. */ async function applyTextStyleToMatchingNodes(styleId, nodeNamePattern) { const textNodes = figma.currentPage.findAllWithCriteria({ types: ['TEXT'] }); let applied = 0; for (const node of textNodes) { if (node.name.includes(nodeNamePattern)) { await node.setTextStyleIdAsync(styleId); applied++; } } return applied; }完整可运行脚本:
const applied = await applyTextStyleToMatchingNodes('STYLE_ID', 'Heading'); return { applied };两个易错点:
- 应用样式不需要加载字体:把
textStyleId赋给节点(或调用setTextStyleIdAsync(id))不要求字体已加载——只有直接编辑文本内容或字体属性时才需要。这一点与创建样式时的"必须先 loadFont"形成对比。 setTextStyleIdAsync是推荐形态:在documentAccess: "dynamic-page"清单下,textStyleId属性是只读的,必须改用setTextStyleIdAsync(见 plugin-api-standalone.d.ts 第 9551–9559 行附近)。该文件还提供了按字符区间设置的setRangeTextStyleIdAsync(start, end, styleId),适用于混合排版节点。
常见陷阱清单(备查)
综合 text-style-patterns.md、wwds-text-styles.md 与 gotchas.md,文本样式相关的高频坑如下:
- 设置
fontName前必须await figma.loadFontAsync({ family, style }):创建或修改样式的字体前缺这一步必炸。 - 字体风格名是文件相关的:
"SemiBold"与"Semi Bold"依提供商与文件而异,用探测脚本(Probing 一节)确定,而不是猜测硬编码。 TextStyle.setBoundVariable()在无头模式下不存在:use_figma中调用抛"not a function",改为设裸值,需要绑定时到 Figma 编辑器内交互完成。- 创建样式不会自动应用:必须把样式
id赋给文本节点,样式才生效。 getLocalTextStyles()已弃用:一律使用getLocalTextStylesAsync()。- 名称不唯一:查找已知样式按
id或key匹配,别只按name。 - 斜杠分组只是 UI 视觉提示:
"Heading/XL"与"HeadingXL"是两个不同名字,斜杠不构成命名空间逻辑。 lineHeight与letterSpacing必须是对象:style.lineHeight = 1.5抛错,用{ value, unit }或{ unit: 'AUTO' }。
延伸阅读
- figma-use Skill 总入口:含
use_figma全部运行规则、页面规则、增量工作流与错误恢复流程 - Text Styles 与设计体系(wwds-text-styles.md):何时创建文本样式、与令牌的关系、变量绑定能力边界
- Gotchas 与常见错误:每个陷阱的 WRONG/CORRECT 代码对照
- Plugin API 索引:按符号名检索
.d.ts中TextStyle、LineHeight、LetterSpacing等类型定义 - Token 创建参考(figma-generate-library):文本样式在完整设计体系搭建流程(Phase 1)中的位置、幂等标记与校验脚本
- 桌面应用
- 开发者工具
- 人工智能
- AI 应用
- AI Agent
- 代码智能体
【免费下载链接】warp
Warp is an agentic development environment, born out of the terminal.
相关推荐
Novu figma-use Skill 详解:Figma Plugin API 常用操作模式实战指南
Novu figma use Skill 详解:Figma Plugin API 常用操作模式实战指南 Novu 仓库的 .agents/skills/figm
后端消息路由前端通信AI Agent大麦抢票开源工具教程:把开售到下单的时间压进0.1秒级
大麦抢票开源工具教程:把开售到下单的时间压进0.1秒级 开售倒计时的那一刻,你的拇指已经按在“立即购买”上,屏幕却先一步弹出“已售罄”。手动从进页面到提交订单要
GUI 自动化RPA使用 Figma Plugin API 构建 Text Styles:设计系统文字样式实战指南
使用 Figma Plugin API 构建 Text Styles:设计系统文字样式实战指南 导读 本文以 use_figma skill https://l
人工智能AI 技能AI 插件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考