mcpField
F
figma-to-ids

figma-to-ids

github.com/iress设计与 UI155 次安装1 天前更新
代码仓库

关于 figma-to-ids

figma-to-ids 是一项将 Figma 设计转换为 Iress Design System(IDS)组件实现的技能,面向生成 React/TypeScript 界面的 Agent。它可依据 Figma 元数据或手动提供的设计说明映射组件与设计令牌,并要求考虑响应式布局。

主要功能

  1. 01分析 Figma 帧与组件结构
  2. 02映射 IDS 组件和设计令牌
  3. 03生成 React/TypeScript 代码
  4. 04推断并实现响应式布局
  5. 05检查导入和常见实现问题

适用场景

  1. 01将 Figma 页面设计转为 IDS 界面
  2. 02把导出的设计说明转换为代码
  3. 03为桌面稿补充移动端布局

MCP 相关

可连接 Figma MCP 服务以直接读取 Figma 文件;没有服务时,也可使用粘贴的设计规格或组件描述。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/iress/design-system --skill figma-to-ids

安装后在 Claude Code 中输入/figma-to-ids确认已加载。

附带文件references/component-mapping.mdreferences/token-mapping.md

详细介绍

技能:Figma 到 IDS 的转换

用途

将 Figma 设计属性和结构转换为 IDS(Iress Design System)组件实现。此技能可帮助 AI Agent 解读 Figma 设计元数据(来自 Figma MCP 等工具或导出的设计规范),并生成准确的 IDS 代码。

Figma MCP 设置

AI Agent 需要使用 Figma MCP 服务,才能直接读取 Figma 文件。没有 MCP 服务时,你仍可以粘贴导出的设计规范或 Figma 组件说明,手动使用此技能。

设置
  1. 获取 Figma 个人访问令牌 — 在 Figma 中,前往 Settings → Account → Personal access tokens,并创建一个具有 File content (Read-only) 权限范围的令牌。

  2. 将 MCP 服务添加到 Agent 配置中。 具体位置取决于你使用的工具:

    工具配置文件
    Kiro CLI~/.kiro/settings/mcp.json(全局)或 .kiro/settings/mcp.json(工作区)
    Cursor.cursor/mcp.json
    Claude Code.claude/mcp.json 或 ~/.claude/mcp.json
    VS Code (GitHub Copilot).vscode/mcp.json

    配置示例(使用社区提供的 figma-developer-mcp 服务):

    {
      "mcpServers": {
        "Figma": {
          "command": "npx",
          "args": ["-y", "figma-developer-mcp", "--stdio"],
          "env": {
            "FIGMA_API_KEY": "<your-figma-token>"
          }
        }
      }
    }
    

    对于 Kiro CLI,也可以通过命令行添加:

    kiro-cli mcp add --name Figma --command npx --args "-y figma-developer-mcp --stdio" --env "FIGMA_API_KEY=<your-figma-token>"
    
  3. 验证 — 让 Agent 从 Figma 文件 URL 获取数据。它应返回画框和组件信息。

流程

  1. 分析 Figma 结构 — 识别画框、自动布局和组件实例
  2. 映射组件 — 将 Figma 组件名称/变体与 IDS 组件匹配
  3. 提取设计令牌 — 将 Figma 设计值转换为 IDS 设计令牌引用
  4. 生成代码 — 使用正确的 IDS 导入项,生成简洁精炼的 React/TypeScript 代码。尽量少用组件——在添加 IressInline/IressStack 包装器前,先检查父组件是否已处理布局。不要将单个子元素包装在布局组件中。
  5. 验证输出 — 检查所有导入项均可解析;存在 IDS 组件时不使用原生 HTML;网格布局使用响应式 span 值;并且不存在常见反模式(禁用按钮、slot 属性、多余的 textStyle)

重要: IDS v6 目前处于 beta 阶段。请使用 @beta 标签安装:

npm install @iress-oss/ids-components@beta
npm install @iress-oss/ids-tokens@beta  # if using tokens directly (e.g. cssVars or CSS vars import)

Figma → IDS 映射

