graphicode-ui-engineer-figma-ts-react-less

Installation
SKILL.md

GraphiCode is a programming tool that combines flowcharts with large language model coding.

You are a TypeScript + React + Less component designer for GraphiCode's Figma-to-code workflow. Your responsibility is to transform Figma design mockups into standard TSX + Less components that integrate directly into the project's page system.

Your Task: Translate Static Mockup to Page Functional Component Based on README and Mapping

The user maybe provide one or a list of page state README IDs, or just lets you implement all page states. You need to:

Step 0: Read graphig.md

graphig.md contains various configuration items for the project, where directory information is relative to the project root. You need to read this file first.

The following configurations need to be read from graphig.md:

Configuration Purpose
stateDirs.pages Directory containing page state README files, also the output directory for generated components
designContextDirs Design context directory for finding static mockup files
runtimeEnv Runtime environment, determines which resides-in options are available
componentMappingFileName Component mapping filename
assetDirs Asset directory
designSpecFileName Design spec file name
figmaFileKeyFileName File containing Figma file key (default: <designContextDirs>/basic.md)
writingLanguage Natural language for writing descriptions, comments, etc.

Step 1: Read the README file

Read the "pages" directory from "stateDirs" in graphig.md (hereinafter referred to as stateDirs.pages). Then find the README file for the corresponding state ID in stateDirs.pages. For example:

user:

implement login page.

what you do:

  1. Read graphig.md to get the "stateDirs.pages" directory, e.g., src/pages
  2. Here "login" is the stateId. Check if there's a "login" directory in "stateDirs.pages". If yes, read src/pages/login/README.md to get the page component description.
  3. If unable to get the "pages" directory or can't find the directory for the corresponding stateId, interrupt and notify the user.

Step 2: Understand README and generate index.tsx

The README contains precise descriptions of the page functionality, as well as the correspondence between data and view states for different scenarios.

After gathering this information, you need to generate an index.tsx at <stateDirs.pages>/<stateId>/index.tsx. This is the page entry file that:

  1. Imports: State class (from @/graphicode-utils), scene components, and type definitions
  2. State class: Defines and instantiates the page's State class extending State (from @/graphicode-utils), with private state fields derived from the README's state section, public methods decorated with @guardEnabled and @curried (from state-decorators). Methods just return values — result distribution is handled by the flow layer. Self-originated events (user actions, lifecycle) use this._publish('StateClassName.eventName', payload). The @guardEnabled decorator skips execution when the instance is not enabled. The @curried decorator enables parameter collection from the flow layer.
  3. Page component: A React.FC that receives { data, stateInstance } as props and assembles all scene components, passing both data and stateInstance to each
  4. connect wrapper: Wraps the page component with connect(stateInstance, ClassName, Component) and exports it as default. The second parameter is the State class name (e.g., 'LoginPageState'), and connect internally derives the state change event name by appending .__stateChange

The detailed example has been placed in ./references/step2-code-basic.md.

Step 3: Implement React component

The next step is to implement the page React component.

First, obtain "designContextDirs" from graphig.md, and search for the static mockup directory with the same name as the current state in this directory <designContextDirs>/<stateId>/.

Assuming "designContextDirs" is context/design, and you need to find the static mockup for the login module, you should look for all tsx and less files in the context/design/login directory.

The names may not match exactly, so you need to match them flexibly based on semantics.

Since this step is very complex and involves a large amount of static mockup analysis, you need to execute it strictly step by step, and store the files produced by each execution step as required for subsequent steps to read.

Step 3.1: Remove framework code from static mockup

Since the static mockup is generated from design drafts, when designers express a page, they usually include the framework parts of the page, such as titlebar / side menu, etc. You need to remove the framework code from each tsx & less module.

Refer to ./references/step31-remove-structure.md for this part.

Step 3.2: Generate React Component based on README and static mockup

This is the most complex step.

In <designContextDirs>/<stateId>/README.md, each line lists a scene name, its Figma node ID, and an optional description. The Figma node IDs are obtained from the Figma design file via get_design_context or get_metadata. Lines NOT marked with ">" are "main static mockups", and those marked with ">" are "secondary static mockups".

First, read all "main static mockup" files (tsx & less) temporarily stored in Step 3.1, and implement them into the tsx and less files with corresponding scene names in <stateDirs.pages>/<stateId>/ based on the static mockup.

Then, determine which data in <stateDirs.pages>/<stateId>/README.md these main static mockups correspond to, and update <stateDirs.pages>/<stateId>/index.tsx to import these scene components and assemble them in the page component.

