Skip to content

Commit 3973429

Browse files
author
figma-bot
committed
Code Connect v1.4.0
1 parent ea14f76 commit 3973429

41 files changed

Lines changed: 1434 additions & 138 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
# Code Connect v1.4.0 (18th February 2026)
2+
3+
## Features
4+
5+
### React
6+
7+
- Add support for `figma.slot()` to map Figma slot layer properties in Code Connect files.
8+
9+
### Parserless
10+
11+
- Added a beta migration script to migrate parser-based Code Connect files to parserless templates under `figma connect migrate`.
12+
- The default extension for parserless/template files is now `.figma.js` instead of `.figma.template.js`. The old `.figma.template.js` extension is still fully supported for backwards compatibility.
13+
- Removed `--include-template-files` flag. Template files (`.figma.js` and `.figma.template.js`) are now always included when detected.
14+
- Add support for `instance.getSlot(name)` in templates to reference "slot" properties.
15+
- Parserless templates now support optional `component` and `source` comment fields (e.g., `// component=Button`)
16+
117
# Code Connect v1.3.13 (29th January 2026)
218

319
## Features

cli/npm_catalog.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@
171171
"@tailwindcss/postcss" = "4.1.3"
172172
"@tailwindcss/vite" = "4.1.3"
173173
"tailwindcss" = "4.1.3"
174+
"@tanstack/react-router" = "1.130.0"
175+
"@tanstack/react-router-devtools" = "1.130.0"
174176
"@vitejs/plugin-react" = "4.4.1"
175177
"vite" = "6.3.6"
176178
"webpack" = "5.91.0"
@@ -181,7 +183,7 @@
181183
"@figma/plugin-typings" = "1.121.0"
182184
"@figma/widget-typings" = "1.12.1"
183185
"@formatjs/icu-messageformat-parser" = "^2.11.2"
184-
"@modelcontextprotocol/ext-apps" = "0.4.0"
186+
"@modelcontextprotocol/ext-apps" = "1.0.1"
185187
"@modelcontextprotocol/sdk" = "1.24.0"
186188
"@opentelemetry/api" = "^1.9.0"
187189
"@sentry/cli" = "2.58.3"
@@ -209,6 +211,7 @@
209211
"mocha-junit-reporter" = "2.2.1"
210212
"postcss" = "8.5.2"
211213
"prettier" = "3.6.2"
214+
"puppeteer" = "24.36.1"
212215
"react-dom" = "18.3.1"
213216
"react-redux" = "8.0.5"
214217
"react" = "18.3.1"
@@ -218,6 +221,7 @@
218221
"ts-node" = "^10.9.2"
219222
"typescript" = "5.9.3"
220223
"yaml" = "2.8.0"
224+
"@zip.js/zip.js" = "2.8.19"
221225
"zod-to-json-schema" = "^3.23.5"
222226
"zod" = "3.25.58"
223227
"ai" = "4.1.62"

cli/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@figma/code-connect",
3-
"version": "1.3.13",
3+
"version": "1.4.0",
44
"description": "A tool for connecting your design system components in code with your design system in Figma",
55
"keywords": [],
66
"author": "Figma",
@@ -81,7 +81,6 @@
8181
"jest": "^29.7.0",
8282
"patch-package": "^8.0.0",
8383
"pkg": "^5.8.1",
84-
"react": "18.3.1",
8584
"ts-jest": "^29.2.5",
8685
"ts-loader": "^9.5.1",
8786
"tsx": "^4.11.0",
@@ -92,6 +91,8 @@
9291

9392

9493
"boxen": "5.1.1",
94+
95+
9596
"chalk": "^4.1.2",
9697
"commander": "^11.1.0",
9798
"compare-versions": "^6.1.0",
@@ -110,6 +111,7 @@
110111
"strip-ansi": "^6.0.0",
111112
"ts-morph": "^27.0.0",
112113
"typescript": "5.9.3",
114+
113115
"undici": "^7.19.1",
114116
"zod": "3.25.58",
115117
"zod-validation-error": "^3.2.0"