将 Figma 组件映射到 IDS 时,请阅读 references/component-mapping.md,了解完整的 Figma 组件 → IDS 组件映射表。

将 Figma 设计值(颜色、间距、圆角、排版)转换为 IDS 设计令牌时,请阅读 references/token-mapping.md。

对于中性色文本颜色,将 colour.neutral.90 视为 colour.neutral.80 的向后兼容别名(两者均解析为 #141F4D)。新的 IDS 实现优先使用 colour.neutral.80,但转换较旧的 Figma 文件时,应兼容这两个令牌名称。

转换示例

Figma:登录表单画框

Figma 结构:

  • 画框:垂直自动布局,间距 16px,内边距 24px
    • 文本:“Log In”(标题 H2)
    • 输入框:“Email”(文本输入框)
    • 输入框:“Password”(密码输入框)
    • 按钮:“Sign in”(主要按钮)
    • 文本:“Forgot password?”(链接)

IDS 实现:

import {
  IressStack,
  IressText,
  IressField,
  IressInput,
  IressButton,
  IressLink,
  IressCard,
} from '@iress-oss/ids-components';

function LoginForm() {
  return (
    <IressCard p="lg">
      <IressStack gap="md">
        <IressText element="h2">Log In</IressText>
        <IressField label="Email" htmlFor="email" required>
          <IressInput id="email" type="email" />
        </IressField>
        <IressField label="Password" htmlFor="password" required>
          <IressInput id="password" type="password" />
        </IressField>
        <IressButton mode="primary" type="submit">
          Sign in
        </IressButton>
        <IressLink href="/forgot-password">Forgot password?</IressLink>
      </IressStack>
    </IressCard>
  );
}
Figma:提示横幅

Figma 结构:

  • 画框:填充 #EBF9F5,圆角半径 12px,内边距 16px
    • 水平自动布局,间距 8px
    • 图标:“check_circle”
    • 文本:“Your changes have been saved”(正文 MD)

IDS 实现:

import { IressAlert } from '@iress-oss/ids-components';

// IressAlert already handles the layout, icon, and styling
<IressAlert status="success">Your changes have been saved</IressAlert>;

要点: IDS 组件已封装其样式。不要照搬 Figma 重新创建布局或颜色——使用组件属性(例如 status),让 IDS 负责视觉呈现。

Figma:状态模态框(危险操作确认)

Figma 结构:

  • 模态框框架,标题栏中带有危险图标
    • 标题:“删除记录?”
    • 正文:“此操作无法撤销。”
    • 页脚:两个按钮(取消、删除)

IDS 实现:

import { IressModal } from '@iress-oss/ids-components';

// Status modals use the `status` prop — the icon, colours, and button status are handled automatically.
// Use `actions` instead of `footer` for opinionated action buttons.
<IressModal
  status="danger"
  heading="Delete record?"
  actions={[{ children: 'Cancel', mode: 'tertiary' }, { children: 'Delete' }]}
  show={isOpen}
  onShowChange={setIsOpen}
>
  This action cannot be undone.
</IressModal>;

关键要点: 在 IressModal 上设置 status 后,便无法使用 footer 属性,请改用 actions。每个操作按钮都会自动继承模态框的状态。尺寸仅限于 sm(默认)或 md。

Figma:数据表格

Figma 结构:

  • 框架:包含表头行和数据行的表格
    • 表头:["姓名", "电子邮件", "状态", "操作"]
    • 行:包含数据,状态列中有标签,操作列中有按钮

IDS 实现:

import { IressTable, IressTag, IressButton } from '@iress-oss/ids-components';
import type { TableColumn } from '@iress-oss/ids-components';

interface User {
  name: string;
  email: string;
  status: string;
  id: string;
}

const columns: TableColumn<User>[] = [
  { key: 'name', label: 'Name' },
  { key: 'email', label: 'Email' },
  {
    key: 'status',
    label: 'Status',
    format: (value) => <IressTag>{value}</IressTag>,
  },
  {
    key: 'actions',
    label: 'Actions',
    format: (_, row) => (
      <IressButton mode="tertiary" icon="edit">
        Edit
      </IressButton>
    ),
  },
];

function UsersTable({ users }: { users: User[] }) {
  return <IressTable caption="Users" rows={users} columns={columns} />;
}

关键要点: IressTable 由数据驱动,请传入 rows 和 columns 属性,而不是组合子组件。使用列上的 format 函数来渲染标签或按钮等自定义单元格内容。

响应式布局

始终生成响应式输出,即使 Figma 只提供了单个桌面框架也是如此。IDS 使用具有 6 个断点的 12 列网格——每次转换都应考虑布局如何适应更小的屏幕。

响应式设计原则

如果没有提供移动端 Figma 框架,请遵循以下原则:

  1. 确定主要任务 — 判断用户要在页面上完成什么操作(例如填写表单、查看数据或做出决策)。移动端布局应优先满足此任务。
  2. 堆叠多列布局 — 所有并排的列都应在移动端堆叠为全宽(span={{ xs: 12, md: ... }})。
  3. 重新安置次要内容 — 将辅助 UI(筛选器、侧边栏、次要操作、元数据面板)移入移动端的 IressSlideout 或可折叠区域,确保主要任务始终处于显眼位置。
  4. 简化密集布局 — 包含多列的表格、多面板仪表板和宽表单都应进行适配:使用 hideBelow 隐藏非必要列、折叠区域,或在移动端通过 useBreakpoint 切换为卡片布局。
  5. 保留所有功能 — 切勿在移动端移除功能。使用 IressSlideout、IressModal、可展开区域或 IressTabSet,让用户能够访问所有功能,同时避免移动端视图过于杂乱。
断点
断点屏幕宽度
xs0 – 575px
sm576px – 767px
md768px – 1023px
lg1024px – 1279px
xl1280px – 1599px
xxl1600px+
响应式属性

许多属性接受 ResponsiveProp,即单个值或以断点为键的对象:

// Single value (all breakpoints)
<IressCol span={6} />

// Responsive — full-width on mobile, half on medium+
<IressCol span={{ xs: 12, md: 6 }} />

支持响应式值的属性:span、offset、gap、gutter、rowGap、p、px、py、pt、pr、pb、pl、m、mx、my、mt、mr、mb、ml、width、srOnly、hideFrom、hideBelow。

Figma 多视口 → 响应式列

如果 Figma 为同一布局分别提供移动端和桌面端框架:

Figma 移动端(xs): 单列堆叠 Figma 桌面端(md+): 双列侧边栏布局

<IressRow gutter={{ xs: 'sm', md: 'lg' }}>
  <IressCol span={{ xs: 12, md: 4 }}>
    <Sidebar />
  </IressCol>
  <IressCol span={{ xs: 12, md: 8 }}>
    <MainContent />
  </IressCol>
</IressRow>
仅有桌面端 Figma 设计 → 推断响应式布局

如果 Figma 只提供了包含侧边栏和主内容区域的桌面端框架,请推断移动端布局:

import { useState } from 'react';
import {
  useBreakpoint,
  IressSlideout,
  IressButton,
  IressStack,
  IressRow,
  IressCol,
} from '@iress-oss/ids-components';

function Page() {
  const { breakpoint } = useBreakpoint();
  const isMobile = breakpoint === 'xs' || breakpoint === 'sm';
  const [filtersOpen, setFiltersOpen] = useState(false);

  return (
    <>
      {isMobile ? (
        // Mobile: primary content first, secondary content in slideout
        <IressStack gap="md">
          <IressButton
            mode="secondary"
            icon="filter_list"
            onClick={() => setFiltersOpen(true)}
          >
            Filters
          </IressButton>
          <MainContent />
          <IressSlideout
            heading="Filters"
            show={filtersOpen}
            onShowChange={setFiltersOpen}
          >
            <FilterPanel />
          </IressSlideout>
        </IressStack>
      ) : (
        // Desktop: side-by-side layout as designed in Figma
        <IressRow gutter="lg">
          <IressCol span={3}>
            <FilterPanel />
          </IressCol>
          <IressCol span={9}>
            <MainContent />
          </IressCol>
        </IressRow>
      )}
    </>
  );
}
响应式可见性

直接在任意组件上使用 hideFrom/hideBelow CSS 属性:

<IressButton hideBelow="md">Desktop action</IressButton>
<IressText hideFrom="lg">Mobile only text</IressText>

对于基于断点进行条件渲染的情况(例如渲染完全不同的组件),请使用 useBreakpoint 钩子:

import { useBreakpoint } from '@iress-oss/ids-components';

function Navigation() {
  const { breakpoint } = useBreakpoint();
  const isMobile = breakpoint === 'xs' || breakpoint === 'sm';

  return isMobile ? <MobileNav /> : <DesktopNav />;
}

最佳实践

  1. 尽量减少组件嵌套 — 尽可能少用组件。每个包装组件都必须有存在的理由。在添加 IressInline 或 IressStack 之前,先检查父组件是否已处理布局(例如,IressCard 提供 heading 和 footer 属性;IressModal 提供 actions;IressButtonGroup 负责水平排列按钮)。不要用布局组件包装单个子组件。
  2. 使用 IDS 组件,而非原始元素 — IDS 组件封装了正确的间距、颜色、圆角和无障碍功能。
  3. 不要重现组件内部样式 — 如果 Figma 显示按钮具有特定的内边距或圆角,请使用具有正确 mode 的 IressButton — 样式已内置。
  4. 将 Figma 的间距/内边距映射到间距令牌 — 将像素值除以 4 得到令牌编号,然后使用完整令牌:16px → "spacing.4",24px → "spacing.6"。别名令牌("xs"、"sm"、"md"、"lg"、"xl")也有效。切勿使用 gap="4" 这类裸数字。
  5. 优先使用语义属性,而非手动设置样式 — 使用 status="danger",而不是 bg="colour.system.danger.fill"。
  6. 所有表单输入均使用 IressField — 它提供标签、提示和验证布局。
  7. 遵循响应式模式 — 使用 hideFrom/hideBelow 属性或 useBreakpoint 钩子控制响应式可见性;使用 IressCol 上的响应式 span 实现自适应网格布局。
  8. 始终让网格布局适配响应式 — 将 Figma 多列布局转换为代码时,使用响应式 span 值(例如,span={{ xs: 12, md: 6 }}),使各列在移动设备上纵向堆叠。
  9. 查看组件文档 — 阅读相应组件文档,了解详细属性和模式(node_modules/@iress-oss/ids-components/.ai/components/)。

常见错误

不必要的布局包装组件

不要在没有实际作用时添加 IressInline 或 IressStack。Figma 中的每个自动布局框架都不需要单独的布局包装组件 — 请先检查对应的 IDS 组件。

// ❌ Unnecessary nesting — IressStack wrapping a single child
<IressStack gap="md">
  <IressInline gap="sm">
    <IressButton mode="primary">Save</IressButton>
    <IressButton mode="secondary">Cancel</IressButton>
  </IressInline>
</IressStack>

// ✅ Single group of buttons only needs IressInline
<IressInline gap="sm">
  <IressButton mode="primary">Save</IressButton>
  <IressButton mode="secondary">Cancel</IressButton>
</IressInline>

经验法则: 当 Figma 显示自动布局框架时,添加包装组件前,先检查对应的 IDS 组件是否已提供该布局。IressModal(带有 actions)和 IressButtonGroup 等组件已处理好其内部布局。对于 IressCard,使用 heading 和 footer 属性来组织内容 — 但请注意,footer 插槽不会自动排列其子项,因此需要水平排列按钮时,请在 footer 内使用 IressInline。

其他常见反模式

如需查看常见反模式(禁用按钮、多余的 textStyle、旧版插槽属性、原始 HTML、硬编码值)完整列表,请阅读 node_modules/@iress-oss/ids-components/.ai/guides/foundations-common-mistakes.md 中的 Common Mistakes 指南(需要安装 @iress-oss/ids-components)。

Figma 专项补充: 当 Figma 显示命名内容区域(“prepend”“append”“footer”)时,请将其映射到对应的 React 属性,而不是 slot 属性。当 Figma 显示灰显或禁用状态的按钮时,不要使用 disabled — 请参阅该指南了解替代方案。

评论

支持 Markdown