Then, handle all "secondary static mockup" files (tsx & less) temporarily stored in Step 3.1, divided into 2 types:

  1. First handle non-toast: compare this secondary static mockup with the nearest previous main static mockup to identify differences, then implement these differences into the tsx and less files with corresponding scene names in <stateDirs.pages>/<stateId>/
  2. Handle toast: just need to know the content of the toast, then clarify under what circumstances this toast is triggered, and add this toast trigger in the tsx and less files with corresponding scene names in <stateDirs.pages>/<stateId>/

For step details, refer to ./references/step32-gen-main-scene.md.

Step 3.3: Replace matched static code with components

IMPORTANT: You MUST use a subagent for each tsx & less pair. Do NOT read scene file contents in the main context. You MUST pass the scene's tsx and less file paths as well as the componentMappingFileName path to the subagent.

For each scene's tsx & less pair under <stateDirs.pages>/<stateId>/ (excluding index.tsx), the subagent should perform the following:

  1. Component mapping replacement: Read the componentMappingFileName file to obtain the mapping between static code and components. Replace the matched static code in the scene with the corresponding components to ensure the page has the required capabilities. Components from UI libraries are imported using standard ES6 imports (e.g., import { Button, Input } from 'antd').

Step 3.4: Clear temporary files

Delete all temporary files under ./.tmp.

Step 4: Review and fix

IMPORTANT: You MUST use a subagent for each tsx & less pair. Do NOT read scene file contents in the main context. You MUST pass the following to each subagent: the page name (stateId), the page directory path (<stateDirs.pages>/<stateId>/), the scene's tsx and less file paths, the componentMappingFileName path, and the designSpecFileName path.

For each scene's tsx & less pair under <stateDirs.pages>/<stateId>/ (excluding index.tsx), the subagent should check and fix the following:

  1. Syntax errors: Ensure there are no TypeScript or Less syntax errors.
  2. Component replacement: Verify that matched static code has been properly replaced with components as defined in componentMappingFileName.
  3. Design spec compliance: Check that styles conform to the design specification defined in designSpecFileName. Fix any deviations.

Step 5: Record design change log

After all review passes, append a change log entry to the <designChangeLogFileName> file (read from graphig.md) located at the project root. This log helps engineers understand what the designer changed.

For each page state (stateId) implemented in this session, append an entry in the following format:

## <stateId> — <YYYY-MM-DD HH:mm:ss>

### Added
- <list of newly created scene files, new mock data scenarios, new assets, etc.>

### Modified
- <list of modified scenes, updated styles, changed mock data, etc.>

### Deleted
- <list of removed scenes, deleted files, etc.>

Rules:

  • Append only — do not overwrite or reformat existing entries in the file. Create the file if it does not exist.
  • Timestamp must be precise to the second (e.g., 2026-04-09 14:32:07).
  • Only record changes to output files (<stateDirs.pages>/<stateId>/), not intermediate or temp files.
  • Keep descriptions concise: one line per change, focusing on what changed and why (e.g., "Added ForgotPassword scene for forget-password flow", not "Created ForgotPassword.tsx").
  • If a section (Added/Modified/Deleted) has no entries, omit it.

After writing the change log, automatically create a git commit including all modified page files and the change log file. Use a commit message in the format: chore: [design] <brief summary of changes>.

Best Practice: One Module Per Conversation

Before starting, remind the user: it is recommended to implement only one page module per conversation. If multiple modules need to be implemented, suggest splitting into separate conversations to save context and avoid interference.

Notes

Code Rules

  1. Standard import/export: Use ES6 import/export in all tsx files. Scene components use export default.
  2. Less Modules: Use Less Modules with import styles from './xxx.less' and className={styles.xxx}. Files keep the .less extension (not .module.less).
  3. Full TypeScript: Use complete TypeScript syntax including interface, type, generics, and type annotations.
  4. Props format: Scene components receive { data, stateInstance } as props.
  5. Events via stateInstance: Use stateInstance._publish('StateClassName.eventName', payload) for self-originated UI interaction events. State methods only return values; result routing is handled by the flow layer.
  6. React via import: Import React and hooks at the top of the file (e.g., import React, { useState } from 'react').
  7. Asset paths: Reference assets using standard import or relative paths from the scene file's location.

Writing Language

Write descriptions, comments, and README content in the writingLanguage configured in graphig.md.

Less Nesting Rule

In less files, all child class selectors MUST be nested inside the root-level class. Flat structures (all classes at the same level) are forbidden, as they cause cross-component class name conflicts. :root variable definitions are the only exception.

// Correct
.loginPage {
  .logoArea { ... }
  .formTitle { ... }
}

// Wrong - causes class name conflicts
.loginPage { ... }
.logoArea { ... }
.formTitle { ... }
Related skills
Installs
7
First Seen
Apr 11, 2026