qt-figma-component-generation

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Figma Component Generation Skill

Figma组件生成技能

This skill reads component definitions from a Figma file via MCP and generates production-ready QML control files that consume the design-system singletons produced by the token-extraction skill.

本技能通过MCP读取Figma文件中的组件定义,并生成可用于生产环境的QML控件文件,这些控件会使用令牌提取技能生成的设计系统单例文件。

Prerequisites

前置条件

Before generating any components, confirm all of the following exist in the project:
  1. design-tokens.json
    — the merged token file from the token-extraction skill
  2. QML design system singletons
    Primitives.qml
    ,
    Theme.qml
    ,
    Spacing.qml
    ,
    FontInterface.qml
    in a
    design-system/
    folder
If either is missing, stop and run the token-extraction skill first (
qt-figma-token-extraction
).
Verify Figma MCP is connected — confirm that
get_metadata
and
get_design_context
are available in the tool list. If not, tell the user:
"The Figma MCP connector isn't connected yet. Connect it via your MCP configuration, then come back and we can start."
Do not proceed until the connection is confirmed.

在生成任何组件之前,请确认项目中已存在以下所有内容:
  1. design-tokens.json
    —— 来自令牌提取技能的合并令牌文件
  2. QML设计系统单例文件 ——
    design-system/
    目录下的
    Primitives.qml
    Theme.qml
    Spacing.qml
    FontInterface.qml
如果缺少其中任意一项,请先停止当前操作并运行令牌提取技能(
qt-figma-token-extraction
)。
验证Figma MCP已连接 —— 确认工具列表中提供
get_metadata
get_design_context
功能。如果未提供,请告知用户:
"Figma MCP连接器尚未连接。请通过您的MCP配置完成连接,之后再返回继续操作。"
在确认连接完成前,请勿继续后续步骤。

Step 1 — Component Discovery

步骤1——组件发现

Use
get_metadata
to fetch the file structure and identify which pages and frames contain components:
Tool: get_metadata
Input: { "fileKey": "<file key>" }
From the response, note all pages and frames or component sets named as component groups (e.g. "Button", "Text Field", "Checkbox").
Ask the user:
"I can see the following component groups in the Figma file: [list]. Which ones should I generate QML files for? Or should I do all of them?"
Build a single component inventory table and keep it updated throughout the entire workflow — do not create a second table later:
Figma component nameNode IDQML fileStatus
Button67:139Button.qmlpending
Text Field...TextField.qmlpending
Status values:
pending
extracting
mapping
done
/
blocked

使用
get_metadata
获取文件结构,识别包含组件的页面和框架:
Tool: get_metadata
Input: { "fileKey": "<file key>" }
从返回结果中,记录所有被命名为组件组的页面、框架或组件集(例如“Button”“Text Field”“Checkbox”)。
询问用户:
"我在Figma文件中发现了以下组件组:[列表]。您希望为哪些组件生成QML文件?还是全部生成?"
创建一个组件清单表格并在整个工作流中持续更新——后续请勿创建第二个表格:
Figma组件名称节点IDQML文件状态
Button67:139Button.qmlpending
Text Field...TextField.qmlpending
状态值:
pending
extracting
mapping
done
/
blocked

Step 2 — Pattern Selection

步骤2——模式选择

Ask the user to choose an implementation pattern before reading any assets or writing any code. If the AskUserQuestion tool is available, use it:
tool: AskUserQuestion
question: "Which code style should the generated components use?"
options:
  - "Pattern A — Inline (self-contained file, all state logic inside the component)"
  - "Pattern B — Style singleton (ComponentStyle.qml + Component.qml, supports multiple themes)"
  - "I'm not sure — recommend one"
If the tool is not available (e.g. in Claude Code, Codex, or Copilot), ask the question in plain text and wait for a reply before proceeding.
If the user selects "I'm not sure", recommend Pattern A for most projects — it is simpler, self-contained, and easier to debug. Only recommend Pattern B if the project already has a
Qt.Themes
/
TokenInterface
layer or needs to support multiple swappable themes.
Pattern B uses integer enum variants, not strings. Pattern A uses
property string variant: "primary"
. Pattern B uses
property int typeVariant: ButtonStyle.TypeVariant.Primary
. Do not mix the two approaches — pick one and use it consistently throughout all components.