cli/src/commands/__test__/parseRawFile.test.ts

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { parseRawFile } from '../connect'
22
import { CodeConnectConfig } from '../../connect/project'
3+
import { SyntaxHighlightLanguage } from '../../connect/label_language_mapping'
34
import fs from 'fs'
45
import path from 'path'
56
import os from 'os'
@@ -125,12 +126,89 @@ export default figma.code\`<Button />\``
125126

126127
const config: CodeConnectConfig = {
127128
parser: 'react',
128-
language: 'kotlin',
129+
language: SyntaxHighlightLanguage.Kotlin,
129130
}
130131

131132
const result = parseRawFile(tempFilePath, 'React', config)
132133

133-
expect(result.language).toBe('kotlin')
134+
expect(result.language).toBe(SyntaxHighlightLanguage.Kotlin)
134135
expect(result.label).toBe('React')
135136
})
137+
138+
it('parses component field from comment', () => {
139+
const fileContent = `// component=Button
140+
// url=https://figma.com/design/abc123?node-id=1:1
141+
const figma = require('figma')
142+
export default figma.code\`<Button />\``
143+
144+
fs.writeFileSync(tempFilePath, fileContent)
145+
const result = parseRawFile(tempFilePath, undefined)
146+
147+
expect(result.component).toBe('Button')
148+
expect(result.figmaNode).toBe('https://figma.com/design/abc123?node-id=1:1')
149+
})
150+
151+
it('parses source field from comment', () => {
152+
const fileContent = `// source=src/button.tsx
153+
// url=https://figma.com/design/abc123?node-id=1:1
154+
const figma = require('figma')
155+
export default figma.code\`<Button />\``
156+
157+
fs.writeFileSync(tempFilePath, fileContent)
158+
const result = parseRawFile(tempFilePath, undefined)
159+
160+
expect(result.source).toBe('src/button.tsx')
161+
})
162+
163+
it('parses fields in any order', () => {
164+
const fileContent = `// url=https://figma.com/design/abc123?node-id=1:1
165+
// component=Button
166+
// source=src/button.tsx
167+
const figma = require('figma')
168+
export default figma.code\`<Button />\``
169+
170+
fs.writeFileSync(tempFilePath, fileContent)
171+
const result = parseRawFile(tempFilePath, undefined)
172+
173+
expect(result.figmaNode).toBe('https://figma.com/design/abc123?node-id=1:1')
174+
expect(result.component).toBe('Button')
175+
expect(result.source).toBe('src/button.tsx')
176+
})
177+
178+
it('handles missing optional fields', () => {
179+
const fileContent = `// url=https://figma.com/design/abc123?node-id=1:1
180+
const figma = require('figma')
181+
export default figma.code\`<Button />\``
182+
183+
fs.writeFileSync(tempFilePath, fileContent)
184+
const result = parseRawFile(tempFilePath, undefined)
185+
186+
expect(result.figmaNode).toBe('https://figma.com/design/abc123?node-id=1:1')
187+
expect(result.component).toBeUndefined()
188+
})
189+
190+
it('throws error when url field is missing', () => {
191+
const fileContent = `// component=Button
192+
const figma = require('figma')
193+
export default figma.code\`<Button />\``
194+
195+
fs.writeFileSync(tempFilePath, fileContent)
196+
197+
expect(() => parseRawFile(tempFilePath, undefined)).toThrow('Missing required url field')
198+
})
199+
200+
it('trims whitespace from field values', () => {
201+
const fileContent = `// component= Button
202+
// source= src/button.tsx
203+
// url= https://figma.com/design/abc123?node-id=1:1
204+
const figma = require('figma')
205+
export default figma.code\`<Button />\``
206+
207+
fs.writeFileSync(tempFilePath, fileContent)
208+
const result = parseRawFile(tempFilePath, undefined)
209+
210+
expect(result.component).toBe('Button')
211+
expect(result.source).toBe('src/button.tsx')
212+
expect(result.figmaNode).toBe('https://figma.com/design/abc123?node-id=1:1')
213+
})
136214
})

0 commit comments

Comments
 (0)