theqtcompanyrnd/agent-skills/qt-figma-component-generation

Claude Code and agent skill by theqtcompanyrnd/agent-skills

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Extract component metadata from a Figma design system and generate production-ready QML controls. Use this skill whenever someone wants to turn Figma components into QML files — whether they say "generate components from Figma", "create QML controls based on a design system", "convert Figma components to QML", "build the component library", "extract button/input/checkbox from Figma", or anything similar. Requires design-tokens.json and QML design system singletons to already exist (from the token extraction skill). Uses Figma MCP to inspect components one at a time and maps variants, states, sizing, and token usage to idiomatic Qt Quick Controls 2 patterns. Trigger this skill at the component generation step of any QML design-system workflow.

Install

npx vskill@latest install theqtcompanyrnd/agent-skills/qt-figma-component-generation

SKILL.md

Figma Component Generation Skill

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.


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.


Step 1 — Component Discovery

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


Step 2 — Pattern Selection

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.

Step 3 — Prepare the Chosen Pattern

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.

Pattern A assets — 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.qmlButton.qmlAbstractButton, multi-variant state machine, size helpers, accent family mapping
references/TextField.qmlTextField.qmlTextInput wrapped in ColumnLayout, label + error + helper text, clear button
references/Checkbox.qmlCheckbox.qmlCheckBox indicator, Canvas tick mark, indeterminate state
references/Toggle.qmlToggle.qmlSwitch track + animated thumb, NumberAnimation
references/Select.qmlSelect.qmlCustom 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.

Pattern B assets — 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

Step 4 — Per-Component Extraction

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.

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.


Step 5 — Figma → QML Mapping

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.
Base type selection
Figma componentQML base type
Button (any style)AbstractButton (from QtQuick.Controls)
CheckboxCheckBox (from QtQuick.Controls.Basic)
Radio buttonRadioButton (from QtQuick.Controls.Basic)
Toggle / switchSwitch (from QtQuick.Controls.Basic)
Text input / fieldColumnLayout 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
SliderSlider (from QtQuick.Controls.Basic)
Tab barTabBar + TabButton
Progress barProgressBar (from QtQuick.Controls.Basic)
Spinner / spin boxSpinBox (from QtQuick.Controls.Basic)
Card / containerRectangle or plain Item
DividerRectangle (1 px, fillWidth)
BadgeRectangle wrapping a Text
TooltipToolTip (from QtQuick.Controls.Basic)
Variant → property pattern (Pattern A)
qml
property string variant: "primary" // primary | secondary | ghost | tertiary | danger
property string size: "medium" // small | medium | large (sm | md | lg accepted)
Variant → enum pattern (Pattern B)
qml
// Use integer enums, not strings — do not mix with Pattern A string variants
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
}
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
}
}
Sizing — tokens first, literals as 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.

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
}
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
Cursor pattern
qml
HoverHandler { cursorShape: root.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor }

Step 6 — Write the QML File

Place each component in the project's components/ folder. Use PascalCase matching the Figma component name (Button.qml, TextField.qml, etc.).

File header

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/theqtcompanyrnd/agent-skills/qt-figma-component-generation/badge)](https://verified-skill.com/skills/theqtcompanyrnd/agent-skills/qt-figma-component-generation)

Something wrong with this skill or its page? Tell us.