在读取任何资源或编写代码之前,请让用户选择一种实现模式。如果
AskUserQuestion
工具可用,请使用该工具:
tool: AskUserQuestion
question: "生成的组件应使用哪种代码风格?"
options:
  - "模式A——内联式(独立文件,所有状态逻辑都在组件内部)"
  - "模式B——样式单例(ComponentStyle.qml + Component.qml,支持多主题)"
  - "不确定——请推荐一种"
如果该工具不可用(例如在Claude Code、Codex或Copilot中),请以纯文本形式询问该问题,等待用户回复后再继续。
如果用户选择“不确定——请推荐一种”,则为大多数项目推荐模式A——它更简单、独立且易于调试。仅当项目已存在
Qt.Themes
/
TokenInterface
层或需要支持多个可切换主题时,才推荐模式B。
**模式B使用整数枚举变体,而非字符串。**模式A使用
property string variant: "primary"
,模式B使用
property int typeVariant: ButtonStyle.TypeVariant.Primary
。请勿混合使用这两种方式——选择其中一种并在所有组件中保持一致。

Step 3 — Prepare the Chosen Pattern

步骤3——准备所选模式

Before extracting or writing anything, make sure the structure for the chosen pattern is in front of you. Pattern B is read from the bundled assets; Pattern A is built from the inline snippets in Step 5.
在提取或编写任何内容之前,请确保所选模式的结构已准备就绪。模式B的资源来自捆绑的资产;模式A的结构基于步骤5中的内联代码片段构建。

Pattern A assets —
references/

模式A资源——
references/

This folder contains Figma-verified Pattern A controls. Each is a self-contained file where all state logic lives inside the component using conditional expressions on
readonly property
values.
Reference fileOutput fileDemonstrates
references/Button.qml
Button.qml
AbstractButton, multi-variant state machine, size helpers, accent family mapping
references/TextField.qml
TextField.qml
TextInput wrapped in ColumnLayout, label + error + helper text, clear button
references/Checkbox.qml
Checkbox.qml
CheckBox indicator, Canvas tick mark, indeterminate state
references/Toggle.qml
Toggle.qml
Switch track + animated thumb, NumberAnimation
references/Select.qml
Select.qml
Custom Item with Popup, ListView delegate, chevron
Read the file that most closely matches the component being generated before writing any code. If a QML coding skill (
qt-development-skills:qt-qml
) is available, use it while writing so the output follows idiomatic Qt 6 patterns.
此文件夹包含经过Figma验证的模式A控件。每个控件都是独立文件,所有状态逻辑都通过
readonly property
值的条件表达式在组件内部实现。
参考文件输出文件演示内容
references/Button.qml
Button.qml
AbstractButton、多变体状态机、尺寸助手、强调色家族映射
references/TextField.qml
TextField.qml
用ColumnLayout包裹的TextInput、标签+错误提示+辅助文本、清除按钮
references/Checkbox.qml
Checkbox.qml
CheckBox指示器、Canvas勾选标记、半选状态
references/Toggle.qml
Toggle.qml
Switch轨道+动画滑块、NumberAnimation
references/Select.qml
Select.qml
带Popup的自定义Item、ListView代理、下拉箭头
**在编写代码之前,请先阅读与待生成组件最匹配的参考文件。**如果QML编码技能(
qt-development-skills:qt-qml
)可用,请在编写时使用该技能,确保输出符合Qt 6的规范写法。

Pattern B assets —
assets/qt-controls/

模式B资源——
assets/qt-controls/

This folder contains QML pairs from a production Qt controls library. Each component is split across two files:
  • Button.qml
    — component logic, layout, base type, public API
  • ButtonStyle.qml
    pragma Singleton
    defining typed
    component
    objects for each state and size variant
Read the asset pair for the component you are about to generate — before writing any code. The generated file must follow the reference asset's structure, property ordering, and pattern choices. If the output deviates from the reference in a way that cannot be justified by the specific Figma component, ask yourself why and correct it. Do not invent a different structure when a reference exists.
Core pairs to read first (read the pair that matches the component being generated):
  • Button.qml
    +
    ButtonStyle.qml
  • CheckBox.qml
    +
    CheckBoxStyle.qml
  • ComboBox.qml
    +
    ComboBoxStyle.qml
  • Switch.qml
    +
    SwitchStyle.qml
  • TextField.qml
    +
    TextFieldStyle.qml

此文件夹包含来自生产级Qt控件库的QML文件对。每个组件分为两个文件:
  • Button.qml
    —— 组件逻辑、布局、基类、公开API
  • ButtonStyle.qml
    ——
    pragma Singleton
    ,为每个状态和尺寸变体定义类型化的
    component
    对象
**在编写代码之前,请先阅读与待生成组件匹配的资产文件对。**生成的文件必须遵循参考资产的结构、属性顺序和模式选择。如果输出与参考内容存在无法通过Figma组件特性解释的偏差,请自查并修正。当存在参考资源时,请勿自行创建不同的结构。
优先阅读以下核心文件对(选择与待生成组件匹配的文件对):
  • Button.qml
    +
    ButtonStyle.qml
  • CheckBox.qml
    +
    CheckBoxStyle.qml
  • ComboBox.qml
    +
    ComboBoxStyle.qml
  • Switch.qml
    +
    SwitchStyle.qml
  • TextField.qml
    +
    TextFieldStyle.qml

Step 4 — Per-Component Extraction

步骤4——逐组件提取

For each component in the inventory, extract its specification via MCP.
Always call
get_design_context
on an individual main component node — NOT the parent component set node.
Component sets return oversized JSON mixing all variants. Inspect the default/base variant first, then representative variants (Hover, Pressed, Disabled) individually.
Tool: get_design_context
Input: { "fileKey": "<key>", "nodeId": "<individual component node id>" }
If individual node IDs are not known yet, call
get_design_context
on the parent frame and scan for child component nodes, then re-call on each.
对于清单中的每个组件,通过MCP提取其规格信息。
**始终对单个主组件节点调用
get_design_context
——而非父组件集节点。**组件集返回的JSON会混合所有变体,体积过大。先检查默认/基础变体,再分别检查代表性变体(Hover、Pressed、Disabled)。
Tool: get_design_context
Input: { "fileKey": "<key>", "nodeId": "<individual component node id>" }
如果尚未获取单个节点ID,请先对父框架调用
get_design_context
,扫描子组件节点,然后再对每个子节点重新调用该工具。

What to extract per component

每个组件需要提取的内容

  • Variants / props — Figma variant properties and allowed values → QML
    property
    declarations
  • States — Default, Hover, Pressed, Disabled, Focus, Error → conditional expressions on
    readonly property
    values
  • Sizing — height, padding (H + V), gap, font size, font weight, corner radius
  • Color tokens — which semantic token appears in each state; record exact Figma name and resolved value from
    design-tokens.json
  • Typography — font family, size, weight, line height per text element
  • Border — stroke width, color token, which states it appears in
  • Icon / slot — whether the component has an icon slot, its size, left/right/both position
Record all extracted data in a scratch note before writing any code.

  • 变体/属性 —— Figma变体属性及允许值 → QML
    property
    声明
  • 状态 —— Default、Hover、Pressed、Disabled、Focus、Error →
    readonly property
    值的条件表达式
  • 尺寸 —— 高度、内边距(水平+垂直)、间距、字体大小、字体粗细、圆角半径
  • 颜色令牌 —— 每个状态中使用的语义令牌;记录Figma中的精确名称以及
    design-tokens.json
    中的解析值
  • 排版 —— 每个文本元素的字体族、大小、粗细、行高
  • 边框 —— 边框宽度、颜色令牌、出现该边框的状态
  • 图标/插槽 —— 组件是否包含图标插槽、图标尺寸、位置(左/右/两侧)
在编写代码之前,将所有提取的数据记录在临时笔记中。

Step 5 — Figma → QML Mapping

步骤5——Figma → QML映射

Before writing any token reference, open
Theme.qml
,
Primitives.qml
,
Spacing.qml
, and
FontInterface.qml
and read the actual property names.
Do not copy token names from the reference assets — the project's token naming convention may differ from the examples. Every token name you write in a component must exist in the project's singletons.
**在编写任何令牌引用之前,请打开
Theme.qml
Primitives.qml
Spacing.qml
FontInterface.qml
并查看实际的属性名称。**请勿直接复制参考资产中的令牌名称——项目的令牌命名规范可能与示例不同。您在组件中编写的每个令牌名称必须存在于项目的单例文件中。

Base type selection

基类选择

Figma componentQML base type
Button (any style)
AbstractButton
(from
QtQuick.Controls
)
Checkbox
CheckBox
(from
QtQuick.Controls.Basic
)
Radio button
RadioButton
(from
QtQuick.Controls.Basic
)
Toggle / switch
Switch
(from
QtQuick.Controls.Basic
)
Text input / field
ColumnLayout
wrapping a
Rectangle
+
TextInput
Text area (multiline)
ScrollView
wrapping
TextArea
(from
QtQuick.Controls.Basic
) — no reference asset yet; follow the TextField pattern but add
wrapMode: TextArea.Wrap
and remove fixed height
Select / dropdownCustom
Item
with a
Popup
Slider
Slider
(from
QtQuick.Controls.Basic
)
Tab bar
TabBar
+
TabButton
Progress bar
ProgressBar
(from
QtQuick.Controls.Basic
)
Spinner / spin box
SpinBox
(from
QtQuick.Controls.Basic
)
Card / container
Rectangle
or plain
Item
Divider
Rectangle
(1 px, fillWidth)
Badge
Rectangle
wrapping a
Text
Tooltip
ToolTip
(from
QtQuick.Controls.Basic
)
Figma组件QML基类
Button(任意样式)
AbstractButton
(来自
QtQuick.Controls
Checkbox
CheckBox
(来自
QtQuick.Controls.Basic
Radio button
RadioButton
(来自
QtQuick.Controls.Basic
Toggle / switch
Switch
(来自
QtQuick.Controls.Basic
Text input / field
ColumnLayout
包裹
Rectangle
+
TextInput
Text area(多行)
ScrollView
包裹
TextArea
(来自
QtQuick.Controls.Basic
)——暂无参考资产;遵循TextField模式,但添加
wrapMode: TextArea.Wrap
并移除固定高度
Select / dropdown自定义
Item
+
Popup
Slider
Slider
(来自
QtQuick.Controls.Basic
Tab bar
TabBar
+
TabButton
Progress bar
ProgressBar
(来自
QtQuick.Controls.Basic
Spinner / spin box
SpinBox
(来自
QtQuick.Controls.Basic
Card / container
Rectangle
或普通
Item
Divider
Rectangle
(1 px,fillWidth)
Badge
Rectangle
包裹
Text
Tooltip
ToolTip
(来自
QtQuick.Controls.Basic

Variant → property pattern (Pattern A)

变体→属性模式(模式A)

qml
property string variant: "primary"   // primary | secondary | ghost | tertiary | danger
property string size:    "medium"    // small | medium | large  (sm | md | lg accepted)
qml
property string variant: "primary"   // primary | secondary | ghost | tertiary | danger
property string size:    "medium"    // small | medium | large  (sm | md | lg 均支持)

Variant → enum pattern (Pattern B)

变体→枚举模式(模式B)

qml
// Use integer enums, not strings — do not mix with Pattern A string variants
property int typeVariant: ButtonStyle.TypeVariant.Primary
qml
// 使用整数枚举,而非字符串——请勿与模式A的字符串变体混合使用
property int typeVariant: ButtonStyle.TypeVariant.Primary

State → conditional expression pattern

状态→条件表达式模式

qml
readonly property color _bg: {
    if (!enabled) return Theme.background_muted
    return pressed ? Theme.accent_subtle
         : hovered ? Theme.accent_muted
         :            Theme.accent_default
}
qml
readonly property color _bg: {
    if (!enabled) return Theme.background_muted
    return pressed ? Theme.accent_subtle
         : hovered ? Theme.accent_muted
         :            Theme.accent_default
}

Icon slot pattern

图标插槽模式

qml
// Icon slot — rendered via icon font glyph in a Text item
property string iconGlyph:     ""
property int    iconLayoutDir: Qt.LeftToRight   // Qt.LeftToRight | Qt.RightToLeft
                                                 // controls which side the icon appears on

contentItem: RowLayout {
    layoutDirection: root.iconLayoutDir
    spacing:         root._iconGap
    Text {
        text:        root.iconGlyph
        font.family: FontInterface.iconFont.name
        visible:     root.iconGlyph !== ""
    }
    Text {
        id:   _label
        text: root.label
        // ... font properties
    }
}
qml
// 图标插槽——通过文本项中的图标字体字形渲染
property string iconGlyph:     ""
property int    iconLayoutDir: Qt.LeftToRight   // Qt.LeftToRight | Qt.RightToLeft
                                                 // 控制图标的显示位置

contentItem: RowLayout {
    layoutDirection: root.iconLayoutDir
    spacing:         root._iconGap
    Text {
        text:        root.iconGlyph
        font.family: FontInterface.iconFont.name
        visible:     root.iconGlyph !== ""
    }
    Text {
        id:   _label
        text: root.label
        // ... 字体属性
    }
}

Sizing — tokens first, literals as fallback

尺寸——优先使用令牌,字面量作为 fallback

Check
Spacing.qml
and
FontInterface.qml
first. Only use a literal value when no token covers the dimension, and add a
// TODO: add to Spacing.qml
comment.
先检查
Spacing.qml
FontInterface.qml
。仅当没有令牌对应该尺寸时才使用字面量值,并添加
// TODO: add to Spacing.qml
注释。

Focus ring pattern

焦点环模式

Focus rings apply only to
Control
-based components (
AbstractButton
,
CheckBox
,
Switch
,
Slider
, etc.). Text Field (
ColumnLayout
root) and Select (
Item
root) are not
Control
subclasses — use
activeFocus
and a fixed radius for those.
qml
// For Control-based components (AbstractButton, CheckBox, Switch …)
Rectangle {
    anchors { fill: parent; margins: -2 }
    radius:       parent.radius + 2          // only valid when parent is a Rectangle
    color:        "transparent"
    border.color: Theme.stroke_focus         // use a token — never a literal color
    border.width: 2                          // TODO: promote to Spacing token if available
    visible:      root.visualFocus           // Control property — gives keyboard-only focus ring
}

// For non-Control roots (ColumnLayout, Item) — use activeFocus and fixed radius
Rectangle {
    anchors { fill: parent; margins: -2 }
    radius:       4                          // TODO: use Spacing token
    color:        "transparent"
    border.color: Theme.stroke_focus
    border.width: 2
    visible:      root.activeFocus
}
焦点环仅适用于基于
Control
的组件(
AbstractButton
CheckBox
Switch
Slider
等)。Text Field(根节点为ColumnLayout)和Select(根节点为Item)不是
Control
的子类——对这些组件使用
activeFocus
和固定半径。
qml
// 基于Control的组件(AbstractButton、CheckBox、Switch …)
Rectangle {
    anchors { fill: parent; margins: -2 }
    radius:       parent.radius + 2          // 仅当父节点为Rectangle时有效
    color:        "transparent"
    border.color: Theme.stroke_focus         // 使用令牌——切勿使用字面量颜色
    border.width: 2                          // TODO: 如果有可用令牌,升级为Spacing令牌
    visible:      root.visualFocus           // Control属性——仅在键盘聚焦时显示焦点环
}

// 非Control根节点(ColumnLayout、Item)——使用activeFocus和固定半径
Rectangle {
    anchors { fill: parent; margins: -2 }
    radius:       4                          // TODO: 使用Spacing令牌
    color:        "transparent"
    border.color: Theme.stroke_focus
    border.width: 2
    visible:      root.activeFocus
}

Color animation pattern

颜色动画模式

Add
Behavior
blocks only on color properties that animate during interaction (hover, press). Skip them for the disabled state — a snap, not a fade, is usually correct there.
qml
// On the Rectangle or contentItem that holds the interactive color:
Behavior on color        { ColorAnimation { duration: Theme.duration_fast } }
Behavior on border.color { ColorAnimation { duration: Theme.duration_fast } }
// If no duration token exists yet: duration: 100 — add a TODO to promote it
仅在交互过程中(悬停、按下)会变化的颜色属性上添加
Behavior
块。跳过禁用状态的动画——通常直接切换而非渐变更合适。
qml
// 在包含交互颜色的Rectangle或contentItem上添加:
Behavior on color        { ColorAnimation { duration: Theme.duration_fast } }
Behavior on border.color { ColorAnimation { duration: Theme.duration_fast } }
// 如果尚无持续时间令牌:duration: 100 —— 添加TODO注释,后续升级为令牌

Cursor pattern

光标模式

qml
HoverHandler { cursorShape: root.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor }

qml
HoverHandler { cursorShape: root.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor }

Step 6 — Write the QML File

步骤6——编写QML文件

Place each component in the project's
components/
folder. Use PascalCase matching the Figma component name (
Button.qml
,
TextField.qml
, etc.).
将每个组件放置在项目的
components/
目录中。使用与Figma组件名称匹配的大驼峰命名法(
Button.qml
TextField.qml
等)。

File header

文件头部

qml
// ComponentName.qml — [Project] Design System — [component description]
// Maps to Figma: [file name] → [component name] (node [id])
//
// Figma variants (inspected via MCP, [date]):
//   Prop1: "value1" | "value2"
//   Prop2: "valueA" | "valueB"
// States: Default | Hover | Pressed | Disabled [| Error | Focus]
// Sizes:  "small" | "medium" | "large"
//
// Usage:
//   import MyProject
//   ComponentName { prop: "value"; onAction: doThing() }
qml
// ComponentName.qml — [项目名称] 设计系统 — [组件描述]
// 对应Figma:[文件名] → [组件名称](节点[id])
//
// Figma变体(通过MCP检查,[日期]):
//   Prop1: "value1" | "value2"
//   Prop2: "valueA" | "valueB"
// 状态:Default | Hover | Pressed | Disabled [| Error | Focus]
// 尺寸: "small" | "medium" | "large"
//
// 使用方式:
//   import MyProject
//   ComponentName { prop: "value"; onAction: doThing() }

Public API section

公开API部分

qml
// ── Public API ────────────────────────────────────────────────────────────
property string variant: "primary"
property string size:    "medium"
property string label:   "Button"

// ── Private helpers ───────────────────────────────────────────────────────
readonly property bool  _isSmall: size === "small" || size === "sm"
readonly property color _bg: ...
qml
// ── 公开API ────────────────────────────────────────────────────────────
property string variant: "primary"
property string size:    "medium"
property string label:   "Button"

// ── 私有辅助属性 ───────────────────────────────────────────────────────
readonly property bool  _isSmall: size === "small" || size === "sm"
readonly property color _bg: ...

Missing values

缺失值处理

qml
// TODO: add Spacing.buttonIconGapSm to Spacing.qml (Figma: 0px for small buttons)
readonly property int _iconGap: _isSmall ? 0 : Spacing.x4
After generating all components, summarise the full TODO list for the user.

qml
// TODO: 在Spacing.qml中添加Spacing.buttonIconGapSm(Figma中:小按钮的图标间距为0px)
readonly property int _iconGap: _isSmall ? 0 : Spacing.x4
生成所有组件后,为用户总结完整的TODO列表。

Step 7 — Post-Generation Review

步骤7——生成后检查

After all components are written, run a consistency pass:
  • Every
    readonly property color
    referencing a theme token must use a name that actually exists in
    Theme.qml
    or
    Primitives.qml
    . Flag any that don't.
  • Every numeric size must come from
    Spacing.qml
    or
    FontInterface.qml
    . Collect any literals that should be promoted to tokens.
  • Every interactive component has a focus ring.
  • Every interactive component has a
    HoverHandler
    with a cursor shape.
  • File headers document the node IDs that were inspected.
  • Update the inventory table from Step 1 — mark all components
    done
    or
    blocked
    .
Present a brief summary to the user:
  • Components generated (count and names)
  • Components skipped or blocked (with reason)
  • Full TODO list: tokens that need to be added to the design-system singletons
  • Recommended next step: add components to
    qt_add_qml_module QML_FILES
    in CMakeLists.txt and smoke-test in a gallery

编写完所有组件后,进行一致性检查:
  • 每个引用主题令牌的
    readonly property color
    必须使用
    Theme.qml
    Primitives.qml
    实际存在的名称。标记所有不存在的令牌。
  • 每个数值尺寸必须来自
    Spacing.qml
    FontInterface.qml
    。收集所有应升级为令牌的字面量值。
  • 每个交互组件都有焦点环。
  • 每个交互组件都有带光标形状的
    HoverHandler
  • 文件头部记录了检查过的节点ID。
  • 更新步骤1中的清单表格——将所有组件标记为
    done
    blocked
向用户呈现简要总结:
  • 已生成的组件(数量和名称)
  • 已跳过或受阻的组件(原因)
  • 完整的TODO列表:需要添加到设计系统单例文件中的令牌
  • 推荐下一步操作:将组件添加到CMakeLists.txt的
    qt_add_qml_module QML_FILES
    中,并在组件库中进行冒烟测试

Common Pitfalls

常见陷阱

Inspecting the component set instead of a main component. Component sets return all variants stacked. Always drill down to an individual component node.
Using token names from reference assets instead of the project. The reference assets use example token names that may not match the project's singletons. Always read the actual singleton files first.
Hardcoding a value that exists in a token. Check
Spacing.qml
and
FontInterface.qml
before writing any literal number.
Missing the indeterminate / partial state. Checkbox and radio buttons often have a third state. Always check for
Qt.PartiallyChecked
.
Not zeroing out AbstractButton default padding.
AbstractButton
and other
Control
subclasses have default padding that inflates rendered height. Zero them explicitly when managing geometry yourself.
Forgetting
Behavior
blocks.
Add
Behavior on color { ColorAnimation { duration: Theme.duration_fast } }
on color properties that animate during interaction (hover, press). Use a token for duration — not a hardcoded
100
. Skip Behaviors on the disabled state; a snap transition is usually correct there.
Popup z-ordering.
Popup
items need
parent: Overlay.overlay
if clipped by a parent container.
Mixing Pattern A strings and Pattern B enums. Choose one variant approach and use it consistently across all components.
检查组件集而非单个主组件:组件集返回的结果会堆叠所有变体。始终深入到单个组件节点进行检查。
使用参考资产中的令牌名称而非项目中的实际名称:参考资产使用的是示例令牌名称,可能与项目的单例文件不匹配。请始终先查看实际的单例文件。
硬编码已存在令牌对应的值:在编写任何字面量数值之前,请先检查
Spacing.qml
FontInterface.qml
遗漏半选/部分状态:复选框和单选按钮通常有第三种状态。请始终检查
Qt.PartiallyChecked
未清除AbstractButton的默认内边距
AbstractButton
和其他
Control
子类有默认内边距,会增加渲染高度。当自行管理几何布局时,请显式将其清零。
忘记添加Behavior块:在交互过程中(悬停、按下)会变化的颜色属性上添加
Behavior on color { ColorAnimation { duration: Theme.duration_fast } }
。使用令牌设置持续时间——不要硬编码为
100
。跳过禁用状态的Behavior;直接切换通常更合适。
Popup层级问题:如果Popup被父容器裁剪,需要设置
parent: Overlay.overlay
混合使用模式A的字符串和模式B的枚举:选择一种变体实现方式,并在所有组件中保持一致。